在学习动态数码管之前,我们要先介绍一个延时函数Dealy的编写
打开STC-ISP
这是一个12MZ的单片机关于1ms的延时函数,当单片机执行这段程序时需要1ms才能执行后面的程序,以达到延时1ms的效果。
其他型号的开发板可以在主板中找以下的元器件,单片机的晶振就是上面的数字
将我们得到的delay函数稍加修改
//延时子函数
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
这个Delay函数中,不同晶振的i、j数值不同,不要盲目修改成一样的,如果对延时的时间不要求太精准,也可以直接拿来使用。
通过上一篇文章,我们可以在八个数码管中选中一个数码管,让其显示0-9的任意数字。
由于74HC138同一时间只能输出一个0,即只可以选择一个数码管,那么想要让8个数码管都亮起来,我们需要其他的办法去解决这个问题,它就是动态数码管。
我们知道电视的画面是闪烁的,如果用手机的视频模式去拍摄电视,那么会有闪烁的现象。
为什么电视的屏幕显示是间断的,而我们看到的确实流畅的画面?因为余晖效应,即人眼的视觉暂留会让消失的画面还停留在我们的脑海里,然后又有新的画面出现衔接上已经消失的画面,从而产生画面流畅的感觉。
根据这个原理,我们让数码管依次快速点亮,只要切换的速度足够快,那么人眼是无法发现其他数码管是熄灭的,看起来就是8个数码管全部点亮。
使用上一篇文章的void Nixie(unsigned char Location,Number)函数,我们可以在主程序main中这样写
void main()
{
while(1)
{
Nixie(1,0); //在数码管的第1位置显示0
Nixie(2,1); //在数码管的第2位置显示1
Nixie(3,2); //在数码管的第3位置显示2
Nixie(4,3); //在数码管的第4位置显示3
Nixie(5,4); //在数码管的第5位置显示4
Nixie(6,5); //在数码管的第6位置显示5
Nixie(7,6); //在数码管的第7位置显示6
Nixie(8,7); //在数码管的第8位置显示7
}
}
由于是需要依次循环点亮,所以把执行代码放在了while(1)中,这样代码可以一直在while()里面循环执行。
但是这样的代码是在实际使用时会有问题,以下的实际运行该代码的实物图
这个情况是由于数码管是先位选再段选,当新的位选开始而新段选还没有开始,这段时间新的位选执行在旧的段选上面。
解决办法是在段选后加一点延时。(数码管的消影)
//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
switch(Location) //位码输出
{
case 8:P2_4=1;P2_3=1;P2_2=1;break;
case 7:P2_4=1;P2_3=1;P2_2=0;break;
case 6:P2_4=1;P2_3=0;P2_2=1;break;
case 5:P2_4=1;P2_3=0;P2_2=0;break;
case 4:P2_4=0;P2_3=1;P2_2=1;break;
case 3:P2_4=0;P2_3=1;P2_2=0;break;
case 2:P2_4=0;P2_3=0;P2_2=1;break;
case 1:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[Number]; //段码输出
Delay(1); //显示一段时间
P0=0x00; //段码清0,消影
}
数码管消影后,即可以得到符合预期的实际效果了
#include <REGX51.H>
//数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//延时子函数
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
switch(Location) //位码输出
{
case 8:P2_4=1;P2_3=1;P2_2=1;break;
case 7:P2_4=1;P2_3=1;P2_2=0;break;
case 6:P2_4=1;P2_3=0;P2_2=1;break;
case 5:P2_4=1;P2_3=0;P2_2=0;break;
case 4:P2_4=0;P2_3=1;P2_2=1;break;
case 3:P2_4=0;P2_3=1;P2_2=0;break;
case 2:P2_4=0;P2_3=0;P2_2=1;break;
case 1:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[Number]; //段码输出
Delay(1); //显示一段时间
P0=0x00; //段码清0,消影
}
void main()
{
while(1)
{
Nixie(1,0); //在数码管的第1位置显示0
Nixie(2,1); //在数码管的第2位置显示1
Nixie(3,2); //在数码管的第3位置显示2
Nixie(4,3); //在数码管的第4位置显示3
Nixie(5,4); //在数码管的第5位置显示4
Nixie(6,5); //在数码管的第6位置显示5
Nixie(7,6); //在数码管的第7位置显示6
Nixie(8,7); //在数码管的第8位置显示7
}
}
以上就是动态数码管的编写。