logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[atmega8][C] problem z CC1000pp

gVVint 29 Sty 2009 10:48 1269 2
  • #1 6070729
    gVVint
    Poziom 10  
    Witam,

    projekt obejmuje pomiar temperatury oraz wysłanie danych do odbiornika przy PC. Układ odbiornika działa poprawnie (testowany przy starej wersji nadajnika z uC z rodziny attiny). Problem pojawia się gdy chcę wysłać ramkę (na razie bez danych) z nowego układu. Pod względem elektrycznym i programowym obsługa CC1000pp jest bez zarzutu tzn zarówno generowanie przerwania jak i budowa ramki jest poprawna (sprawdziłem oscyloskopem na wyjściu z atmegi jak wygląda cała ramka - preambuła, przerwa bo nie ma danych, CRC8), podobnie jak kalibracja i ustawienie rejestrów. Odbiornik wyposażony jest w miernik siły sygnału. W normalnych warunkach gdy pracują starsze wersje układu miernik wskazuje wzrost mocy sygnału czyli że odbiera coś na danej częstotliwości, w nowej wersji nawet nie drgnie a na wyjściu CC1000pp nie pojawia się żaden przebieg. Pytanie jest następujące:
    - czy wymagane jest aby w ramce znajdowały się jakieś dane (dowolny ciąg 0 i 1 )? w nocie napisane jest aby przerwa między preambuła a danymi nie była za długa ale czy wykrycie już samej preambuły nie powinno być sygnalizowane?
    Dodatkowo mogę powiedzieć że układ działa poprawnie jako odbiornik więc nie można nic zarzucić CC1000pp ani atmedze pod względem elektrycznym.
  • #2 6083700
    MarcinKawka
    Poziom 12  
    Nie są wymagane żadne dane, spróbuj z jednego modułu nonstop siać preambułe (0xAA), miernik powinien to poczuć i moduł odbiorczy powininen też odbierać i przesyłać 0xAA lub 0x55 do mikrokontrolera.
  • #3 6205648
    Jack_
    Poziom 2  
    Witam,

    szukałem, próbowałem ale nie jestem w stanie skomunikować się ATMega8 i CC1000PP.
    Piszę w C. Zmontowałem płytkę (trawiona), napisałem kod (przerobiłem trochę dostępne sample) ale nie działa.
    Oczywiście nie chodzi mi zaraz o nadawanie/odbieranie, bo to oczywiście nie działa.
    Póki co chciałem skonfigurować CC1000. Staram się więc na próbę zapisać coś do jego rejestrów konfiguracyjnych i odczytać z nich te właśnie wartości wyświetlając na diodach (PORTD).
    Oczywiście czytam same 0.
    Zwracam się więc do kolegów z prośbą o przejrzenie kodu i pomoc.
    Gdzie tkwi błąd? A może to hardware?

    Garść info:
    - konwerter napięć Mega8-CC1000PP na układach 74LV125 i 74HCT126 jak w projekcie Link
    - Mega8 z kwarcem 11.0592MHz (fuse bits na 95% dobrze zrobione)
    - CC1000 zasilany +3.3V, Mega8 +5V

    W kodzie zostawiłem większość funkcji ale najważniejsze to WriteToCC1000Register oraz ReadFromCC1000Register, bo tylko je w zasadzie w main używam i to one nie działają.

    
    #include <avr/io.h>
    #include <avr/wdt.h> 		// macros for AVR watchdog timer
    #include <util/delay.h>
    #include <avr/interrupt.h>
    
    //definition of CC1000 registers
    #define CC1000_MAIN            0x00
    #define CC1000_FREQ_2A         0x01
    #define CC1000_FREQ_1A         0x02
    #define CC1000_FREQ_0A         0x03
    #define CC1000_FREQ_2B         0x04
    #define CC1000_FREQ_1B         0x05
    #define CC1000_FREQ_0B         0x06
    #define CC1000_FSEP1           0x07
    #define CC1000_FSEP0           0x08
    #define CC1000_CURRENT         0x09
    #define CC1000_FRONT_END       0x0A
    #define CC1000_PA_POW          0x0B
    #define CC1000_PLL             0x0C
    #define CC1000_LOCK            0x0D
    #define CC1000_CAL             0x0E
    #define CC1000_MODEM2          0x0F
    #define CC1000_MODEM1          0x10
    #define CC1000_MODEM0          0x11
    #define CC1000_MATCH           0x12
    #define CC1000_FSCTRL          0x13
    #define CC1000_FSHAPE7         0x14
    #define CC1000_FSHAPE6         0x15
    #define CC1000_FSHAPE5         0x16
    #define CC1000_FSHAPE4         0x17
    #define CC1000_FSHAPE3         0x18
    #define CC1000_FSHAPE2         0x19
    #define CC1000_FSHAPE1         0x1A		
    #define CC1000_FSDELAY         0x1B		
    #define CC1000_PRESCALER       0x1C		
    #define CC1000_TEST6           0x40
    #define CC1000_TEST5           0x41
    #define CC1000_TEST4           0x42
    #define CC1000_TEST3           0x43
    #define CC1000_TEST2           0x44
    #define CC1000_TEST1           0x45
    #define CC1000_TEST0           0x46
    
    //definition of pins used to communicate with CC1000
    #define PDATA  4   
    #define PDATA_PORT PORTB
    #define PDATA_PIN PINB
    #define PDATA_DDR DDRB
    #define PCLK   3   
    #define PCLK_PORT PORTB
    #define PALE   5   
    #define PALE_PORT PORTB
    #define DIO    0   
    #define DIO_PORT PORTB
    #define DIO_PIN PINB
    #define DIO_DDR DDRB
    #define DCLK   2   
    #define DCLK_PIN PINB
    
    //This pin sets the direction of an external level conventer,
    // H means FROM CC1000, L means to CC1000
    #define DDRCC  1   
    #define DDRCC_PORT PORTB
    
    //Copied from SmartRF Studio
    #define TX_CURRENT		0x81
    #define RX_CURRENT		0x44
    #define TX_PLL			0x48
    #define RX_PLL			0x58
    #define OUTPUT_POWER	0xff
    const char registers[] = {0x51, 0x50, 0xA0, 0x00, 0x41, 0xF6, // 00 - 05
    					      0x10, 0x02, 0x80, 0x44, 0x12, // 06 - 0A
    					      0x0F, 0x58, 0x10, 0x26, 0x9C, // 0B - 0F
    					      0x6F, 0x55, 0x70, 0x01, 0x00, // 10 - 14
                                                  0x10, 0x08, 0x3F, 0x04, 0x00, // 15 - 19
    					      0x00, 0x00   };			  // 1A - 1B
    
    volatile char RxBuff[2];	//Receive buffer
    volatile char RxW;			//Write "pointer" for receive buffer
    volatile char RxR;			//Read "pointer" for receive buffer
    volatile char TxBuff[2];	//Transmit buffer
    volatile char TxW;			//Write "pointer" for transmit buffer
    volatile char TxR;			//Read "pointer" for transmit buffer
    
    void writeToRxBuffer(char Data) {
      RxW++;				//Move pointer to the next location
      if(RxW>=30) RxW=0;	//If behind buffer set it to 0
      if(RxW==RxR) {		//If read and write pointers are equal
        //buffer overrun
        
    	//move pointer back
    	if(RxW==0) {
    	  RxW=29;
    	} else {
          RxW--;
        }  
      } else {
        RxBuff[(int)RxW]=Data;	//Write data to buffer
      }
    }
    
    char readFromRxBuffer(void) {
      RxR++;				//Move pointer to the next location
      if(RxR>=30) RxR=0;	//If behind buffer set it to 0
      return RxBuff[(int)RxR];	//Read from buffer
    }
    
    //Almost the same functions as above but for TxBuffer
    
    void writeToTxBuffer(char Data) {
      TxW++;
      if(TxW>=30) TxW=0;
      if(TxW==TxR) {
        //buffer overrun
        //move pointer back
    	if(TxW==0) {
    	  TxW=29;
    	} else {
          TxW--;
        }  
      } else {
        TxBuff[(int)TxW]=Data;
      }
    }
    
    char readFromTxBuffer(void) {
      TxR++;
      if(TxR>=30) TxR=0;
      return TxBuff[(int)TxR];
    }
    
    //sets the direction of MCU pins and external level conventer
    char setIO(char isinput) { 
      char res=0;                     //stores result (last state)
      
      //examine the external level conventer direction pin
      if(DDRCC_PORT & (1<<DDRCC)) res=1; 
      
      if(isinput) { //set MCU as input
        DIO_DDR&=~(1<<DIO);		//set pin direction
        PDATA_DDR&=~(1<<PDATA);	//set pin direction
        DDRCC_PORT|=(1<<DDRCC);	//set external level conventer pin
        DIO_PORT&=~(1<<DIO);		//disconnect pull-up resistor
        PDATA_PORT&=~(1<<PDATA);	//disconnect pull-up resistor
      } 
      else {   		//set MCU as output
        // change state of MCU pins to the state of CC1000 pins
        // to avoid higher current flow
       //if port level is different than level sensed at the same pin...
    	if((DIO_PORT&(1<<DIO))!=(DIO_PIN&(1<<DIO))) 
    	  //change the state of the pin, so they were equal
    	  DIO_PORT^=1<<DIO;							
        //the same for PDATA
        if((PDATA_PORT&(1<<PDATA))!=(PDATA_PIN&(1<<PDATA))) 
    	  PDATA_PORT^=1<<PDATA;
        DDRCC_PORT&=~(1<<DDRCC);	//set external level conventer pin
        DIO_DDR|=(1<<DIO);			//set pin as output
        PDATA_DDR|=(1<<PDATA);		//set pin as output
      }
      return res;					//return old value
    }
    
    void CC1000PP_send(char bit) {
      if(bit) {
        DIO_PORT|=(1<<DIO);	//DIO=1;
      } else {
        DIO_PORT&=~(1<<DIO);	//DIO=0;
      }	
      while((DCLK_PIN & (1<<DCLK))==0); //wait for clock high state
      while((DCLK_PIN & (1<<DCLK))!=0); //wait for clock low state
    }
    
    void CC1000PP_send_byte(char my_byte) {
      char my_bit=1; //my_bit=00000001b
      while(1) {
        CC1000PP_send(my_byte & my_bit);
    	if(my_bit==128) break; //if(my_bit=10000000b) break;
    	my_bit <<= 1; //00000001 -> 00000010 -> ... -> 10000000
      }
    }
    
    char CC1000PP_receive(void) {
      char ret;		
      while((DCLK_PIN & (1<<DCLK))==0);	//wait for clock high state
      ret = DIO_PIN & (1<<DIO);			//sample the pin state
      while((DCLK_PIN & (1<<DCLK))!=0);	//wait for clock low state
      return ret;
    }
    
    char CC1000PP_receive_byte(void) {
      char my_bit=1, my_byte=0; //my_byte is used for storing result
      while(1) {
        if(CC1000PP_receive()) my_byte|=my_bit;
    	if(my_bit==128) break;
    	my_bit <<= 1;
      }
      return my_byte;
    }
    
    //write bit to the configuration register of CC1000
    void CC1000PP_config_write_bit(char val) { 
      PCLK_PORT|=(1<<PCLK); //PCLK=1
      if(val==0) {
    	PDATA_PORT&=~(1<<PDATA); //PDATA=0
      } else {
    	PDATA_PORT|=(1<<PDATA); //PDATA=1
      }
      PCLK_PORT&=~(1<<PCLK); //PCLK=0
    }
    
    void WriteToCC1000Register(char address, char data) {
      char BitCounter,oldIO;       // this is to ensure the falling edge on PALE
      PALE_PORT|=(1<<PALE); //PALE=1 
      PALE_PORT&=~(1<<PALE); // PALE=0
      
      oldIO=setIO(0); //set MCU as output
      
      // Send address bits 
      for(BitCounter=0;BitCounter<7;BitCounter++) {
        //MSB first (address is 7 bit long)
    	CC1000PP_config_write_bit(address&0x40); 
        address=address<<1;
      }
      
     // Send read/write bit (1)
      CC1000PP_config_write_bit(1);
      // Send data bits 
      PCLK_PORT|=(1<<PCLK); //PCLK=1
      PALE_PORT|=(1<<PALE); //PALE=1
      for(BitCounter=0;BitCounter<8;BitCounter++) {
        CC1000PP_config_write_bit(data&0x80);
        data=data<<1;
      }
      PCLK_PORT|=(1<<PCLK); //PCLK=1
      setIO(oldIO); //restore previous setting
    }
    
    char ReadFromCC1000Register(char address) {
      char data, BitCounter, oldIO;
      oldIO = setIO(0); //set MCU as output
      //this is to ensure the falling edge on PALE
      PALE_PORT|=(1<<PALE); //PALE=1
      PALE_PORT&=~(1<<PALE); //PALE=0
      for(BitCounter=0;BitCounter<7;BitCounter++) {
    	CC1000PP_config_write_bit(address&0x40); //Send MSB first
        address=address<<1;
      }
      // Send read/write bit (0)
      CC1000PP_config_write_bit(0);
      // Receive data bits 
      PCLK_PORT|=(1<<PCLK); //PCLK=1
      PALE_PORT|=(1<<PALE); //PALE=1
      PDATA_PORT|=(1<<PDATA); //PDATA=1
      setIO(1); //set MCU as input
      data=0;
      for(BitCounter=0;BitCounter<8;BitCounter++) {
        PCLK_PORT&=~(1<<PCLK); //PCLK=0
        data=data<<1;
        if((PDATA_PIN&(1<<PDATA))!=0) data|=0x01;
        PCLK_PORT|=(1<<PCLK); //PCLK=1
      }
      setIO(oldIO);		//restore old direction
      return data;
    }
    
    
    
    
    
    
    int main(void) {
      char blink=0x3A;
    
      TxW=TxR=RxW=RxR=0;
      MCUCSR=0;
      
      
      DDRB=(1<<PALE)|(1<<PCLK)|(1<<DDRCC); 
            // PALE,PCLK,DDRCC-wy DCLK-we
      
      DDRB&=~(1<<DCLK);
      DDRC=0xff;
      DDRD=0xff;
      
      PORTC=0x00;
      
      PALE_PORT|=(1<<PALE);   //PALE=1
      
      //reset CC1000:
    
      WriteToCC1000Register(CC1000_MAIN, blink); 	   //reset start, 0011 1010 xtal core on
      blink=0x3B;
      WriteToCC1000Register(CC1000_MAIN, blink); //reset end,   0011 1011 xtal core on
      _delay_ms(2);
      
      // zapis wartości do rejestrów:
      int i;
      for(i=1; i<28; i++) //write all registers
        WriteToCC1000Register(i,registers[(int)i]);
        
      //jakiś świecenie, by wiedzieć że układ żyje
      PORTD=~blink;
      _delay_ms(300);
      
      PORTD=blink;
      _delay_ms(300);
      
      PORTD=~blink;
      _delay_ms(300);
      
      PORTD=blink;
    	
      //odczyt z tych samych rejestrów co zapisaliśmy
      for(i=1; i<28; i++) {
        PORTD = ReadFromCC1000Register(i);
    	_delay_ms(500);
    	}
    
      //pętla kończąca odczyt
      while(1) {
    	PORTD = 0xAA;
    	_delay_ms(500);
    	PORTD = 0x55;
    	_delay_ms(500);
    	}
    }
    
    


    No i między zaprogramowanym świeceniem na porcie D mam same zera (tam gdzie powinien coś odczytać).

    Proszę o pomoc, bo nie widzę siebie rozwiązującego ten problem :|

    Pozdrawiam...
REKLAMA