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.

CCS/MSP430FR2433: TMP112 no response when the temperature changes instantaneously

Part Number: MSP430FR2433
Other Parts Discussed in Thread: TMP102, , TMP112

Tool/software: Code Composer Studio

Dear team,

My customer is using MSP430FR2433 with TMP102/TMP112.

The response is normal when temperature changes slowly. 

However,there will be no response when the temperature changes drastically for a certain period of time (such as when hot air is blown) and it will be better after a while.

Other MCU (AVR) without this phenomenon. The SDA\SCL pins are all pulled up through a 10K resistor, and the frequency is about 100K.

Please help.

#include <msp430.h>
#include <stdint.h>
#include <string.h>
#include <i2c.h>
#define TIMEOUT 60000

void i2c_init(void){
    static char init=0;
    if(!init){
        P1REN |= BIT2 | BIT3;
        P1OUT |= BIT2 | BIT3;

        // if the bus is stuck (SDA = low): clock until it recovers
        P1DIR |= BIT3;
        while(!(P1IN & BIT2)){
            P1OUT |= BIT3;
            __delay_cycles(8*80);
            P1OUT &= ~BIT3;
            __delay_cycles(8*80);
        }

        P1SEL0 |= BIT2 | BIT3;                  // I2C pins
        // Configure USCI_B0 for I2C mode
        UCB0CTLW0 |= UCSWRST;                   // Software reset enabled
        UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C mode, Master mode, sync
                                                // after UCB0TBCNT is reached
        UCB0BRW = 10;                       // baudrate = SMCLK / 10 = ~100K
        UCB0CTL1 &= ~UCSWRST;
        init = 1;
    }
}

int i2c_senddata(char *data, int len){
    unsigned int timeout=0;
    unsigned int i;
    static int dummy=0;
    /*if(dummy){
        UCB0TXBUF = 0;
        timeout = 0;
        while(!(UCB0IFG & UCTXIFG0))
            if(timeout++ > TIMEOUT)
                return -1;
    }
    if(dummy == 0) dummy = 1;
*/
     //__delay_cycles(5000);
    for(i=0;i<len;i++){
        UCB0TXBUF = data[i];
        timeout = 0;
        while(!(UCB0IFG & UCTXIFG0))
            if(timeout++ > TIMEOUT)
                return 3;
    }
    return 0;
}

int i2c_readdata(char *data, int len){
    unsigned int timeout=0;
    unsigned int i;

    memset(data, 0, len);
    for(i=0;i<len;i++){
        data[i] = 0;
        timeout=0;

        while(!(UCB0IFG & UCRXIFG0))
            if(timeout++ > TIMEOUT)
                return -1;


        data[i] = UCB0RXBUF;
        if(len > 1)
            if(i == len-2)
                UCB0CTLW0 |= UCTR | UCTXSTP;

    }
    //while(!(UCB0IFG & UCTXIFG0));
    return 0;
}

int i2c_start(char addr, int read){
    unsigned int timeout=0;
    UCB0I2CSA = addr;
    if(read)
        UCB0CTLW0 &= ~UCTR;
    else
        UCB0CTLW0 |= UCTR;
    while (UCB0CTL1 & UCTXSTP);
    UCB0CTLW0 |= UCTXSTT;            // I2C TX, start condition

    while(!(UCB0IFG & UCTXIFG0))
        if(timeout++ > TIMEOUT)
            return 1;

    if(UCB0IFG & UCNACKIFG)
    {
        UCB0CTL1 |= UCTXSTP;               // I2C start condition
        UCB0IFG = 0;                            // Clear All USCI_B0 flags
        return 2;      // check for NACK
    }

    if(!read){
        UCB0TXBUF = 0;
        while(!(UCB0IFG & UCTXIFG0));
    }

    return 0;
}

int i2c_start2(char addr, int read){
    unsigned int timeout=0;
    UCB0I2CSA = addr;
    if(read)
        UCB0CTLW0 &= ~UCTR;
    else
        UCB0CTLW0 |= UCTR;
    while (UCB0CTL1 & UCTXSTP);
    UCB0CTLW0 |= UCTXSTT;            // I2C TX, start condition

    while(!(UCB0IFG & UCTXIFG0))
    {
        if(timeout++ > TIMEOUT)
            return 5;
    }

    if(UCB0IFG & UCNACKIFG)
    {
        UCB0CTL1 |= UCTXSTP;               // I2C start condition
        UCB0IFG = 0;                            // Clear All USCI_B0 flags
        return 6;      // check for NACK
    }

    /*if(!read){
        UCB0TXBUF = d;
        while(!(UCB0IFG & UCTXIFG0));
    }*/

    return 0;
}

int i2c_stop(void){
    unsigned int timeout=0;
    UCB0CTLW0 |= UCTR | UCTXSTP;            // I2C TX, stop condition
    while(UCB0IFG & UCTXSTP)
        if(timeout++ > TIMEOUT)
            return 4;
    return 0;
}

int read_reg(int address, int reg){
    int err;
    char buf[2] = {reg};
    err = i2c_start2(address, 0);
    if(err != 0) return err;
    err = i2c_senddata(buf, 1);
    if(err != 0) return err;
    err = i2c_stop();
    if(err != 0) return err;
    __delay_cycles(10000);              //等待转换完成
    err = i2c_start2(address, 1);
    if(err != 0) return err;
    err = i2c_readdata(buf, 2);
    if(err != 0) return err;
    return buf[0]<<8|buf[1];

}

void write_reg(int address, int reg, int value){
    char buf[2] = {reg, value};
    i2c_start2(address, 0);
    i2c_senddata(buf, 2);
    i2c_stop();
}


void tmp117_init(void){
    i2c_init();
}

int tmp117_gettemp(void)
{
    unsigned int tmp117_raw = 0;
    float t = 0;
    tmp117_raw = read_reg(0x48, 0);
    tmp117_raw >>= 4;

    if(tmp117_raw <= 0x7ff){

        t= tmp117_raw * 6.25;

    }
    if(tmp117_raw>=0xc90) {
        tmp117_raw = ~tmp117_raw;
        tmp117_raw &=0x0fff;
        tmp117_raw +=1;
        t= tmp117_raw*6.25;
        t =-t;
    }
    return (int)t;
}

  • Hi Susan,

    is the bus completely stuck or is there any clock or data visible?

    Does the behavior also apply if the debugger is connected and if yes what is the outcome?

    By the way how the temperature is controlled with the hot air gut are you sure you do not violate the max allowed temp?

  • The waveform is shown below.

    The bus always be stuck. After the stuck, I will perform a stop operation or start operation.

    The result of connecting the debugger (LaunchPad onboard) is the same, and there is no response after sending the slave device address.

    I am sure that the allowable value is not exceeded. The highest temperature is more than 50℃.

    The normal waveform:

    And the Abnormal waveform:

  • On the working one the address is 0x90 not 0x48 or do I count incorrect?

    In fact on the abnormal wave form the address is send correctly but the slave does not ACK the address right? You should see this in the debugger as well that the address is not acknowledged right?

    Did you tried to reset the slave and try again?

    Also on the upper waveforms looks a little bit slow for the edges so can you please make the pull ups a bit stronger to make edges more steep by applying e.g. 5kOhm or 7.5kOhm for pull up.

  • Hi:

    address is 0x48(bit7~bit1),bit0 is Read/Write bit, here's 0, So bit7~bit0 is 0x90.

    yes, i'm sure the address is not acknowledged.

    I just perform a stop operation when no ack, then start to try again.

    now i used 10kOhm for pull up.

    I will try again as you suggest : reset the slave and Replace 10kOhm with 5kOhm 

    Thanks!

  • Hi Susan,

    were you able to try the different pull up values to get it working? Please let me know if anything is missing otherwise I will close this thread by end of the week.

**Attention** This is a public forum