目录
1.原理:
动态显示实质上就是轮流点亮单个数码管实现多位数码管整体显示的效果。在轮流显示过程中,每位数码管点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。
对于一组4位数码管来说,静态显示和动态显示都可实现同样的效果,但所需要的IO端口不同;静态显示需要IO端口:8个段码*4+4个公共端=36个IO引脚。动态显示需要IO端口:8个段码+4个公共端=12个IO引脚。
2.思路:以显示“2018--12”为例
前四位显示“2018”,后四位“--”与月份的变化
void DisPlay_Dynamic() //动态显示函数 '2018--12'
{
DisPlaySMG_Bit(SMG_duanma[2],0);
DelaySMG(500); //出现残影的话,是由于延时时间太长
DisPlaySMG_Bit(SMG_duanma[0],1);
DelaySMG(500);
DisPlaySMG_Bit(SMG_duanma[1],2);
DelaySMG(500);
DisPlaySMG_Bit(SMG_duanma[8],3);
DelaySMG(500);
DisPlaySMG_Bit(SMG_duanma[16],4);
DelaySMG(500); //出现残影的话,是由于延时时间太长
DisPlaySMG_Bit(SMG_duanma[16],5);
DelaySMG(500);
DisPlaySMG_Bit(SMG_duanma[month/10],6); //月份的十位
DelaySMG(500);
DisPlaySMG_Bit(SMG_duanma[month%10],7); //月份的个位
DelaySMG(500);
}
实现以上前提是锁存器的选通与静态数码管的显示:
void SelectHC573(unsigned char channel)
{
switch(channel)
{
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 DisPlaySMG_Bit(unsigned char value,unsigned char pos) //静态显示函数
{
SelectHC573(6);
P0 = 0x01 << pos; //选通各个com端
SelectHC573(7);
P0 = value;
}
3.全部代码的实现:
#include "reg52.h"
unsigned char month = 12;
unsigned char code SMG_duanma[18] = {0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,0x88,
0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
//函数声明
void SelectHC573();
void DisPlaySMG_Bit();
void DelaySMG();
void DisPlay_Dynamic();
void Delay();
void main();
void SelectHC573(unsigned char channel)
{
switch(channel)
{
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 DisPlaySMG_Bit(unsigned char value,unsigned char pos) //静态显示函数
{
SelectHC573(6);
P0 = 0x01 << pos; //选通各个com端
SelectHC573(7);
P0 = value;
}
void DelaySMG(unsigned int t)
{
while(t--);
}
void DisPlay_Dynamic() //动态显示函数 '2018--12'
{
DisPlaySMG_Bit(SMG_duanma[2],0);
DelaySMG(500); //出现残影的话,是由于延时时间太长
DisPlaySMG_Bit(SMG_duanma[0],1);
DelaySMG(500);
DisPlaySMG_Bit(SMG_duanma[1],2);
DelaySMG(500);
DisPlaySMG_Bit(SMG_duanma[8],3);
DelaySMG(500);
DisPlaySMG_Bit(SMG_duanma[16],4);
DelaySMG(500); //出现残影的话,是由于延时时间太长
DisPlaySMG_Bit(SMG_duanma[16],5);
DelaySMG(500);
DisPlaySMG_Bit(SMG_duanma[month/10],6); //月份的十位
DelaySMG(500);
DisPlaySMG_Bit(SMG_duanma[month%10],7); //月份的个位
DelaySMG(500);
}
void Delay(unsigned char t)
{
while(t--)
{
DisPlay_Dynamic(); //延时里也要执行动态显示的内容
}
}
void main()
{
while(1)
{
DisPlay_Dynamic();
month++;
if(month >12)
{
month = 1; //月份动态显示
}
Delay(200);
}
}