手上有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;
}




