Basic SPI not working pic16

Status
Not open for further replies.

Lipton2

Newbie level 4
Joined
Jun 6, 2014
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
55
Hey!

I am trying to make a simple SPI connection with between a TC77 digital tempereture sensor and my PIC6f690.I have read all the datahseets very carefully and connected everything ok, but it doesn't seem to work..

When i try to read from the TC77 i need two INT, because it send a 13 bit signal. So i read the SSPBUF registers twice and then shift the registers to form one int. To check if the value is good, i send the output through UART to my PC with the pickit2 application. But when i check the temperature I only get the weird value of 73..

Can you please help me to find the problem?

Code:
#include <htc.h>
#include <pic16f690.h>



    void initTMR0 (void);
    void initUARTsend (void);
    void initSPI (void);
 signed int  SPI_receive();
 
    void UART_send(signed int temp_out);

    void main()
    {
       initTMR0();  //TMR0 init
       initUARTsend();  //   UART init
       initSPI();
        signed int temp;
       temp=0;
       PORTC=0;     // PORTC reset


      while(1)
      {
       temp = SPI_receive();
        __delay_ms(100);

       UART_send(temp);
      }
    }


    void initTMR0(void)
    {
       OPTION_REGbits.PS0=1; //Prescaler is divide by 256
       OPTION_REGbits.PS1=1;
       OPTION_REGbits.PS2=1;
       OPTION_REGbits.PSA=0; //Timer Clock Source is from Prescaler
       OPTION_REGbits.T0CS=0;//Prescaler gets clock from FCPU (1MHz)

       INTCONbits.T0IE=1;   //Enable TIMER0 Interrupt
       INTCONbits.T0IF=0;
       INTCONbits.PEIE=1;     //Enable Peripheral Interrupt
       INTCONbits.GIE=1;      //Enable INTs globally
    }

    void initUARTsend(void)
    {
        SPBRG = 25; //Fosch 4Mhz -> baudrate 2400
        TXSTAbits.BRGH = 0;  //Sets Low Baud Rate
        TXSTAbits.SYNC = 0;  //Sets Asynchronous mode
        RCSTAbits.SPEN = 1;  //Enables EUSART
        TXSTAbits.TXEN = 1;  //Enables the EUSART transmiter
    }

    void initSPI(void)
    {
       TRISCbits.TRISC6=0;     //CS SPI output
       TRISCbits.TRISC7=0;      //SDO SPI out
       TRISBbits.TRISB6=0;      //SCK out
       TRISBbits.TRISB4=1;      //SDI SPI IN
        SSPCONbits.SSPEN = 1;   //= Enables serial port and configures SCK, SDO and SDI as serial port pins
        SSPCONbits.CKP = 1; //Idle state for clock is a low level (Microwire alternate)
        SSPCONbits.SSPM = 0;    //SPI Master mode, clock = FOSC/4
        SSPSTATbits.SMP = 0;    // Input data sampled at middle of data output time
        SSPSTATbits.CKE = 1;    //data transfer on rising edge clk

    }

   signed int SPI_receive()
   {

       signed int temp_out_msb;
       signed int temp_out_lsb;
       signed int temp_out;
       temp_out = 0;
       PORTCbits.RC6 = 0; //CS laag, initieer communicatie
       __delay_ms(10);
      SSPBUF = 0;  //dummy to start clk

        //First 8 bits
        while(!PIR1bits.SSPIF) //wait for receive complete
        temp_out_msb = SSPBUF;
        PIR1bits.SSPIF = 0;

        //last 6 bits
        SSPBUF = 0; // write dummy data again to initiate second receive
        while(!PIR1bits.SSPIF) //wait for receive complete
        temp_out_lsb = SSPBUF;
        PIR1bits.SSPIF = 0;

        PORTCbits.RC6 = 1; //CS high, stop SPI

        temp_out = ((temp_out_msb << 8 ) | (temp_out_lsb )); //shift bits to find temp

         return temp_out;

   }


   void UART_send(signed int temp_out)
    {
                while(!TRMT);
                TXREG = temp_out; //Transmit the binary number 1x per se

   }
 

Code:
SSPCONbits.CKP = 1; //Idle state for clock is a low level (Microwire alternate)
The PIC datasheet tells different.
 

Oh yeah that is a mistake in the comment section. Since the TC77 has only three SPI connections i am using the microwire default.
 

I can't remember where I read this but it is what I do and have not had problems. You should disable the SPI module (SSPEN=0), do all the SPI configuration (mode, speed, etc.), then enable the SPI module. The way your code is written (assuming I remembered correctly), the SPI module is using the power-up defaults and not what you are setting it to.

Also, use this chart to correctly set the mode. The mode should be listed in the data sheet for the peripheral.

Code:
/*	
  Standard SPI Mode | Microchip PIC
     Terminology    | Control Bits
   Using CPOL,CPHA  |   CKP CKE
 -------------------+--------------
       0,0 (0)      |    0   1
       0,1 (1)      |    0   0
       1,0 (2)      |    1   1
       1,1 (3)      |    1   0
*/
 

Hmm that sounds quite logical, but i tried it and it didn´t work for me

The datasheet of the TC77 states that "The microcontroller serial I/O bus master clocks
the data in on the rising edge of SCK. The falling edge
of SCK is then used to clock out the rest of the data."

When i compare that with the standard SPI terminology I selected CKP = 0 and CKE = 1, which leaves me with mode 0.
But still nothing.. Some other tips maybe?

My new code:
Code:
#include <htc.h>
#include <pic16f690.h>


    void initTMR0 (void);
    void initUARTsend (void);
    void initSPI (void);
    signed int  SPI_receive();
   // void SPI_send();
    void UART_send(signed int temp_out);

    void main()
    {

            ANSEL = 0;
    ANSELH = 0;
       initTMR0();  //TMR0 init
       initUARTsend();  //   UART init
       initSPI();
       signed int temp;
       temp=0;
      
      while(1)
      {
         temp = SPI_receive();
         __delay_ms(100);
         UART_send(temp);
      }
    }


    void initTMR0(void)
    {
       OPTION_REGbits.PS0=1; //Prescaler is divide by 256
       OPTION_REGbits.PS1=1;
       OPTION_REGbits.PS2=1;
       OPTION_REGbits.PSA=0; //Timer Clock Source is from Prescaler
       OPTION_REGbits.T0CS=0;//Prescaler gets clock from FCPU (1MHz)

       INTCONbits.T0IE=1;   //Enable TIMER0 Interrupt
       INTCONbits.T0IF=0;
       INTCONbits.PEIE=1;     //Enable Peripheral Interrupt
       INTCONbits.GIE=1;      //Enable INTs globally
    }

    void initUARTsend(void)
    {
        SPBRG = 25; //Fosch 4Mhz -> baudrate 2400
        TXSTAbits.BRGH = 0;  //Sets Low Baud Rate
        TXSTAbits.SYNC = 0;  //Sets Asynchronous mode
        RCSTAbits.SPEN = 1;  //Enables EUSART
        TXSTAbits.TXEN = 1;  //Enables the EUSART transmiter
    }

    void initSPI(void)
    {
       //SSPCONbits.SSPEN = 0;   //= Enables serial port and configures SCK, SDO and SDI as serial port pins
       TRISCbits.TRISC6=0;     //CS SPI output
       TRISCbits.TRISC7=0;      //SDO SPI out
       TRISBbits.TRISB6=0;      //SCK out
       TRISBbits.TRISB4=1;      //SDI SPI IN

       SSPSTATbits.CKE = 1;    //data transfer on rising edge clk
       SSPCONbits.SSPM = 0;    //SPI Master mode, clock = FOSC/4
       SSPSTATbits.SMP = 0;    // Input data sampled at middle of data output time
       SSPCONbits.CKP = 0; //Idle state for clock is a low level (Microwire alternate)
       SSPCONbits.SSPEN = 1;

    }

   signed int SPI_receive()
   {
      signed int temp_out_msb;
      signed int temp_out_lsb;
      signed int temp_out;
      temp_out = 0;
        
      PORTCbits.RC6 = 0; //CS laag, initieer communicatie
      __delay_ms(10);
      SSPBUF = 0;  //dummy to start clk

       //First 8 bits
      while(!PIR1bits.SSPIF) //SSPBUF full flag
      temp_out_msb = SSPBUF;
      PIR1bits.SSPIF = 0;

      //last 6 bits
      SSPBUF = 0;
      while(!PIR1bits.SSPIF)//SSPBUF full flag
      temp_out_lsb = SSPBUF;
      PIR1bits.SSPIF = 0;

      PORTCbits.RC6 = 1; //CS hoo, stop SPI

      temp_out = ((temp_out_msb << 8 ) | temp_out_lsb); //shift bits to find temp
      return temp_out;
   }



   void UART_send(signed int temp)
   {
        while(!TRMT);
        TXREG = temp; //Transmit the binary number 1x per se
   }
 

I could only suggest trying the other 3 modes. One thing you may want to try is to set temp_out to a known value at the end of the SPI_receive() function and debug your UART code. You are passing in a 16 bit value but only transmitting 8 bits of it.
 

Mode 0 is correct for TC77, there must be a different problem. Maybe it's your harware?
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…