PIC18F2580 [SPI]- Problem with communication to ADT7310

Find out how to setup your programmer's software and how to solve many common problems.

Moderator: phalanx

Post Reply
flukeco
Posts: 3
Joined: Fri Apr 25, 2014 4:54 am

PIC18F2580 [SPI]- Problem with communication to ADT7310

Post by flukeco » Wed May 07, 2014 6:40 am

Hi everyone,

First of all I want to apologize in advance for my bad English. I'm not a native speaker, but I'll try my best to explain the problem I have.

Now I'm trying to communicate with temperature sensor (ADT7310) via SPI bus.

I'm using PIC18F2580, 10Mhz internal oscillator with PLL enabled (so the clock frequency is 40Mhz), and ADT7310 temperature.
For the compiler, I'm using MPLAB IDE and XC8 compiler.

First, I tried to read the temperature values, but I'm receiving some meaningless values, so I suspected that my SPI settings might be wrong.

Since the code for my temperature reading is quite long, and I only need to know whether my SPI settings is correct or not, I rewrite my code to only read the device status register (register address 0x00). If my settings is correct, I should receive 0x80 as stated in the datasheet.

Unfortunately, instead of receiving 0x80, I received some 8-bit junk. However, that 8-bit junk is consistent all the time (0x47 to be more specific).

I neither have access to oscilloscope nor the logic analyzer, so I have no idea why this goes wrong.

I've read ADT7310's datasheet many times and found some articles which contain working code. So I'm pretty sure that I set clock polarity (CKP), clock edge selection (CKE), and sampling phase (SMP) bits to communicates with ADT7310 correctly via SPI.

Also PIC18F2580's datasheet states that using Fosc/4 at 40 Mhz will give the maximum data rate of 10.00 Mbps, so I'm also pretty sure that I'm on the right track.

I also have 1 more problem. When I debug my program by setting breakpoint and then use "Step Into", the variable that I'm using to store SSPBUF will contain a value (even if it's not what I expected). However, if I set breakpoint and then "Run", when the breakpoint is hit, the variable that I'm using to store SSPBUF is zero all the time. For example:

Code: Select all

    while (1) {
        PORTAbits.SS = 0;           /* enable SPI */

        SSPBUF = 0b01000000;     /* read register 0x00 (status register)*/
        while(!PIR1bits.SSPIF);     /* wait for transmission to completed */
        value = SSPBUF;             /* receive 8-bit value */

        PIR1bits.SSPIF = 0;         /* clear SSP interrupt flag */   <-- breakpoint here, if I use "step into" until come to
                                                                   this line again, value is 0x47. However, if I click
                                                                  "Continue", when the breakpoint is hit next time value
                                                                   contains 0x00

        PORTAbits.SS = 1;           /* disable SPI*/
    }
The following is my completed code. If you find something wrong or have any suggestions, please tell me. your help would be highly appreciated.

Thank you in advance for your help, and again, sorry for my bad English.

Pat

Code: Select all

int main(void) {
    unsigned char value = 0;

    ADCON1 = 0x0F;     /* set all port A pins, including SS (RA5), as digital I/O */

    TRISCbits.RC3 = 0;  /* set SCK as output pin */
    TRISCbits.RC4 = 1;  /* set SDI as input pin */
    TRISCbits.RC5 = 0;  /* set SDO as output pin */
    TRISAbits.RA5 = 0;  /* set SS as output pin */

    SSPCON1 = 0b0000;           /* master mode, Fosc/4 */

    SSPSTATbits.SMP = 0;        /* input data sampled at middle of data output time */
    SSPSTATbits.CKE = 1;        /* transmit on transition from active to idle clock state */

    SSPCON1bits.CKP = 1;        /* clock idle state is high, active is low */

    PORTAbits.SS = 1;       /* disable SPI*/
    SSPCON1bits.WCOL = 0;   /* clear write collision */
    SSPCON1bits.SSPOV = 0;  /* clear receive overflow */

    SSPCON1bits.SSPEN = 1;      /* enable serial port (SCK, SDO, SDI, SS pins) */

    while (1) {
        PORTAbits.SS = 0;           /* enable SPI */

        /* ADT7310's command byte format: */
        /* bit 7 must be 0, bit 6 is R/W bits (0 for write, 1 for read), bits<5:3> = register address */
        /* bit 2 is continuous read mode (for reading temperature value register (address 0x02) only */
        /* bits<1:0> must be 0 */
        SSPBUF = 0b01000000;     /* read register 0x00 (status register)*/
        while(!PIR1bits.SSPIF);     /* wait for transmission to completed */
        value = SSPBUF;             /* receive 8-bit value */
        PIR1bits.SSPIF = 0;         /* clear SSP interrupt flag */

        PORTAbits.SS = 1;           /* disable SPI*/
    }

    return (EXIT_SUCCESS);
}

waltr
Support Volunteer
Posts: 2823
Joined: Tue Sep 08, 2009 12:07 pm
Location: Philadelphia, USA

Re: PIC18F2580 [SPI]- Problem with communication to ADT7310

Post by waltr » Wed May 07, 2014 10:53 am

Without looking at your code check/try the following:
Use a slower clock speed to ensure there is not a speed issue in the hardware. If you get the clock speed down around 10kHz then you can use a very low cost logic analyzer (PICKit2 utility or a PC Audio input).

Double check the SPI Mode. There are four modes in the setup that change the Idle level, and the clock to data phase (sample data on falling or rising edge of the clock. Each SPI device can require a different SPI mode (Analog devices is different than Micro chip). This is where a logic analyzer or O'scope is handy.

Post Reply