开幕先抱怨一下,小小模块没有说明文档,客服一问三不知,原理图也不提供,害人不浅,啊啊啊啊啊。
后来为了测温更加方便准确,选择了外接的方案,于是板子上只预留了相应的接口,并且对IIC SDA和IIC SCL进行上拉。
为了方便以后的升级,在IIC总线上还预留上了EEPROM的位置
因为沟通上出现问题,需要我自己来选购一个LM75温度模块进行外接使用,于是看到了淘宝各种模块,最后选择销量高的一款下单。
有意思的是淘宝种类繁多的LM75模块,竟然没有一家可以提供详细的模块资料,连接方法也没有,有的仅仅是LM75官方的数据手册,难道默认买这种器件的都是专业的,所以就以为我们都懂?吐血。
不给我模块的说明我,我怎么能知道引脚都进行了哪些操作,或者我应该如何改进。
IIC通信首先要有一个地址,所以,第一点我先确认模块A0 A1 A2的状态,一开始自以为是的测量了对应的引脚,发现电压都是0,就以为已经预设好接地了。
然后就是因为我的预留口已经进行了总线的上拉,为了防止模块的影响,模块的上拉电阻是多少也要进行了解。
这里电阻上采用的印丝编号是E96贴片系列的编号方式,于是需要查询01C和30D,分别是10K和200K的阻值,
两个10K在模块中对SDA和SCL又进行了上拉,不会照成什么影响。
然后这里接用了师姐的LM75读取温度的代码,修改移植到了本次的项目中。
#include “LM75.h”
#define LM75_READ 0x91
#define LM75_WRITE 0x90
float I2C_LM75_Test(void)
{
uint8_t TempH,TempL;
uint16_t read_data;
float temp;
IIC_Start();
IIC_Send_Byte(LM75_WRITE);
while(IIC_Wait_Ack());
IIC_Send_Byte(0x00);
while(IIC_Wait_Ack());
IIC_Start();
IIC_Send_Byte(LM75_READ);
while(IIC_Wait_Ack());
TempH = IIC_Read_Byte(1);
TempL = IIC_Read_Byte(0);
read_data=((uint16_t)TempH << 8) | TempL ;
read_data=(read_data>>5);
if(TempH&0x80)
{
temp=-(float)((~read_data+1)0.125);
}
else
{
temp=(float)(read_data0.125);
}
IIC_Stop();
return temp;
}
根据IIC通讯的方式,代码也很容易理解,按照开始信号、结束信号和应答信号走就可以了。
这里呢,需要注意LM75的地址
前面的是固定的1001,即9,后面的A2 A1 A0是需要根据自己情况配置,作为自己的地址,也就是说这里可以最多允许222个LM75器件,最后一位是R/W控制读写,我这里的地址要配置成1001 000 0/(1),也就是0x90写,0x91读。
但是在实际的测试中,遇到了一个特别有意思的现象,就是如果我的手不去碰LM75模块,整个程序运行正常,可以读取到正常的温度,但是当我的手触碰LM75模块,程序就会进入“等待应答”的指令中,无法跳出。
一开始,我以为是连接的杜邦线有问题,但是检查了后,包括换了另一LM75,问题依旧,然后想到是不是地址问题,但是理论上也没有毛病。
一通检查,软件,硬件没有发现任何逻辑上的硬伤,就在这时候,坑爹的操作来了,我无意间拿起这个模块,看到了背面。
我才突然意识到,会不会是这里需要自己配置好才行,之前的A0 A1 A2接地是错觉,其实并没有接地,只是浮空,显示0电压,然后我手碰到模块,导致A0 A1 A2变化,地址发生改变,所以才无法应答。
为了验证,我又去问了客服,在这种方式的询问下,才告诉我,需要手动焊接上进行配置。
然后全部接地,这下之前的问题全都不见了,手碰也没事儿了,温度检测也准确了,反应也灵敏了。因为对于模块的不正当使用,导致浪费半天时间。模块为啥不写清楚使用方法,以及自己怎么安排的引脚,啊啊啊啊啊啊。
到这里,这个的功能全部实现,全部调通。剩下的就是收尾工作了,撒花。