要想让数码管显示更多的内容,一种方式是增加数码管的个数,但这样会带来成本的增加和体积的增大;另一种可行的方案是让数码管滚动显示,写一个滚动显示的数码管并不复杂,下面将使用stc89c52rc单片机和开发板配套的8位数码管写一个可以让数码管滚动显示的代码。
硬件连接
如图,这是八个八段共阴数码管,意味着高电平点亮,数码管的段显通过74HC573连接到单片机P1口
74HC573是一个锁存器,当LE处于高电平的时候,输入和输出的信号是同步的,用在数码管主要用来增大驱动能力。
数码管的位显通过138译码器连接到单片机的P0口
138译码器通过3位的输入控制8位输出
代码编写
首先让数码管可以动态刷新显示
只要让对应段显点亮就可以了
下面是通过数码管的数据手册写出来的真值表,为了方便后面的显示,这里使用宏定义的方式定义真值表。
#define MAXWEI 8 //这里定义的是数码管的个数
#define E0 0x3f
#define E1 0x06
#define E2 0x5b
#define E3 0x4f
#define E4 0x66
#define E5 0x6d
#define E6 0x7d
#define E7 0x07
#define E8 0x7f
#define E9 0x6f
#define EE 0x00 //什么都不显示
定义一个数组用于存放要显示的数字
unsigned char Num[] = {
E0,E1,E2,E3,E4,E5,E6,E7,E8,E9,
EE,EE,EE,EE,EE,EE,EE,EE,EE,EE
};
在main函数里面刷新显示
void main()
{
unsigned char i = 0;
while(1)
{
for(i=0;i<MAXWEI;i++)
{
P0 = i;
P1=Num[i];
}
}
}
实际显示效果并不好
这是因为显示刷新太快,数码管有残影导致的,为了解决这个问题,可以通过添加延时函数解决
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 2;
j = 190;
do
{
while (--j);
} while (--i);
}
void delay(unsigned int ms)
{
while(ms)
{
ms--;
Delay1ms();
}
}
在主函数显示部分添加延时函数
void main()
{
unsigned char i = 0;
while(1)
{
for(i=0;i<MAXWEI;i++)
{
delay(1);
P0 = i;
P1=Num[i];
}
}
}
显示效果有明显改进
接下来添加一些代码可以让它滚动显示
为了让代码滚动显示,只要在每次刷新完一次将显示的起使位置向后移一位,并在达到最后一个数码管后重新将显示起使位置切换到第一个。
开启一个定时器,在中断函数中将标志位后移。定时器最大只能开启50ms中断,所以添加标志位延长时间。
添加两个标志位,一个用于后移显示,另一个用于时间标志位
unsigned char j = 0;//后移显示
unsigned int a = 0;//时间标志
定时器初始化
void Timer0Init(void) //500微秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
}
定时器中断函数
void tm0_isr() interrupt 1
{
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
TF0 = 0; //清除TF0标志
a++;
if(a==150)
{
j++;
if(j==20)
{
j=0;
}
a=0;
}
}
在主函数中初始化定时器、开启中断,并使用后移标志。
void main()
{
unsigned char i = 0;
EA = 1;
Timer0Init();
while(1)
{
for(i=0;i<MAXWEI;i++)
{
delay(1);
P0 = i;
P1=Num[i+j];
}
}
}
并更改显示内容,适配滚动显示
unsigned char Num[] = {
EE,EE,EE,EE,EE,EE,EE,EE,EE,
E0,E1,E2,E3,E4,E5,E6,E7,E8,E9,
EE,EE,EE,EE,EE,EE,EE,EE,EE,EE
};
额外的说明
滚动显示本质上还是八个数字逐个刷新,所以定义显示内容的数组里面存放了一些不显示的真值,这也是为什么数组长度是29而中断中让标志位等于20后就归零了。