我负责一个模块,功能比较简单,就是测量环境温、湿度,外加控制空调开/关、温度设定。就是这么几个功能,就反复试验、修改,才达到稳定。在调试时,出现各种各样的BUG,一些是编程时候出现的语法错误,一些是功能设计不合理的原因。其中有个BUG折腾了好久,今天终于发现原因,这还是别人帮助我才解决的。下面看看这除BUG的过程:
空调通讯方面问题比较多:
1、起初是有时候出现空调与模块完全不能通讯的现象;
2、出现空调与模块单边通讯的现象,即空调收到模块的指令,但模块没有收到空调返回的信息;
3、出现空调与模块首次上电时,情况2发生,但不重启的情况时,第二次之后完全通讯成功(双边通讯)的现象。
针对情况一,通过请教OMRON公司的技术人员,我了解到温控器接收指令与发送指令之间必须有一定的时间间隔,大概有500ms就可以了。所以我在发送数据程序中加入了500ms的延时指令,问题1情况不在出现,但随之而来的是问题2的频繁出现。这个问题困扰了我很长时间。在现场我做了如下试验:
首先,断开温控器与模块之间的RS485连接,然后通过usb转串口线把温控器与调试所用的笔记本连接起来,然后通过通过串口调试助手调试温控器,目的是为了验证温控器是否能够正常工作。经过试验,结果表明温控器完全能够正常工作。电气连接示意图如图1:
图1 温控器与上位机连接
接着,断开笔记本与温控器的连接,然后通过usb转串口线把模块与调试所用的笔记本连接起来,然后通过串口调试助手调试模块,目的是为了测试模块软件是否正常。经过试验,结果表明模块能够成功接收到串口助手发送过来的数据。电气连接示意图如图2:
图2 模块与上位机连接
最后,重新连接温控器与模块,上电,设置温度,情况2再次出现。电气连接示意图如图3:
图3 温控器与模块连接
同时连接温控器、模块、笔记本时候,则温控器与模块之间能够够正常通信。电气连接示意图如图4:
图4 温控器与模块、上位机连接
到此初步估计是由于RS485接线问题,经过询问OMRON公司技术人员可知,1对1时,RS485总线终端电阻(约为120欧姆)可有可无。模块上接有终端电阻,当我尝试去掉该电阻时,针对图3情况时,问题2得到解决。但出现问题3。
经过考虑,在模块上电初始化中,我加入了向空调发送“开空调”程序,这段程序能够保证每次模块上电时都要重新开启空调,以保证空调随时进行接收别的指令(当空调处于“关”时,它是不工作的,即使空调已经上电)。问题3得以解决。
到这里,本以为可以结束了,其实还有很大的问题,如果在模块上电之后才开空调的话,那么那个初始化中加入的指令就不会起作用,还是会出现问题3。这个方法治标不治本,后来,在一同事的帮助下,终于从根本上解决的问题。问题是这样解决的,只在一个地方加了这么一条语句。
void beginSend(void)
{
uint8 i = 0;
sendEnable(); //设为发送
TXSTAbits.TXEN = 1; //使能发送
for(i=0; i< sendCount; i++)
{
TXREG = sendBuf[i];
while (!TXSTAbits.TRMT); //TSR为空时置TRMT = 1
}
receEnable(); //设为接收
sendCount = 0;
receCount = 0; //这个很重要
TXSTAbits.TXEN = 0;
Delay10KTCYx(100); //延时500ms
}
关于这个函数就不多解释了。对比我这样、那样的测试,还是没有找到错误的根本原因,人家只是看了一遍调试报告,就立马找出了问题的所在。这固然有经验的问题,但更多的是我自身对于问题的分析不够冷静、思维不够严谨。还没有形成自己的一套发现错误、分析错误、解决错误的思维体系。在遇到“比较怪”的情况时,就乱了方阵,试图用穷举法把可能出现错误的地方都测试一遍,这大大消耗了时间,并且本质上讲并不能对解决问题有效的帮助。反而可能因为混乱一通的测试,遇到更多别的问题,最终偏离了正确解决问题的道路。
发现并找到一种合乎科学的编程习惯、除BUG思路是以后工作时的重中之重。