目录
1、什么是 静态显示和动态显示?
①静态显示:COM1~4都是由P0控制,例如:P0给8,则COM1~4都是显示8;
如果要显示2018: COM1~4由P0~3控制,P0给2,P1给0,P2给1,P3给8。(浪费 资源)
②动态显示:实质是轮流点亮单个数码管实现多位数码管整体显示的效果。
轮流显示过程中,每位数码管点亮时间为1~2ms,由于人的视觉暂留现象及发光二极 管的余辉效应,尽管各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印 象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的, 节省大量I/O端口,功耗更低。
2、数码管的动态显示
训练:实现数码管的动态显示,在8位数码管中,前4位显示年份“2018”,接着2位是分隔符 “-”,最后2位是月份;从一月份开始,每隔一段时间加1个月,到12月之后又从1月开始递增,如此往复。
代码:
#include "reg52.h"
sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;
unsigned char yue = 1;
unsigned char code SMG_duanma[18] = {
// 0 1 2 3 4 5 6 7
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
// 8 9 A B C D E F
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
// - .
0xbf,0x7f}; //共阳数码管
void DelaySMG(unsigned int t)
{
while(t--);
}
void InitHC138(unsigned char n)//选Y
{
switch(n)
{
case 4://8路LED
HC138_C = 1;
HC138_B = 0;
HC138_A = 0;
break;
case 5://蜂鸣器与继电器
HC138_C = 1;
HC138_B = 0;
HC138_A = 1;
break;
case 6://数码管位置
HC138_C = 1;
HC138_B = 1;
HC138_A = 0;
break;
case 7://数码管段码
HC138_C = 1;
HC138_B = 1;
HC138_A = 1;
break;
}
}
void InitSystem()//初始化系统(关闭蜂鸣器与继电器)
{
InitHC138(5);
P0 = 0x00;
}
void SMG_Bit(unsigned pos, unsigned char dat)//数码管位置、数据
{
InitHC138(6);
P0 = 0x01 << pos;
InitHC138(7);
P0 = dat;
}
void Dynamic_SMG()
{
//前4位显示年份“2018”
SMG_Bit(0, SMG_duanma[2]);
DelaySMG(500);
SMG_Bit(1, SMG_duanma[0]);
DelaySMG(500);
SMG_Bit(2, SMG_duanma[1]);
DelaySMG(500);
SMG_Bit(3, SMG_duanma[8]);
DelaySMG(500);
//2位分隔符“-”
SMG_Bit(4, SMG_duanma[16]);
DelaySMG(500);
SMG_Bit(5, SMG_duanma[16]);
DelaySMG(500);
//最后2位月份,月份递增1~12,循环往复
SMG_Bit(6, SMG_duanma[yue/10]);
DelaySMG(500);
SMG_Bit(7, SMG_duanma[yue%10]);
DelaySMG(500);
}
void Delay(unsigned char t)//每隔一段时间加1个月
{
while(t--)
{
Dynamic_SMG();//在等待月份+的同时,要动态扫描数码管(否则数码管暂停在这里)
}
}
void main()
{
InitSystem();
while(1)
{
Dynamic_SMG();
yue++;
if (yue > 12)
{
yue = 1;
}
Delay(100);//这里没有延时月份不递增,会出现重影等?//每隔一段时间加1个月
}
}