Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Unable to do SPI with PIC16F876A

Status
Not open for further replies.

jitun2

Member
I am developing a wireless communication device using the CC2500 chip from TI. I need to communicate with the chip by SPI. I was simulating the circuit in Proteus using the SPI debugger but it Don't show any exchange of data. I have attached the Simulation Log and the SPI debugger connection here. Here is the code I use.

Code:
#include <16F876A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include "ST24.h"
//#use spi(FORCE_HW, BITS=8,BAUD=9000000, stream=SPI_STREAM)

void main()
{
   unsigned int8 Text[10];
   unsigned int8 i=0;
   int1 read=0;
   unsigned int8 RSSI=0;
   unsigned int8 LQI=0;
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   SETUP_SPI(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4 | SPI_SS_DISABLED);
   
   output_b(0xBF);
   output_a(0x00);
   delay_ms(600);
   st24_init();
   st24_initreg(0,5,0x10);
   delay_ms(400);
   output_b(0xFF);
   while(1)
   {
         if(input(ST24_GDO2)==1)
         {
            if(read==0)
            {
               ST24_RX(Text,&LQI,&RSSI);
               read=1;
            }
         }
         else
         {
            read=0;
         }
         
         for(i=0;i<5;i++)
         {
               if(i==0)
               {
                  output_a(0x3E);
                  output_b(0xFF ^ Text[i]);		//Invert as we are using Comm Anode Type
                  delay_ms(5);

               }
               else if(i==1)
               {
                  output_a(0x3D);
                  output_b(0xFF ^ Text[i]);
                  delay_ms(5);
               }
               else if(i==2)
               {
                  output_a(0x3B);
                  output_b(0xFF ^Text[i]);
                  delay_ms(5);
               }
               else if(i==3)
               {
                  output_a(0x37);
                  output_b(0xFF ^Text[i]);
                  delay_ms(5);
               }
               else if(i==4)
               {
                  output_a(0x1F);
                  output_b(0xFF ^Text[i]);
                  delay_ms(5);
               }
          }
   }
            
}
The content of ST24.h
Code:
#define ST24_SI      PIN_C5   //Serial IP of ST24 connected to serial OP of MCU
#define ST24_SCLK    PIN_C3   //Serial Clock
#define ST24_SO      PIN_C4   //Serial OP of ST24 connected to serial IP of MCU
#define ST24_CSN     PIN_C0   //Chip Select Signal
#define ST24_GDO0    PIN_C1   //Digital output pin for general use
#define ST24_GDO2    PIN_C2   //Digital output pin for general use

//#use spi(FORCE_HW, BITS=8,BAUD=9000000, stream=SPI_STREAM)

int8 SRES=0x30;
int8 IOCFG2=0x00;   //GD02
int8 PKTLEN=0x06;    //Packet Length
int8 PKTCTRL1=0x07;   //Packet Automation Control
int8 PKTCTRL0=0x08;   //Packet Automation Control
int8 ADDR=0x08;   //Device Address registor
int8 Address=0x00;     //Address of the devices

void st24_init()
{
   output_low(ST24_CSN);
   while(input_state(ST24_SO)!=0x00)
   {
      //do nothing just wait
   }
   output_high(ST24_SCLK);
   output_low(ST24_SI);
   output_low(ST24_CSN);
   output_high(ST24_CSN);
   delay_us(45);
   output_low(ST24_CSN);
   while(input_state(ST24_SO)!=0x00)
   {
      //do nothing just wait
   }
   spi_write(SRES);              //Issue the SRES Command Strobe
   while(input_state(ST24_SO)!=0x00)
   {
      //do nothing just wait
   }
   //Now the chip isin idle state and al the registors have default values
   output_high(ST24_CSN);
}

//mode=1 for TX and mode=0 for RX  Plen is the length of the packet UID is the unique Address for this device
void st24_initreg(int1 mode,int8 Plen,int8 UID)
{
   Address=UID;
   output_low(ST24_CSN);
   while(input_state(ST24_SO)!=0x00)
   {
      //do nothing just wait
   }
   if(mode==0)                   //For RX
   {
      spi_write(IOCFG2);
      spi_write(0x07);           //GDO2 Asserts when a packet has been received with CRC OK. De-asserts when the first byte is read from the RX FIFO
   }
   else                          //For TX
   {
      spi_write(IOCFG2);
      spi_write(0x06);           //GDO2 Asserts when sync word has been sent, and de-asserts at the end of the packet.In TX the pin will de-assert if the TX FIFO underflows.
   }   
   spi_write(PKTLEN);
   spi_write(Plen);
   spi_write(PKTCTRL1);
   spi_write(0x0F);
   spi_write(PKTCTRL0);
   spi_write(0x44);
   spi_write(ADDR);
   spi_write(UID);
   spi_write(0x4B);        //burst mode access starting from FSCTRL1 registor i.e from address 0x0B
   spi_write(0x06);        //0x0B: FSCTRL1 – Frequency Synthesizer Control 
   spi_write(0x00);        //0x0C: FSCTRL0 – Frequency Synthesizer Control    NC
   spi_write(0x5D);        //0x0D: FREQ2 – Frequency Control Word, High Byte
   spi_write(0x93);        //0x0E: FREQ1 – Frequency Control Word, Middle Byte
   spi_write(0xB1);        //0x0F: FREQ0 – Frequency Control Word, Low Byte
   spi_write(0x78);        //0x10: MDMCFG4 – Modem Configuration
   spi_write(0x93);        //0x11: MDMCFG3 – Modem Configuration 
   spi_write(0x03);        //0x12: MDMCFG2 – Modem Configuration
   spi_write(0xA2);        //0x13: MDMCFG1 – Modem Configuration 
   spi_write(0xF8);        //0x14: MDMCFG0 – Modem Configuration  NC
   spi_write(0x44);        //0x15: DEVIATN – Modem Deviation Setting 
   spi_write(0x07);        //0x16: MCSM2 – Main Radio Control State Machine Configuration NC
   spi_write(0x3E);        //0x17: MCSM1 – Main Radio Control State Machine Configuration
   spi_write(0x18);        //0x18: MCSM0 – Main Radio Control State Machine Configuration
   spi_write(0x16);        //0x19: FOCCFG – Frequency Offset Compensation Configuration
   spi_write(0x6C);        //0x1A: BSCFG – Bit Synchronization Configuration  NC
   spi_write(0x43);        //0x1B: AGCCTRL2 – AGC Control
   output_high(ST24_CSN);
   delay_us(10);
   output_low(ST24_CSN);
  while(input_state(ST24_SO)!=0x00)
   {
      //do nothing just wait
   }
   /*spi_write(0x40);      //0x1C: AGCCTRL1 – AGC Control   NC
   spi_write(0x91);        //0x1D: AGCCTRL0 – AGC Control   NC
   spi_write(0x87);        //0x1E: WOREVT1 – High Byte Event0 Timeout   NC
   spi_write(0x6B);        //0x1F: WOREVT0 – Low Byte Event0 Timeout    NC
   spi_write(0xF8);        //0x20: WORCTRL – Wake On Radio Control   NC
   spi_write(0x56);        //0x21: FREND1 – Front End RX Configuration  NC
   spi_write(0x10);        //0x22: FREND0 – Front End TX configuration  NC
   spi_write(0xA9);        //0x23: FSCAL3 – Frequency Synthesizer Calibration    NC
   spi_write(0x0A);        //0x24: FSCAL2 – Frequency Synthesizer Calibration NC*/
   
   spi_write(0x65);        //Start burst mode
   spi_write(0x00);        //0x25: FSCAL1 – Frequency Synthesizer Calibration
   spi_write(0x11);        //0x26: FSCAL0 – Frequency Synthesizer Calibration
   
   /*spi_write(0x41);      //0x27: RCCTRL1 – RC Oscillator Configuration   NC
   spi_write(0x00);        //0x28: RCCTRL0 – RC Oscillator Configuration   NC
   spi_write(0x59);        //0x29: FSTEST – Frequency Synthesizer Calibration Control  Don't write
   spi_write(0x7F);        //0x2A: PTEST – Production Test No need to write
   spi_write(0x3F);        //0x2B: AGCTEST – AGC Test Don't write*/
   output_high(ST24_CSN);
   delay_us(5);
   output_low(ST24_CSN);
   while(input_state(ST24_SO)!=0x00)
   {
      //do nothing just wait
   }
   spi_write(0x6C);        //Start burst mode   
   spi_write(0x81);        //0x2C: TEST2 – Various Test Settings
   spi_write(0x35);        //0x2D: TEST1 – Various Test Settings
   /*spi_write(0x0B);      //0x2E: TEST0 – Various Test Settings  NC*/
   output_high(ST24_CSN);
   delay_us(5);
   output_low(ST24_CSN);
   while(input_state(ST24_SO)!=0x00)
   {
      //do nothing just wait
   }
   spi_write(0x3E);        //Access the PATABLE   
   spi_write(0xFF);        //Write power setting to PATABLE
   output_high(ST24_CSN);
}
//M1 M2  Mode
//0   0  TX
//0   1  RX
//1   0  IDLE
//1   1  SRES(Reset)
void ST24_setmode(int1 m1,int1 m2)        
{
   if(m1==0 && m2==0)
      spi_write(0x35);              //Set the transceiver in TX mode
   else if(m1==0 && m2==1)
      spi_write(0x34);              //Set the transceiver in RX mode
   else if(m1==1 && m2==0)
      spi_write(0x36);              //Set the tranceiver in IDLE mode
   else if(m1==1 && m2==1)
      spi_write(0x30);              //Reset the transceiver
}

int8 ST24_TX(Unsigned int8 data[],Unsigned int8 length)
{
   int8 i=0;
   int8 freeTX=00;
   output_low(ST24_CSN);
   while(input_state(ST24_SO)!=0x00)
   {
      //do nothing just wait
   }
   spi_write(0x7F);           //Burst access to TX FIFO
   spi_write(Address);
   for(i=0;i<length;i++)
   {
      spi_write(data[i]);     //write daTa to the TX FIFO
   }
   
   while(!spi_data_is_in())
   {
      //wait for data
   }
   freeTX=spi_read();         //READ daTa from the Transceiver
   output_high(ST24_CSN);
   return freeTX;
}

int8 ST24_RX(Unsigned int8 *data[],Unsigned int8* LQI,Unsigned int8 *RSSI)
{
   int8 RXBYTES=0;
   int8 RXFIFO=0xBF;
   int8 i=0;
   output_low(ST24_CSN);
   while(input_state(ST24_SO)!=0x00)
   {
      //do nothing just wait
   }
   spi_write(0xFB);              //Read the number of bytes in the RX FIFO from RXBYTES
   while(!spi_data_is_in())
   {
      //wait for data
   }
   RXBYTES=spi_read();
   RXBYTES=RXBYTES & 0x7F;
   if(RXBYTES>0)
   {
      for(i=0;i<RXBYTES;i++)
      {
         RXFIFO++;
         spi_write(RXFIFO);
         while(!spi_data_is_in())
         {
            //wait for data
         }
         if(i==RXBYTES-2)
            *RSSI=spi_read();
         else if(i==RXBYTES-1)
         {
            *LQI=spi_read();
            *LQI=*LQI & 0x7F;
         }
         else
            *(data+i)=spi_read();
      }
   }
   output_high(ST24_CSN);
   return RXBYTES;
}

Please help me. There is something wrong I am not able to figure out. There is actually no SPI communication is taking place.

I even tried using different "setup_spi" but still can't get it work. and why am i geting the messages

"ADC conversion clock period (1e-07) Possibly invalid for device clock frequency"

and

"Data written SSPBUF whilst MSSP(in Master mode) is active - data has been ignored"

Please reply. I will be waiting.
 
Hey.. refer to my post here.
I don't think you can rely only on Proteus SPI debugger. I tried that at first but the SPI debugger only tells you what you receive, or whether you receive anything or not.. It doesn't tell you why you don't receive or what mistakes you make regarding the SPI waveform..
You need to use the oscilloscope as well to check ur signal and compare it to the datasheet...
Refer to my post, it i put the oscilloscope pictures for the write and read sequence..
Hope that helps..
 
Status
Not open for further replies.

Latest threads

Back
Top