手上有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 recoversP1DIR |= 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 modeUCB0CTLW0 |= UCSWRST;// Software reset enabledUCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C mode, Master mode, sync// after UCB0TBCNT is reachedUCB0BRW = 10;// baudrate = SMCLK / 10 = ~100KUCB0CTL1 &= ~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;elseUCB0CTLW0 |= UCTR;while (UCB0CTL1 & UCTXSTP);UCB0CTLW0 |= UCTXSTT;// I2C TX, start conditionwhile(!(UCB0IFG & UCTXIFG0))if(timeout++ > TIMEOUT)return 1;if(UCB0IFG & UCNACKIFG){UCB0CTL1 |= UCTXSTP;// I2C start conditionUCB0IFG = 0;// Clear All USCI_B0 flagsreturn 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;elseUCB0CTLW0 |= UCTR;while (UCB0CTL1 & UCTXSTP);UCB0CTLW0 |= UCTXSTT;// I2C TX, start conditionwhile(!(UCB0IFG & UCTXIFG0)){if(timeout++ > TIMEOUT)return 5;}if(UCB0IFG & UCNACKIFG){UCB0CTL1 |= UCTXSTP;// I2C start conditionUCB0IFG = 0;// Clear All USCI_B0 flagsreturn 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 conditionwhile(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; }
Susan Yang:
我们在周一分析后给您回复
Susan Yang:
若是可以的话,能否请您给出相关的通信波形?是否有可能是干扰造成了没能正常识别器件地址(0x48)从而导致无应答?
另外TMP传感器有一个Temperature Step Response,建议您在通信时等待其稳定后读取
user4190700:
回复 Susan Yang:
好的,我今天外出了,明天把通信波形上传一下,另外这个温度跃变应该不影响读取功能只是影响读取数据准确性吧
Susan Yang:
回复 user4190700:
现在总线是否完全卡住,是否存在任何时钟或数据?
如果连接了调试器,也是这样的结果吗?如果是,结果是什么?
另外,您如何通过热风口控制温度吗?您确定没有超过芯片允许的最高温度吗?
user4190700:
回复 Susan Yang:
您好!波形见下方,总线是会被卡住,卡住后我会进行一个停止操作或者开始操作,连接调试器(LaunchPad板载的)结果一样,也是发了从器件地址后无响应,确定没超过允许的最高温度,也就是50多℃。另外IIC驱动参考的https://www.ti.com.cn/tool/cn/TIDA-010019的软件代码
Susan Yang:
回复 user4190700:
请您跟踪/回复一下下面的链接
e2e.ti.com/…/3474417