踩坑记录:我们遇到的那些邪门问题与解决方案
上篇回顾:我们抱着设备走进三间教室,连续监测了五场2小时的课。数据证明趋势预警确实有效——VENTIL总在MUGGY!前20到40分钟出现。但说出来你可能不信,这台机器在诞生过程中,差点被三个邪门问题逼到绝路。今天不讲成功学,只讲我们是怎么掉坑里、又是怎么爬出来的。
坑一:AM2320的“起床气”
现象
程序写好,烧录,上电。LCD亮了,但第二行显示的不是温湿度数值,而是两个巨大的感叹号——“!!”。
我们检查了接线,没问题。检查了代码逻辑,没问题。重新上电,依然是“!!”。偶尔会正常显示一组数据,然后下一轮又变“!!”。
这就很诡异了。传感器分明连着,供电也正常,为什么它时灵时不灵?
排查
翻AM2320的数据手册(说实话,这是整个项目中我们翻得最仔细的一份文档),找到了一段容易被忽略的描述:
“传感器在完成一次测量后会自动进入休眠状态,需由主机发送起始信号唤醒。”
原来如此。AM2320是个“节能主义者”,每次干完活就倒头睡觉。我们第一次读取数据时,传感器还醒着,所以读到了正确的数值;但读完之后它睡着了,而我们的程序没有做唤醒动作,直接发起下一次读取——传感器根本没理我们,返回了错误码,于是显示“!!”。
解决
很简单:每次读取数据前,先发I2C起始信号,然后等2毫秒。
void wake_AM2320() { I2C_Start(); // 发送起始信号 I2C_SendByte(0xB8); // 发送器件地址 delay_ms(2); // 留2ms让传感器苏醒并完成测量 }
这2毫秒是给传感器从休眠中爬起来、完成内部测量的时间。加上之后,传感器再也没有闹过“起床气”,“!!”彻底消失。
教训
读数据手册时,别只盯着电气参数和通信时序看,“工作模式”和“功耗管理”这类看似软性的内容,往往藏着最大的坑。传感器的省电策略,恰恰可能成为实时监测系统最大的绊脚石。
坑二:单片机“精神分裂”,LCD显示乱码
现象
第二个坑出现在一次烧录之后。上电后LCD显示的不是我们设定的“T:--.-C H:--.-%”,而是一堆乱码——有的字符在闪烁,有的完全认不出,整体就像一台坏掉的电子表。
我们第一反应:代码写错了。于是改代码,重新编译,重新烧录。乱码依旧。
再改,再烧,还是乱码。前后烧了四五次,每次修改不同的初始化时序和延时参数,毫无改善。有人开始怀疑是LCD1602本身坏了——毕竟这玩意娇贵,静电都能打坏。
排查
用万用表测LCD各个引脚的电压。对比度调节脚正常,背光正常,但数据脚上的电压一直在小幅抖动——不对劲,正常情况下应该是稳定的TTL电平。
顺着电源线往回查。STC89C52的供电电压也在抖。
最终发现:单片机芯片在烧录座上没有卡紧。那个烧录座的卡扣略有松脱,芯片的VCC脚和烧录座的触点之间有时接触、有时断开,导致供电时断时续。单片机在这种“吃不饱”的状态下勉强工作,就像人发着高烧还要算数学题——别说不正常了,能亮屏都算它顽强。
解决
把芯片重新用力按进烧录座,听到“咔哒”一声卡紧。上电,LCD规规整整地显示出“T:22.0C H:43.0%”,一切正常。
那一刻的心情很复杂——改了四五轮代码,最后发现是物理接触问题。想抽自己,也想笑。
教训
嵌入式开发是软硬一体的世界。当软件逻辑反复检查都正确时,不要只盯着代码看,去摸一摸电路板,量一量电压,摁一摁芯片。很多时候,Bug不在代码里,在物理世界里。
坑三:LCD单位神秘失踪
现象
前两个坑解决后,系统终于能稳定工作了。温湿度数值正确,状态判断正确,蜂鸣器也响得准。但仔细一看,LCD的显示有点不对劲——
第一行显示的是 T:22.0 H:43.0,而不是 T:22.0C H:43.0%。
摄氏度的“C”和湿度的“%”凭空消失了。
数值是对的,但不知道单位,这让人怎么看?22.0是度还是华氏度?43.0是百分比还是什么别的?
排查
回到代码里查LCD显示函数。我们用的是字符定位写入的方法:
LCD_SetCursor(0, 6); // 定位到第一行第7列 LCD_WriteChar('C'); // 写入℃符号 LCD_SetCursor(0, 14); // 定位到第一行第15列 LCD_WriteChar('%'); // 写入%符号
逻辑看起来没问题。但实际显示时,C和%都没有出现。
仔细核对坐标后发现:温度数值“T:22.0”占用了7个字符位置(T、:、2、2、.、0、空格),而我们设定的光标位置是第7列——但实际上应该在第8列。差了一格。这个偏差让C被写到了屏幕显示区域之外(或者覆盖了其它字符),而%符号也因为类似的计算错误,被安排到了错误的位置。
问题根源是:写代码时心算了一下坐标,没有逐个字符数清屏幕位置,结果偏了一位。
解决
重新梳理第一行的字符布局。
修正坐标参数,把C写在第6列(0起始计数),%写在第14列。烧录后,T:22.0C H:43.0%完整呈现。
教训
屏幕显示无小事。看起来只是少了一个小小的“C”,但对用户来说,没有单位的数字就是废数。写界面时,拿一张纸把每个字符的位置画出来再编码,比脑子心算靠谱十倍。
这三个坑教会我们什么
项目做完了再回头看,这三个坑看似低级,但每一个都恰好卡在嵌入式开发最容易被绊倒的地方:
-
坑一是“软件与器件特性的脱节”——不知道传感器会睡觉,因为没仔细读手册里那段不起眼的描述。
-
坑二是“软件与硬件的边界模糊”——代码看起来全对,但问题出在物理连接上,不摸一摸永远找不到。
-
坑三是“细节精度掉链子”——系统都能算趋势了,差点因为一个单位字符错位让显示失去意义。
做嵌入式,永远是在跟现实世界打交道。传感器会睡觉,芯片会接触不良,你的眼睛会数错坐标——把这些都算进开发过程,才是真正的工程思维。
下一篇预告
坑爬完了,项目也做完了。在最后一篇里,我会做一个完整的复盘:这个项目给了我们什么?如果再做一遍会怎么改进?那套趋势预警的思路,还能用在哪些地方?
下一篇:《复盘与展望——这个项目带给我们什么?》,给整个系列一个收尾。
- 点赞
- 收藏
- 关注作者
评论(0)