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.

TMP102和TMP112温度瞬时变化时读取无响应

Other Parts Discussed in Thread: TMP102, MSP430FR2433, TMP112

手上有TMP102和TMP112,发现正常温度变化缓慢时,读取应答都正常,但是当某段时间温度变化剧烈(比如拿热吹风吹热风时)去读取内部温度寄存器时发送器件地址(0x48)会没有响应,稳定一会儿后又好了,换了很多片都是这个现象。单片机使用的msp430fr2433,有用其它单片机(AVR)试一下没有这个现象,SDA\SCL引脚都是通过10K电阻上拉的,频率大概100K

/* --COPYRIGHT--,BSD
 * Copyright (c) 2017, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/

#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;
}