实验内容:实现数码管的动态显示,在8位数码管中,前面4位显示年份“2018”,接着2位是分隔符“-”,最后两位是月份,从1月份开始,每隔一段时间加1个月,到12月之后又从1月开始递增,如此往复。
训练重点:
1、根据动态显示原理,实现数码管各位显示不同的数据内容。
2、编程实现将数据的个位和十位分别显示到数码管上,进而拓展到三位整数、四位整数,甚至浮点数的数码管显示。
3、数据动态变化的程序设计思路与数码显示的编程模式。
1、动态显示思路
动态显示实质上就是轮流点亮单个数码管实现多位数码管整体显示的效果。 在轮流显示过程中,每位数码管点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。
对于一组4位数码管来说,静态显示和动态显示都能实现同样的效果,但需要的I/O端口是不同的。
静态显示需要I/O端口:8个段码*4 + 4个COM端 = 36个I/O引脚
动态显示需要I/O端口:8个段码 + 4个COM端 = 12个I/O引脚
2、部分函数代码
一、延时函数
void Delay(unsigned char t)
{
while(t--)
{
Smg_Proc();
}
}
注意在延时函数中里面要一直执行数码管显示函数。
二、数码管位显示函数
//数码管显示内容与位置的函数
void SMG_Show_Bit(unsigned char dat,unsigned char pos)
{
HC138_state(6); //数码管的位置
P0 = 0x01 << pos;
HC138_state(7); //数码管的内容
P0 = dat;
}
例如:SMG_Show_Bit(SMG_duanma[0],1); //第1位显示‘0’
三、关于月份
month/10是十位,余数是个位。
// SMG_Show_Bit(SMG_duanma[month/10],6); //第6、7位显示月
// Delay1ms();
// SMG_Show_Bit(SMG_duanma[month%10],7);
// Delay1ms();
void month_add()
{
month++;
if(month >12)
month = 1;
Delay(100);
}
3、代码展示
/***************************************************************
实验现象:实现数码管的动态显示,在8位数码管中,前面4位显示年份
“2023”,接着2位是分隔符“-”,最后两位是月份,从1月份开始,每隔
一段时间加1个月,到12月之后又从1月开始递增,如此往复。
***************************************************************/
#include "reg52.h"
#include "intrins.h"
unsigned char month = 1; //month/10=十位;余数是个位
//1-9;A-F;-;.
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 HC138_state(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 Delay250ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 11;
j = 130;
k = 111;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
//初始化关外设
void InitSystem()
{
HC138_state(5);
P0=0x00; //蜂鸣器,继电器都关闭
}
//数码管显示内容与位置的函数
void SMG_Show_Bit(unsigned char dat,unsigned char pos)
{
HC138_state(6); //数码管的位置
P0 = 0x01 << pos;
HC138_state(7); //数码管的内容
P0 = dat;
}
void Smg_Proc()
{
unsigned char i,j;
SMG_Show_Bit(SMG_duanma[2],0); //第0位显示‘2’
Delay1ms();
SMG_Show_Bit(SMG_duanma[0],1); //第1位显示‘0’
Delay1ms();
SMG_Show_Bit(SMG_duanma[2],2); //第2位显示‘2’
Delay1ms();
SMG_Show_Bit(SMG_duanma[3],3); //第3位显示‘3’
Delay1ms();
SMG_Show_Bit(SMG_duanma[16],4); //第4位显示‘-’
Delay1ms();
SMG_Show_Bit(SMG_duanma[16],5); //第5位显示‘-’
Delay1ms();
SMG_Show_Bit(SMG_duanma[month/10],6); //第6、7位显示月
Delay1ms();
SMG_Show_Bit(SMG_duanma[month%10],7);
Delay1ms();
}
void Delay(unsigned char t)
{
while(t--)
{
Smg_Proc();
}
}
void month_add()
{
month++;
if(month >12)
month = 1;
Delay(100);
}
void main()
{
InitSystem();
while(1)
{
Smg_Proc();
month_add();
}
}