资料目录
单片机应用
LCD花屏的程序调试过程
发布日期:2011/11/11
格芯单片机原创文章,转载请注明出处!
______________________________________________________________________
格芯单片机在项目中遇到了该死的LCD花屏(即在LCD屏上显示的内容由于受干扰而变的乱七八糟,一般表现为缺块、多点、错位,或无显示),而且是很随机的那种,在你不经意间一下就蹦出来,而当你仔细来测试问题时,它却跟你玩捉迷藏。
由于项目中没有射频方面的应用,所以受硬件干扰的可能性不大。
初步诊断为中断程序影响的结果。为此我写了一个小测试程序,让程序在一个循环内接受按键,然后刷新整屏数据。(我的键盘处理程序放在中断程序里调用的)。很快就证实我的想法。随着按键的频率加快,花屏出现的次数明显增多。
好,调到这一步可以肯定花屏与按键有关,我仔细分析了一下按键程序,本身应该是没什么问题的,问题可能是在中断里调用带来的。我也知道中断里是越简洁越好,尽量只在中断里面设标志,而在应用里处理,
但我这是在外部硬中断中启动的键盘扫描,没办法。我又把 Keil C 根据这段代码产生的汇编代码找了出来,仔细的分析一遍。发现按键程序从外部的器件取数据的指令 MOVX 有点可疑。在网上查了一阵资料后发现 KEIL的编译参数里有这么个选项 Don't use absoluteregister accesses.该选项控制编译器使不使用对R0-R7的直接寄存器寻址(直接存取可以提高生成代码的效率)。使用该选项禁止对RO-R7的直接寻址,这样编译出的函数将不依赖于某个寄存器组,也可能用到8051所有的寄存器组。这个选项用在一个函数调用另一函数,而这两个函数使用不同的寄存器组时。似乎问题有点眉目了,与 MOVX 指令无关,而是因为在中断里调用按键程序时,由于工作寄存器组已经切换,所以传递的参数出现了混乱。于是,我立马把该选项勾上,重新编译,测试,问题有所好转,花屏的次数明显下降,但没有完全解决问题,现象依然存在。
看来花屏的原因不止一个,郁闷,眼看就山穷水尽了,我也黔驴技穷。有点不死心,只好硬着头皮拿出了最蠢也是做实用的一招。因为中断里也就80几行代码(主要是按键程序),我一行一行的屏蔽,屏一行DOWN 一次程序,然后测试、看效果,如果没效果就屏下一行,再DOWN 程序、测试、看效果。如果还是没有效果就再重复上一过程。就这样,当我把这80几行代码屏的差不多的时候,问题就浮现出来了。罪魁祸首是一叫 beep() 的函数,而次函数就一行代码 P1_1 = 0;这是一按键音函数,也就是给接在 P1_1 脚上的蜂鸣器一低电平,让蜂鸣器滴答的叫一声。
在此调用 beep() 函数表面上是看不出问题,难道是中断嵌套太深?我随手将beep()改成P1_1 = 0,然后DOWN 程序测试。奇迹出现了,这个程序再怎么快按键也不会花屏。