基于I2C的红外体温测量

神奇的I2C

众所周知,I2C调试是外围设备中调试最为麻烦的事。主要是因为时序和硬件连接等问题。下面是I2C的Wiki定义:

I²C (Inter-Integrated Circuit) is a multimaster serial single-ended computer bus used for attaching low-speed peripherals to a motherboard, embedded system, cellphone, or other digital electronic devices.

这次用MSP430的I2C调试一个含有DSP处理单元的红外体温测量元件MLX90615。里面含有16位的RAM和EEPROM。

遇到的问题

1)MLX90615的slave地址是0x5B,这其实是个7位地址(MSBs[7:1])1011011。而在MSP430中需要给定的就是这个7位地址。在STM32中需要给定的是8位地址10110110,最后一位根据write/read进行变化。所以认真读英文文档是非常重要的。

2)我把slave Adderss理解为选通地址。而MLX90615的数据读取地址是用[命令+地址]的方式定义的,便于去区分RAM和EEPROM。

3)时序问题。
读一个地址的正确时序应该是:start信号——> MSP430自动发送写在UCB1I2CSA寄存器中的SLave Address+Wr 然后从机应答——> 等到从机的应答信号之后,发送Word Byte,相当于读写命令。从机又会有一个应答信号——>等到从机的应答信号之后 重新发送一个起始信号,并配置读写方式为读,以便下一个周期硬件设置让从机发数据回主机(*)——> 主机收到从机在地址0x27处的16bit的数据和一个CRC校验字节。

*中等到从机的应答信号之后重新发送一个起始信号,并配置读写方式为读。这一步相当重要。只有设置了这一步,才能正确收到从机发过来的3个数据。

硬件电路

下面是硬件电路,SCL和SDA都用一个10K的电阻拉到3.3V上。可以维持SCL和SDA的稳定性。在实验过程中,有几次出现了没有从机应答的情况,后来又自个儿好了。我想是电路问题造成的3.3V被分压了,用示波器看过,电压会时不时跳变到2.3V左右的位置。

基于I2C的红外体温测量_第1张图片

程序

<!-- lang: cpp -->
void EEPROM_radom(unsigned char high_Address)
{
while (UCB1CTL1 & UCTXSTP);               // Ensure stop condition got sent
UCB1CTL1 |= UCTXSTT + UCTR;         // 发送起始位,确定为写 
UCB1TXBUF = high_Address;           // 发送地址位高位
while((UC1IFG & UCB1TXIFG)==0);           // 判断是否有应答信号

UCB1CTL1 &= ~UCTR;                        // 配置为接收
while (UCB1CTL1 & UCTXSTP);               // 判断总线是否被释放
UCB1CTL1 |=UCTXSTT;                       // 重新发送起始位
while((UCB1CTL1 & UCTXSTT)==1);           // 判断起始位是否发送成功
for(unsigned char i=0x0;i<0x1f;i++);      // 延时确定数据已经被发送出去 
while((UC1IFG & UCB1TXIFG)==0);
UCB1CTL1 &= ~UCTXNACK;  // 不发送停止位,给应答。让RAM返回3byte数据,每个byte返回一个应答。
}

UCB1CTL1 &= ~UCTXNACK; 这一步也非常重要,没有给从机应该的话只能读到0x27这个16bit内存的后8位。所以要配置为在收到数据后返回应答。

最后读出我的室内皮肤表面温度是24度。

Reference

[1].http://www.eefocus.com/nightseas/blog/2012-03/232785_30cd2.html

你可能感兴趣的:(基于I2C的红外体温测量)