51单片机学习记录——数码管动态显示

正在学习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;

反过来也一样。如果先段选,那么清空位选数据即可。

百度百科有人问了一个差不多的问题,这里引用过来供大家参考:

经验总结:数码管的显示,段选数据和位选数据要紧贴,中间不要夹杂其他语句。换句话说,计算在先,最后一次性传送数据。

原文地址:https://www.cnblogs.com/alexsun/p/3489016.html