问题现象:
项目上,部分GY-MCU90640和单片机通讯异常,在LCD上显示为三项温度均为0℃。
通讯正常的探头显示正常温度(这是一句废话!)
排查思路:
1、使用GY-MCU90640的PC软件直连GY-MCU90640探头。测试结果正常。
2、因为在生产中需要将探头和探头上的PCB分开,所以一开始怀疑是连接线和电源的问题,所以开始向这方面挺进~~
2.1 电源
使用万用表测量电压值,结果正常。
2.2 连线
用万用表测通断,正常。
向厂家咨询此方面问题,厂家怀疑连线可能收到干扰,建议探头与PCB间连线SCL缠绕GND或者使用屏蔽线。按照厂家建议进行处理,结果问题依然存在。
3、对数据进行排查
使用USB转TTL转换头, RX接传感器RX,TX 接传感器TX GND接传感器GND。分别接通讯正常探头和通讯异常探头,得两组数据,经通讯协议核算,数据有偏差,但在正常范围内。此时以为测得数据为单片机内存储的数据,其实不然,后见分晓。
4.对程序代码进行分析
在代码中,看到有一个程序段是这样写的:
if(jyyy1==jyyy2)
{ wdyxbz=1;
mm=0;
for(b=2;b<771;b++)
{
jyyy1=256*(uint)rx_buffer0[2*b+1]+(uint)rx_buffer0[2*b];
rx_buffer0[mm]=jyyy1/100;
mm++;
}
taa=0;
for(b=0;b<24;b++)
{for(mm=0;mm<10;mm++)
{
if(rx_buffer0[b*24+mm]>taa)
{
taa=rx_buffer0[b*24+mm];
}
}
}
tbb=0;
for(b=0;b<24;b++)
{for(mm=10;mm<22;mm++)
{
if(rx_buffer0[b*24+mm]>tbb)
{
tbb=rx_buffer0[b*24+mm];
}
}
}
tcc=0;
for(b=0;b<24;b++)
{for(mm=22;mm<32;mm++)
{
if(rx_buffer0[b*24+mm]>tcc)
{
tcc=rx_buffer0[b*24+mm];
}
}
}
sensort=rx_buffer0[768];
}
else
{
taa=0;tbb=0;tcc=0;sensort=0;
}
在代码中taa tbb tcc温度,只有当jyyy1==jyyy2时,才会对温度进行排序,显示最高温度。
所以有理由怀疑,jyyy1 jyyy2这两个是不相等的。
添加代码进行验证
{
taa=0;tbb=0;tcc=0;sensort=0;
if(jyyy1!=jyyy2)
{
taa=jyyy1%100;
tbb=jyyy2%100;
tcc=(jyyy1-jyyy2)%100;
}
}
结果,如前所料,jyyy1 jyyy2两者不相等。
以上为我个人努力的极限,以下为王工的指导,感谢!
jyyy1 jyyy2是校验码
jyyy1 是对769个温度数据进行求和运算结果。
jyyy2 是校验码运算结果。
既然校验不能使得数据正常显示,那就不要校验。
下载,上电,结果三个温度均为250+ 的夸张温度数据(探头对的是桌面,桌面没有烧火)
上面说到监听数据为探头给传感器主板传输的数据,想当然的以为是单片机内存储的内容。
其实不然,监听只能证:探头向主板在发数据。不能证明:主板上单片机存储的内容就是串口助手显示的内容。
证:主板单片机内存储的内容,使用putchar函数将缓存区rx_buffer0显示在串口助手上(主板TX接监听,断开探头TX,USB转TTL上,由探头过来的TX接TTL上的RX)。增添代码
for(jyyy1=0;jyyy1<1560;jyyy1++)
{
putchar(rx_buffer0[jyyy1])
}
串口助手上显示的结果为:
存储的数据,果然都是较大数据。
实际探头探测的温度为30+ ,存储数据结果为250+ 。
王工怀疑波特率过大,存在偏差,偏差分正负偏差。看原本程序中的偏差为负偏差,倍率×2,偏差变为正偏差。下程序,上电测试,温度值显示正常。
原程序关于波特率的设定:偏差为-3.2%
UCSR0A=0x00;
UCSR0B=0x98;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x08;
修改够的波特率设定:偏差为+2.1%
UCSR0A=0x02;
UCSR0B=0x98;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x10;
总结一下:
守得云开见月明,仰天长啸三万里。