TC77 connected to PIC24FJ64GB004 (by SPI)


The TC77 is a 13-bit digital temperature sensor which offer a good measurement precision. The maximum error at 25°C should be no more than 1°C. The communication with the micro-controller (uC) could be done using it’s implemented SPI (Serial Peripheral Interface) interface. On the sensor chip the SDO (Serial Data Output) and SDI (Serial Data Input) signals are implemented together, into a single signal line (SI/O). Since the PIC24FJ micro-controller support and this type of communication it is no problem (the uC support different types of configurations on the SPI port). On the uC only the SDI pin will be connected to the TC77, the SDO pin will not be ‘activated’.

Connection to uC

Connection to uC

The TC77 sensor comes into 2 distinct package formats. For my experiments I had used the SOIC format.

TC77 package types

TC77 package types

The internal structure of the sensor is presented below. It contains the diode sensor, the temperature register, the manufacturer information, the configuration register and the serial port interface. More information about the TC77 could be found in its datasheet.

TC77 Block Diagram

TC77 Block Diagram

One important aspect about the TC77 is the fact that is more dedicated for measuring the temeperature from different surfaces (by example from the walls) and it is less recommanded for the ambient temperature monitoring. The sensor didn’t actually measure the temperature of the air (surrounding it) but the temperature of the PCB (Printed Circuit Board) on which it is mounted. For low power application it is recommended to be used another sensor, TC72, which have a mode of one-shot reading temperature mode (when a request for temperature reading comes, the sensor is activated, the temeperature value is read and then it enters back into the shutdown mode – less power consumption mode).

The connection on the PCB was not a complex operation. It was more difficult for me to create the code (using MPLAB C30) which to permit me to read the temperature value from the sensor. I’m quite new in this domain (electronics) so it is understandable. I try first to use the spi.h file included and call the necessary functions for establish and communicate with the external device (TC77) and as I didn’t succeded from the first day I try another aproach. I try to write the code at a lower level (not Assembler, also C) and to work with the registers dedicated for the SPI port directly. This was also a good opportunity to understand better the posibilities of this type of communication (SPI).

First step was to establish which pins will be used for communication. This type of micro-controller have the capability to select which pins to be used for the SPI port. There are a set of pins on the uC, called remapable pins, which could be programmed for being used in different situations. One important advantage of these pins is that they could be programmed on the fly (dynamic, during the execution of the firmware application).

For SPI communication with TC77 was necessary 3 pins to be used (it an example, other pins could be also used):

  • #nCS# – which allows to activate the SPI slave module (pin 2- RC6);
  • SCK – the clock signal for SPI slave module (pin 3 – RP23);
  • SDI – the data line for communicstion (pin 4 – RP24).

And the code necessary to do this is presented below:

TRISCbits.TRISC6 = 0;    // digital output
LATCbits.LATC6 = 1;      // high level means that the SPI
                           slave device is not enabled
PPSOutput(PPS_RP23, PPS_SCK1OUT);  //SCK
PPSInput(PPS_SDI1, PPS_RP24);      // SDI

And the functions which opens the SPI communication and read the temperature value is:

//OPEN THE SPI PORT
 // Set SPI Interrupts
 IFS0bits.SPI1IF = 0;          // clear spi1 interrupt flag
 IEC0bits.SPI1IE = 0;          // disable spi1 interrupt
 IPC2bits.SPI1IP = 1;          // set spi1 interrupt to lowest priority

 // Configure SPI1CON1 (individual bits for clarity)
 SPI1CON1bits.DISSCK  = 0;    //Disable SCKx pin bit (SPI Master modes only)
                                - Internal SPI clock is enabled
 SPI1CON1bits.DISSDO  = 1;    //Disable SDOx pin bit - SDOx pin is not used
                                by module; pin functions as I/O
 SPI1CON1bits.MODE16  = 0;    //Word/Byte Communication Select bit
                                - Communication is byte-wide (8 bits)
 SPI1CON1bits.SMP     = 0;    //SPIx Data Input Sample Phase bit - Input data
                                sampled at middle of data output time
 SPI1CON1bits.CKE     = 0;    //SPIx Clock Edge Select bit - Serial output
                                data changes on transition from Idle clock
                                state to active clock state (see bit 6)
 SPI1CON1bits.SSEN    = 0;    //Slave Select Enable (Slave mode) bit - #SSx#
                                pin not used by module; pin controlled by
                                port function
 SPI1CON1bits.CKP     = 1;    //Clock Polarity Select bit - Idle state for
                                clock is a high level; active state is a 
                                low level
 SPI1CON1bits.MSTEN   = 1;    //Master Mode Enable bit - Master mode
 SPI1CON1bits.SPRE    = 7;    //Secondary Prescale bits (Master mode) 
                                - Secondary prescale 1:1
 SPI1CON1bits.PPRE    = 1;    //Primary Prescale bits (Master mode) 
                               - Primary prescale 16:1

 //Configure SPI1CON2 (individual bits for clarity)
 SPI1CON2bits.FRMEN     = 0;    //Framed SPIx Support bit - Framed SPIx 
                                  support disabled
 SPI1CON2bits.SPIFSD = 0;    //Frame Sync Pulse Direction Control on SSx
                               Pin bit - Frame sync pulse output (master)
 SPI1CON2bits.SPIFPOL = 0;    //Frame Sync Pulse Polarity bit (Frame mode 
                                only) - Frame sync pulse is active-low
 SPI1CON2bits.SPIFE  = 0;    //Frame Sync Pulse Edge Select bit 
                               - Frame sync pulse precedes first bit clock
 SPI1CON2bits.SPIBEN = 0;    //Enhanced Buffer Enable bit - Enhanced 
                               buffer disabled

 // Configure SPI1STAT (individual bits for clarity)
 SPI1STATbits.SPIROV     = 0;    //Receive Overflow Flag bit 
                                   - No overflow has occurred
 SPI1STATbits.SPIEN      = 1;    //SPIx Enable bit - Enables module and 
                                   configures SCKx, SDOx, SDIx and #SSx# 
                                   as serial port pins


//READ THE TEMPERATURE VALUE
 Nop();

 LATCbits.LATC6 = 0;    // select the SPI slave device (#CS# signal)

 SPI1BUF = 0x00;        // write data to spi tx buffer (dummy data)

 counter = 0;
 while((SPI1STATbits.SPIRBF == 0) && (counter < 100))
 {
   counter ++;
   Nop();
 }

 datard1 = SPI1BUF & 0xff;  // read the temperature value first byte

 SPI1BUF = 0x00;       // write data to spi tx buffer (dummy data)

 counter = 0;
 while((SPI1STATbits.SPIRBF == 0) && (counter < 100))
 {
   counter ++;
   Nop();
 }

 datard2 = SPI1BUF & 0xff;   //read the temperature value second byte

 LATCbits.LATC6 = 1; // unselect the SPI slave device (#CS# signal)


//CLOSE THE SPI PORT
IEC0bits.SPI1IE = 0;      //Disable the Interrupt bit in the 
                            Interrupt Enable Control Register
SPI1STATbits.SPIEN = 0;   //Disable the module. All pins controlled
                            by PORT Functions
IFS0bits.SPI1IF = 0;      //Disable the Interrupt flag bit in the
                            Interrupt Flag Control Register

From the code I had dissable the interupts. The first byte of temperature is read into the datard1 variable and the second byte into datard2. The interpretation of the response bytes could be also found into the TC77 datasheet.

I try to find a similar code on Interned and I didn’t found exactly what I want. Hope this code will help others which want to do this type of communication. I don’t say that the code is perfect but it works… 😉

!!! Before reading something from the SPI line it is important to send a dummy data, which starts the SCK signal just for transmiting a byte of information.

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: