使用TM4C123GH6PM 的I2C读取TMP75温度寄存器的值,使用一个例程读取到的值是对的,但是它的函数操作顺序与123gh6pm的数据手册不同,我自己参照123gh6pm数据手册写了一个读寄存器函数,但发现读出来的值是乱的, 下面第一个函数是例程,第二个函数是我自己写的. 希望大家能帮忙看一下哪里出了问题,ps(其它配置计算等皆无问题,)
/********************************************
* 例程里的读寄存器函数,能正确读取温度值
* TMP_READ_DELAY是600
* *****************************************/
uint16_t
TMP75DataRead(void)
{
uint8_t i2cWriteBuffer;
uint32_t i2cReadBuffer[2];
uint16_t temp_value;
uint16_t i2c_read_delay;
i2cWriteBuffer = TMP_TEMP_REG;
i2cWriteBuffer &= 0x03;
// frame 1:
I2CMasterSlaveAddrSet(I2C1_BASE, TMP_I2C_ADDR, false);
// frame 2:
I2CMasterDataPut(I2C1_BASE, i2cWriteBuffer);
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND);
i2c_read_delay = TMP_READ_DELAY;
while (i2c_read_delay–);
// frame 3:
I2CMasterSlaveAddrSet(I2C1_BASE, TMP_I2C_ADDR, true);
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
// frame 4:
i2cReadBuffer[0] = I2CMasterDataGet(I2C1_BASE);
i2c_read_delay = TMP_READ_DELAY;
while (i2c_read_delay–)
;
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
// frame 5:
i2cReadBuffer[1] = I2CMasterDataGet(I2C1_BASE);
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
temp_value = (i2cReadBuffer[0] << 8) | i2cReadBuffer[1];
return temp_value;
}
/*
* 这是我自己写的读寄存器函数 ,读出的值不对
* 入口参数: ui32I2CBase — i2c基址, ui8SlaveAddr — 从机地址,
* ui8RegAddr — 寄存器地址
* 返 回 值: ui16RegData — 读到的寄存器值
*/
uint16_t I2CReadRegTwoByte(uint32_t ui32I2CBase, uint8_t ui8SlaAddr,
uint8_t ui8RegAddr)
{
uint8_t ui8WriteBuffer = 0; /* 写缓冲器 */
uint32_t ui32ReadBuffer = 0; /* 读缓冲器 */
uint16_t ui16RegData = 0;
// 查询BUSY位
while(I2CMasterBusy(ui32I2CBase))
{
;
}
// frame 1: 向从机地址I2CMSA寄存器写从机地址
ui8WriteBuffer = ui8SlaAddr;
I2CMasterSlaveAddrSet(ui32I2CBase, ui8WriteBuffer, false);
// frame 2: 向数据寄存器I2CMDR写数据
ui8WriteBuffer = ui8RegAddr;
I2CMasterDataPut(ui32I2CBase, ui8WriteBuffer);
// // 查询BUSBUSY位 (多主机模式) (单主机模式下或被忽略)
// while(I2CMasterBusBusy(ui32I2CBase))
// ;
// frame 3: 向控制/状态寄存器I2CMCS 写 "—0-011" 产生start 不产生stop
I2CMasterControl(ui32I2CBase, I2C_MASTER_CMD_BURST_SEND_START);
// 查询BUSY位
while(I2CMasterBusy(ui32I2CBase))
;
// 查询ERROR位
while(I2CMasterErr(ui32I2CBase) != I2C_MASTER_ERR_NONE)
{
// 若有错误 死在这里或进入中断处理程序
;
}
/******************传输后以重复开始序列进行的接收***************/
// frame 4: 向从机地址I2CMSA寄存器写从机地址
I2CMasterSlaveAddrSet(ui32I2CBase, ui8SlaAddr, true);
// // 查询BUSBUSY位 (多主机模式) (单主机模式下或被忽略)
// while(I2CMasterBusBusy(ui32I2CBase))
// ;
// frame 5: 向控制/状态寄存器I2CMCS 写 "—01011" 产生重复开始
I2CMasterControl(ui32I2CBase, I2C_MASTER_CMD_BURST_RECEIVE_START);
// 查询BUSY位
while(I2CMasterBusy(ui32I2CBase))
;
// 查询ERROR位
while(I2CMasterErr(ui32I2CBase) != I2C_MASTER_ERR_NONE)
{
// 若有错误 死在这里或进入中断处理程序
;
}
// frame 6: 从主机数据寄存器I2CMDR读第一个数据, 默认高8bit(MSB)
ui32ReadBuffer = I2CMasterDataGet(ui32I2CBase);
ui16RegData = ui32ReadBuffer << 8;
// frame 7: 向控制/状态寄存器I2CMCS 写 "—00101" 产生stop
I2CMasterControl(ui32I2CBase, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
// 查询BUSY位
while(I2CMasterBusy(ui32I2CBase))
;
// 查询ERROR位
while(I2CMasterErr(ui32I2CBase) != I2C_MASTER_ERR_NONE)
{
// 若有错误 死在这里或进入中断处理程序
;
}
// frame 8: 从主机数据寄存器I2CMDR读第二个数据, 默认低8bit(LSB)
ui32ReadBuffer = I2CMasterDataGet(ui32I2CBase);
ui16RegData |= ui32ReadBuffer;
return ui16RegData;
}
这是芯片读时序图

user4515746:
这是数据手册上的流程图
xyz549040622:
回复 user4515746:
仔细对比了下,发现基本操作都是一样的。你出现寄存器的值乱是什么意思呢?直接看输出读到的值是否和实际一致?怀疑你数据处理的时候出错了。
user4515746:
回复 xyz549040622:
这是读取寄存器之后处理数据的函数,其他的都不变,只把里面的读寄存器的函数换了一下读出来的值就不对了,用第一个TMP75DataRead()的话读出的温度就是对的,
换成我写的I2CReadRegTwoByte(I2C1_BASE, TMP_I2C_ADDR,TMP_TEMP_REG&0x03)温度就不对了,
floattemp_read(void){ volatile float temp_degree; uint16_t temp_value = 0;
temp_value = TMP75DataRead();
//temp_value = I2CReadRegTwoByte(I2C1_BASE, TMP_I2C_ADDR,TMP_TEMP_REG&0x03);
temp_degree = (uint8_t)temp_value + ((float) ( ( temp_value ) >> 12 ) ) * 0.0625 ;//*0.0625
return temp_degree;}
这是串口打印出来的我的函数读出的错误的温度值
user4515746:
回复 xyz549040622:
这是读取寄存器之后处理数据的函数,其他的都不变,只把里面的读寄存器的函数换了一下读出来的值就不对了,用第一个TMP75DataRead()的话读出的温度就是对的,
换成我写的I2CReadRegTwoByte(I2C1_BASE, TMP_I2C_ADDR,TMP_TEMP_REG&0x03)温度就不对了,
floattemp_read(void){volatile float temp_degree;uint16_t temp_value = 0;
temp_value = TMP75DataRead();
//temp_value = I2CReadRegTwoByte(I2C1_BASE, TMP_I2C_ADDR,TMP_TEMP_REG&0x03);
temp_degree = (uint8_t)temp_value +((float) ( ( temp_value ) >> 12 ) ) * 0.0625 ;//*0.0625
return temp_degree;}
这是串口打印出来的我的函数读出的错误的温度值
user4515746:
回复 xyz549040622:
问题暂时解决了,我把我自己写的函数里面的高低位组合互换了一下,发现结果正确了,但是问题来了,这样的话理论上说例程里的高地位组合和我的高地位就完全反了,但是同样的数据处理得到的结果却是一样的,所以我分析觉得例程里读取寄存器值应该是读取了三个字节,第一次空读了BYTE1,第二次读了一个字节BYTE2给了data[0],第三次又读了一个字节,此时芯片给的数据是再次重复,也就是说第三次读的还是BYTE1给了data[1],因此得到的结果与我读到的结果是高地位相反的,同样的数据处理得到的值就是错的.不知道分析的对不对,大家觉得应该问题应该出在什么方面?
azhiking:
回复 user4515746:
数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位
TI中文支持网





