一,设计目标:
掌握蜂数码管静态显示后,可能我们对数码管有了自己的理解了,其实,接上回书最后(4.蓝桥杯大赛单片机系列—数码管静态显示)的一道练习,八个数码管依次亮的展示效果其实便是数码管动态显示的大致思路,只不过对于动态数码管来说由于八个数码切换速度太快,加上肉眼视觉残留现象,所以给人一种八个数码管全亮的感觉。
二,设计思路:
首先,关于数码管位码和段码的配置还需从基础讲起,这里就不赘述了,不太明白请移步祥参4.蓝桥杯大赛单片机系列—数码管静态显示,那么我们动态数码管则需要让位码切换得快一点,并且还需要特别注意由于位码的切换太快导致段码配置出现时序上的问题,以及切换太慢导致数码管出错,这样可能会出现全亮或者有亮有暗的现象(不均匀)。不过这里对初学者不做要求,可能到您去写往届比赛真题时会出现这种时序方面出现的问题(由于加了太多传感器可能会导致数码管显示问题)。这里还是先把之前的原理图回顾一下。
我们为了后续可以更好的使用数码管,建议给数码管写个配置位码和段码的函数方便调用。而且考虑到位码切换需要特定的速度还需给数码管写个延时函数。以及后续消影函数(关所有数码管)。
void Select573(unsigned int n)
{
switch(n)
{
case 0:
P2=(P2&0x1f)|0x00;break;
case 4:
P2=(P2&0x1f)|0x80;break;
case 5:
P2=(P2&0x1f)|0xa0;break;
case 6:
P2=(P2&0x1f)|0xc0;break;
case 7:
P2=(P2&0x1f)|0xe0;break;
}
}
void display_smg(unsigned char dat,unsigned char pos)
{
Select573(6);
P0=0x01<<pos; //位码 1亮0灭 末尾补0
Select573(7);
P0=dat; //段码
}
void delay_smg(unsigned int t) //延时
{
while(t--);
}
void smg_all() //消影 防止显示效果不佳
{
Select573(6);
P0=0xff; //选中所有数码管(位码)
Select573(7);
P0=0xff; //全灭
}
三,代码实现:
(1)八个数码管都动态显示1~8;
(没有消影,影响不大)
#include "reg52.h"
unsigned char y=1;
unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};
void Select573(unsigned char n)
{
switch(n)
{
case 4:
P2=(P2 & 0x1f)|0x80;break;
case 5:
P2=(P2 & 0x1f)|0xa0;break;
case 6:
P2=(P2 & 0x1f)|0xc0;break;
case 7:
P2=(P2 & 0x1f)|0xe0;break;
}
}
void display_smg(unsigned char dat,unsigned char pos)
{
Select573(6);
P0=0x01<<pos;
Select573(7);
P0=dat;
}
void delay_smg(unsigned int t)
{
while(t--);
}
void Display()
{
display_smg(SMG_duanma[1],0);
delay_smg(500);
display_smg(SMG_duanma[2],1);
delay_smg(500);
display_smg(SMG_duanma[3],2);
delay_smg(500);
display_smg(SMG_duanma[4],3);
delay_smg(500);
display_smg(SMG_duanma[5],4);
delay_smg(500);
display_smg(SMG_duanma[6],5);
delay_smg(500);
display_smg(SMG_duanma[7],6);
delay_smg(500);
display_smg(SMG_duanma[8],7);
delay_smg(500);
}
void main()
{
Select573(5);
P0 = 0x00;
Select573(4);
P0 = 0xff;
while(1)
{
Display();
}
}
(2)近似敲个秒表(12-50-20);
没开始学中断,用延时函数敲的(1s的时间不正确)
#include "reg52.h"
unsigned char y=1;
unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};
unsigned int s=20,m=50,h=12;
void Select573(unsigned char n)
{
switch(n)
{
case 4:
P2=(P2 & 0x1f)|0x80;break;
case 5:
P2=(P2 & 0x1f)|0xa0;break;
case 6:
P2=(P2 & 0x1f)|0xc0;break;
case 7:
P2=(P2 & 0x1f)|0xe0;break;
}
}
void display_smg(unsigned char dat,unsigned char pos)
{
Select573(6);
P0=0x01<<pos;
Select573(7);
P0=dat;
}
void delay_smg(unsigned int t)
{
while(t--);
}
void all()
{
Select573(6);
P0=0xff;
Select573(7);
P0=0xff;
}
void Display()
{
display_smg(SMG_duanma[h/10],0);
delay_smg(500);
display_smg(SMG_duanma[h%10],1);
delay_smg(500);
display_smg(SMG_duanma[16],2);
delay_smg(500);
display_smg(SMG_duanma[m/10],3);
delay_smg(500);
display_smg(SMG_duanma[m%10],4);
delay_smg(500);
display_smg(SMG_duanma[16],5);
delay_smg(500);
display_smg(SMG_duanma[s/10],6);
delay_smg(500);
display_smg(SMG_duanma[s%10],7);
delay_smg(500);
all();
}
void delay(unsigned int t)
{
while(t--)
{
Display(); //这里最好需要把数码管放到延时函数中,防止数码管显示不佳
}
}
void main()
{
Select573(5);
P0=0x00;
Select573(4);
P0=0xff;
while(1)
{
s++;
if(s==60)
{
s=0;
m++;
if(m==60)
{
h++;
m=0;
if(h==12) h=0;
}
}
Display();
delay(100);
}
}