正在学习51的数码管以及中断,打算利用六位数码管实现一个时钟的功能。
但使用数码管输出时,如果不添加延时语句,那么一直有显示混乱的现象,有时完全无法分辨清楚数字。
如果在传送完数据以后延时1ms,显示混乱情况会好转。
同时发现延时的时间越长,显示效果越好。但是当然,相应的显示稳定程度也会下降,即数码管闪烁。
程序中在送完段选数据以后已经使用了参考书中的“消影”语句:
1 dula=1;
2 P0=table[k];
3 dula=0;
4 P0=0xff;//“消影”
可是这个语句只是在有延时的情况下才有效果,如果我不写延时语句,那么显示依旧混乱。
虽然在显示过程延时不会影响中断的计时,但是我总不想依赖for语句写出来的延时。= =
于是自己就尝试了很多方法,想要解决这个问题,我的目标就是不写延时语句让数码管正常显示。
我有试过先向P0传送数据,然后打开锁存器,马上关闭。
如:
1 P0=table[k];
2 dula=1;
3 dula=0;
但是问题依旧
也尝试过在打开任一锁存器之前,再锁一次另一锁存器(即送一次低电平),仍然无效。
最后发现需要在输出数据之前加这么一段代码:
1 P0=0xff;
2 wela=1;
3 wela=0;
4 P0=0x00;
5 dula=1;
6 dula=0;//初始化消除干扰
加了这段代码,数码管显示不再混乱。语句的功能就类似于初始化一下锁存器的内容。
经过两天的研究,终于明白了期中的猫腻。现在发出来跟大家分享一下:
数码管之所以有“影”,根本原因是段选,位选数据无法同时送达。
具体解释一下:当我改变了位选的值后(改变了要显示的数码管),接下来才改变段选的值(改变要显示的数字)。而在这中间有微小的时间间隔,位选的值改变了,但是段选的值没变。也就是说,我改变了要显示的数码管,但是这个数码管显示的是上一个数码管的数字!想到这里,我有如醍醐灌顶,豁然开朗!当然,反之亦然,如果你是先段选再位选,同样有问题。请大家自己考虑。
所以不难解释上面那段代码的作用了,就是在输出之前将之前那个数码管显示空(或者不选择任何数码管)。
所以显然这个初始化代码还可以简化,但是要取决于你是先段选还是先位选。如果先位选,那么就要清空段选数据。
1 P0=0x00;
2 dula=1;
3 dula=0;
反过来也一样。如果先段选,那么清空位选数据即可。
百度百科有人问了一个差不多的问题,这里引用过来供大家参考:
经验总结:数码管的显示,段选数据和位选数据要紧贴,中间不要夹杂其他语句。换句话说,计算在先,最后一次性传送数据。