This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Source code for reading a TMP006 with an MSP430?

Other Parts Discussed in Thread: TMP006, MSP430F5529, MSP430G2553

Hello,

   I'll be needing to read the temperature of an object using the TMP006. Does anyone have source code to interface this with an MSP430? There are two parts:

1) Reading the values of the registers over I2C

2) Computing the temperature based on these values.

I'm fine using a lookup table for 2) but the MSP430 I'm using ('G2553) is limited in the amount of flash it has; so I'd prefer not to use more than 4-8kB of flash for the lookup table.

Thanks,

Derek

  • Derek9531 said:
    I'd prefer not to use more than 4-8kB of flash for the lookup table.

    Depending on the required accuracy, you can interpolate between values of a shortened lookup table. See how much error you can allow, and then calculate in Excel how close hte lookup points have to be so that a linear interpolation between them won't exceed thhis error margin.

    For I2C, there are lots of threads dealign with I2C read and write. There's also a TI library with generic I2C code. Also, there have been several requests for interface code for the TMP series in the past. I don't remember the TMP006, but if you're lucky...

  • Hey everyone,

    I am trying to read from TMP006 (EVM) to my MSP430F5529 experimentor board via I2C on USCI_B1. I am getting an NACKIFG after I transmit the slave address. The address mentioned at the TMP006 EVM user guide is 0X80 for transmit.

    Can anyone please advise me on my piece of code, it's fairly straight forward. Did I miss out on something? 

    Thanks, Gaurav

    #include <msp430f5529.h>

    #define SCL_PIN 0x04
    #define SDA_PIN 0x02

    #define slv_addr_tx 0x80
    #define slv_addr_rx 0x81

    #define internal_reg_addr_V 0x00
    #define internal_reg_addr_T 0x01

    unsigned char temp_MSB;
    unsigned char temp_LSB;


    int main(void)
    {
        while(UCB1STAT & UCBBUSY);                                       // Check if I2C bus is busy

    /*------------------- I2C (USCI_B1) initialization----------------------*/

    P4SEL |= SCL_PIN + SDA_PIN;                                           //Pin 4.1 und 4.2 for I2C
    UCB1CTL1 |= UCSWRST;                                                    //SW-Reset
    UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;                  //MD, I2C-Mode, Synchronous
    UCB1BR0 = 11;                                                                  
    UCB1BR1 = 0;
    UCB1CTL1 = UCSSEL_2 + UCSWRST; //SMCLK
    UCB1CTL1 &= ~UCSWRST;
    UCB1IE |= UCTXIE + UCRXIE + UCNACKIE;                           // Enable TX, RX, NACK interrupt

    /* ------------------Transmit slave address (write) and get acknowledgement-------------------*/

    UCB1I2CSA = 0x80;
    UCB1CTL1 |= UCTXSTT;                                                       // I2C start condition
    __bis_SR_register(LPM0_bits + GIE);                                    // Enter LPM0, enable interrupts

    /* ------------------Transmit slave address (read) and get acknowledgement-------------------*/
    UCB1I2CSA = 0x81;
    UCB1CTL1 |= UCTXSTT;                                                        // I2C start condition
    __bis_SR_register(LPM0_bits + GIE);                                    // Enter LPM0, enable interrupts

    return 0;
    }


    #pragma vector = USCI_B1_VECTOR
    __interrupt void USCI_B1_ISR(void)
    {
    switch(__even_in_range(UCB1IV,12))
    {
    case 0: break;                                                 // Vector 0: No interrupts
    case 2: break;                                                 // Vector 2: ALIFG
    case 4:                                                           // Vector 4: NACKIFG
              UCB1CTL1 |= UCTXSTP;
              UCB1STAT &= ~UCNACKIFG;
              break;
    case 6: break;                                                 // Vector 6: STTIFG
    case 8: break;                                                 // Vector 8: STPIFG
    case 10:                                                         // Vector 10: RXIFG
                temp_MSB = UCB1RXBUF;                 // Move RX data to address PRxData
                temp_LSB = UCB1RXBUF;
                UCB1CTL1 |= UCTXSTP;                      // Generate I2C stop condition
                __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
                break;
    case 12:                                                         // Vector 12: TXIFG
                UCB1TXBUF = internal_reg_addr_T;      // Load TX buffer to transmit register address
                __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
                break;

    default: break;
    }
    }

  • Hi,

    i am not really familiar with the TMP006, but a quick look at the datasheet - http://www.ti.com/lit/ds/symlink/tmp006.pdf - section "SERIAL BUS ADDRESS", it seems you need to make sure the the ADR1 and ADR0 in the right state to use the right address.

    I would recommend to look at the TMP006 Boosterpack: http://www.ti.com/tool/430boost-tmp006, and the firmware written for MSP430G2553 - http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/boosterpack/TMP006/latest/index_FDS.html. The MSP430G2553 has also USCI module, so the code should be re-usable for the MSP430F5529.

  • A normal 7-bit I2C address ranges from 0x00 till 0x7F including some reserved addresses. Also 0x80 is an invalid address.

     

    The EVM GUI software is misleading you. First the address field shows a decimal value but you have to write it as a hex value, second the address is shifted one bit to the left which is correct on the I2C bus but this should be internally done by the GUI software. Read and Write addresses are normally the same, why here a difference I don’t know. The TI software students should be more precise.

     

    The address range for the TMP006 is; 40h-47h. With ADR0 & ADR1 connected to GND the address is 40h. Write in your software also, for both read and write: UCB1I2CSA = 0x40; (The USCI will internally shift the address 1-bit to the left).

  • Gaurav Pratim Talukdar said:
    #define slv_addr_tx 0x80
    #define slv_addr_rx 0x81

    There is only one slave address, and it is the same for read and write. And it is 7 bit. What you define here, is the start byte, which contains the slave address and the R/W bit. The USIC assembles the start byte automatically, taking the slave address and the (inverted) UCTR bit.

     

    Gaurav Pratim Talukdar said:
    case 10:                                                         // Vector 10: RXIFG
                temp_MSB = UCB1RXBUF;                 // Move RX data to address PRxData
                temp_LSB = UCB1RXBUF;
                UCB1CTL1 |= UCTXSTP;                      // Generate I2C stop condition

    You only get one byte at a time. Reading RXBUF doesn’t wait until a new byte has arrived. When you get the RX interrupt, you got one byte. You need to count how many you received, and set the stop when there is only one left (because when the interrupt comes, you not only received a byte, but receiving the next has already started).

     

    Gaurav Pratim Talukdar said:
    /* ------------------Transmit slave address (write) and get acknowledgement-------------------*/

    UCB1I2CSA = 0x80;
    UCB1CTL1 |= UCTXSTT;                                                       // I2C start condition

    As I already said, you do not have to set the slave address separately. Set it once when you decide to talk to this device.
    But for transmitting, you need to set the UCTR bit (and to receive later, you need to clear it again). Either before or when you set UTXSTT.

     

    Gaurav Pratim Talukdar said:
    case 12:                                                         // Vector 12: TXIFG
                UCB1TXBUF = internal_reg_addr_T;      // Load TX buffer to transmit register address
                __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
                break;

    Here again, you need to count the number of bytes you send. You either send something, or, when there is nothing more to send, set UCTXSTP (unless you want to do a repeated start – in this case clear UCTXIFG, so the USCI doesn’t ask for more bytes to send)

**Attention** This is a public forum