显示器鬼影,一般来说存在有硬件问题和软件问题两种,而电子元器件经历了数十年的发展,现在可以见到的芯片基本运行速度都足以抵消鬼影问题。 所以,一般来说鬼影多存在于代码编写的问题上,所以,以此文章记录我关于鬼影的一些心得体会。 首先是放一下没有优化前的效果图: 很显然,LED上面不需要显示的地方也有微弱的亮光,严格来讲,这是不被允许的。 而观察数码管,也可以发现第五位上显示了一个浅浅的“6”,这个同样也会误导使用者,从而可能读出错误的数据。
此时,我的驱动代码块为 因为驱动的是138译码器,之前使用过一种一个引脚一个引脚的赋予状态(如下图所示),但是会发生令人感到不妙的竞争冒险现象 于是,我尝试改进了138译码器驱动部分的代码,仔细查找了途径的译码器(74HC138)和锁存器(74HC573)的电平变化时间,通过保守计算并加上了一定的冗余时间。得到了以下的改进代码:
首先,我通过将P2赋值了一个没有用到的端口Y0,确保接下来对数据口的操作干扰不会影响到应该正常工作的端口。然后,在切换端口之前将数据提前赋值给数据端口,防止因为改变数据造成鬼影。最后,是通过不影响除了P25,P26,P27之外端口的方式(相或方式),赋值给138端口,并且留出足够的时间(10us),来完成电平的变化的记忆保持。 此时,将代码下载进入实体开发板后,LED的鬼影完全的被消除了。但是数码管仍然存在鬼影。因为驱动138数码管的部分我们已经完成了优化。所以,问题应该出现在了动态刷新的代码上面。 通过阅读之前的代码,我们可以得知: 每次切换数码管时,可能因为驱动段码的数据残留而导致鬼影。 所以,我着重对这段代码进行了测试,发现因为刷新速度较快,上一个段码的数据因为IO口的变化延时,会在其他位置造成“数据污染”,也就是我们说的鬼影了,既然硬件上存在了这一点电容我们无法去除,而如果计算残留时间通过延时的方法去除又过于麻烦,所以我选择提前加入了一句清空段码的数据操作。
如下图所示,是改进过后的数码管驱动代码片段: 这其中,主要发挥了作用的就是 control(Duan, 0xff); 这一句代码,剩下的都是对代码结构的一些简单优化 通过提前清除数据,就可以做到如果数据存在残留,可以先提前“清除”掉,有效的防止了鬼影的产生。
至此,关于鬼影的所有优化就已经完成了,下面来看一下优化过后的图片: 很显然,LED和数码管的鬼影都消失了,此时的显示也变得干净与清爽了起来。
|