前倾提到,我们已经学会共阳数码管的静态显示,但是很明显,动态显示会更加常用一点,那么,我们要如何实现相关功能呢?
我们便先来看看这道题目,这道题目就是很显然的动态显示数码管了。
数码管的不同数码管显示不同数字基本上有两种方法,一种是调用IO口去直接连接数码管,但是这样子会大量占用IO口,使得单片机的其他功能无法实现,所以我们可以利用单片机的时间可控性与物理上的一些关于光的性质来实现相关功能。
如上图所示,我们可以利用余晖效应来达成这个目的,相关理论知识请自行查询,总之,我们可以通过每一个数码管都显示的时间极短与快速的扫描来让数码管实现一个数码管显示一个特定的数字或字母或符号。
接下来有了新的问题,一个数码管显示一个数字我们是做到了,可是,我们如何让各个数字动起来显示出不同的状态呢?
那么,我们便需要用到一些小小的C语言知识了。
首先我们先定义一个符号yue,他代表我们的月份。
然后我们再写一段这样的代码
DisplaySMG(SMG[yue / 10],6);
DelaySMG(500);
DisplaySMG(SMG[yue % 10],7);
DelaySMG(500);
把他放在我们原先用于显示的函数里面,就能显示出yue所对应的数字了。
接下来,我们要让他动起来,众所周知,在C语言中想让数字在运行中变化便需要使用循环或者判断体,或者++,--了
yue++;
if(yue > 12)
{
yue = 0;
}
为了防止月份的显示超过13从而显示出一些字母,我们将yue给限制在0~12之间。
为了使效果更明显一点,我们可以再写一个延时函数,但是这个延时函数如果只是像之前一样,纯粹的while(t--)的话,会导致我们0~5号数码管的数字丢失。
为了解决这个问题,我们可以把显示函数也扔进第二个延时函数中,这样,前面6个数码管就能无时无刻的显示了。
void DelayABC(unsigned int t)
{
while(t--)
{
Display_active();
}
}
结合以上所有知识,我们便可以写出这样的代码:
#include <REGX52.H>
unsigned char code SMG[18] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
unsigned char yue = 0;
void SelectHC573(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 DisplaySMG(unsigned char value,unsigned char pos)
{
SelectHC573(6);
P0 = 0x01 << pos;
SelectHC573(7);
P0 = value;
}
void DelaySMG(unsigned int t)
{
while(t--);
}
void Display_active()
{
DisplaySMG(SMG[2],0);
DelaySMG(500);
DisplaySMG(SMG[0],1);
DelaySMG(500);
DisplaySMG(SMG[1],2);
DelaySMG(500);
DisplaySMG(SMG[8],3);
DelaySMG(500);
DisplaySMG(SMG[16],4);
DelaySMG(500);
DisplaySMG(SMG[16],5);
DelaySMG(500);
DisplaySMG(SMG[yue / 10],6);
DelaySMG(500);
DisplaySMG(SMG[yue % 10],7);
DelaySMG(500);
}
void DelayABC(unsigned int t)
{
while(t--)
{
Display_active();
}
}
void main()
{
while(1)
{
Display_active();
yue++;
if(yue > 12)
{
yue = 0;
}
DelayABC(300);
}
}
谢谢观看~~