动态显示的原理
根据上一篇文章数码管的静态显示,我们已经知道如何精准控制某一个数码管显示某一个数字。
如果我们要前三个数码管显示1、2、3,只不过是运用静态显示的方法,精准控制第一个数码管显示了1,然后马上,在非常短的时间内(单片机处理速度很快),精准控制第二个数码管显示2,又马上精准控制第三个数码管显示3,不断循环。
因为人眼识别不了这么快运动的图像,看上去就好像1、2、3一起显示了。
以下是一个有问题的程序
#include <reg52.h>
sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选
void main()
{
while(1)
{
/*这里是循环头,循环尾的P0=0x5b跑到这里来了*************************************************/
WE = 1; //打开位选
/*打开位选的一瞬间*************************************************************************/
/*P0 = 0x5b;跑进来了***********************************************************************/
P0 = 0XFE; //选择第一个数码管
WE = 0; //锁住位选数据
DU = 1; //打开段选
P0 = 0x06; //显示1
DU = 0; //锁住段选数据
WE = 1; //打开位选
P0 = 0XFD; //选择第二个数码管
WE = 0; //锁住位选数据
DU = 1; //打开段选
P0 = 0x5b; //显示2
DU = 0; //锁住段选数据
/*执行到这里,P0=0x5b,然后回到循环头********************************************************/
}
}
以下是正确的程序
#include <reg52.h>
sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选
void delay(unsigned int z)
{
unsigned int x, y;
for(x = z; x > 0; x--)
for(y = 114; y >0; y--);
}
void main()
{
while(1)
{
P0 = 0xff; //1111 1111不选择任何一个数码管
WE = 1; //打开位选
P0 = 0XFE; //1111 1110选择第一个数码管
WE = 0; //锁住位选数据
DU = 1; //打开段选
P0 = 0x06; //显示1
DU = 0; //锁住段选数据
delay(5); //别切换太快了
P0 = 0xff; //1111 1111不选择任何一个数码管
WE = 1; //打开位选
P0 = 0XFD; //1111 1101选择第二个数码管
WE = 0; //锁住位选数据
DU = 1; //打开段选
P0 = 0x5b; //显示2
DU = 0; //锁住段选数据
delay(5); //别切换太快了
}
}
写一个显示三位数的函数
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选
uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f} ; //code表示存在code区,数据不能被修改
void delay(unsigned int z)
{
unsigned int x, y;
for(x = z; x > 0; x--)
for(y = 114; y >0; y--);
}
void display(uchar i)
{
uchar bai, shi, ge;
bai = i / 100;
shi = i / 10 % 10;
ge = i % 10;
/*******************************************************/
P0 = 0xff; //清除断码
WE = 1; //打开位选
P0 = 0XFE; //1111 1110选择第一个数码管
WE = 0; //锁住位选数据
DU = 1; //打开段选
P0 = table[bai]; //显示百位
DU = 0; //锁住段选数据
delay(5);
/*******************************************************/
P0 = 0xff; //清除断码
WE = 1; //打开位选
P0 = 0XFD; //1111 1101选择第二个数码管
WE = 0; //锁住位选数据
DU = 1; //打开段选
P0 = table[shi]; //显示十位
DU = 0; //锁住段选数据
delay(5);
/*******************************************************/
P0 = 0xff; //清除断码
WE = 1; //打开位选
P0 = 0XFB; //1111 1011选择第三个数码管
WE = 0; //锁住位选数据
DU = 1; //打开段选
P0 = table[ge]; //显示个位
DU = 0; //锁住段选数据
delay(5);
}
void main()
{
display(236);
}