思路:
用四段数码管显示一个四位数。
1、把要显示的数字的每一位都分开,用一个数组val[4]存起来,如val[0] = 千位, val[1] = 百位,
val[2] =十位, val[3] = 个位。
2、段选和位选通过查表的方式。将每位数字通过循环的方式输出。
3、原理是人眼的视觉暂留,所以需要确定扫描的时间间隔,时间间隔用延时函数delay()。这个延时函数时间过长,数码管看起来就是全亮。如果时间太短,会出现闪烁,合适的时间自己去试。
4、在点亮每位数码管之间需要延时同时还需要消隐。例如P0 = 0xff 或者是P0=0x00,具体取决于共阴还是共阳。
电路:
四位数码管,段选接P0口,位选分别接P34~P37连续接
例程:
#include
typedef unsigned char uchar;
typedef unsigned int uint;
//段选,用查表的方式
uchar code SegSelect[] =
{~0x3f,~0x06,~0x5b,~0x4f,~0x66,~0x6d,~0x7d,~0x07,~0x7f,~0x6f,~0x40};//共阳
//uchar code SegSelect[] =
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴
uint g_num = 0;
uchar g_count = 0;
sbit wei0 = P3^4;
sbit wei1 = P3^5;
sbit wei2 = P3^6;
sbit wei3 = P3^7;
void display(uint num);
void delay(unsigned int i)
{
char
j;
for(i; i
> 0; i--)
for(j = 200; j > 0; j--) ;
}
//位选的函数
//只用四位数码管,也可以用查表的方式
//也可以不用查表的方式,直接每个引脚输出,switch...case...
void bitSel(uchar i)
{
switch(i)
{
case 0 :
wei0 = 0;
wei1 = 1; wei2 = 1; wei3 = 1;
break;
case 1 :
wei0 = 1;
wei1 = 0; wei2 = 1; wei3 = 1;
break;
case 2 :
wei0 = 1;
wei1 = 1; wei2 = 0; wei3 = 1;
break;
case 3 :
wei0 = 1;
wei1 = 1; wei2 = 1; wei3 = 0;
break;
default:
break;
}
return;
}
//数码管显示函数
void display(uint num)
{
uchar i = 0;
uchar val[4] ={0,0,0,0};
val[0] = num % 10000/ 1000;
val[1] = num % 1000 /100;
val[2] = num % 100 / 10;
val[3] = num % 10;
for(i = 0; i < 4; ++i)
{
//P2 &=
BitSelect[i];//对寄存器的操作尽量用 与或非 这些逻辑操作, 而不要用直接的 = 。
bitSel(i);
P1 = SegSelect[val[i]];
//或1与0的效果是一样的,都不会改变寄存器的值。
delay(150);//如果没有延时或延时时间太短,扫描的速度将会非常快,人眼根本看不清,如果延时时间太长,扫描效果太差,会出现闪烁
P1 = 0xff; //消隐
}
//bitSel(i);
}
//初始化定时器0产生1s的时钟
void initT0()
{
TMOD |= 0X01; //定时器0工作在工作方式1
TH0 =-50000 /
256;//赋初值
TL0 =-50000 %
256;TR0 =
1;//启动定时器0
ET0 =
1;//打开定时器中断
EA =
1;//打开总中断
}
void main(void)
{
initT0();//初始化定时器产生1s的时间
while(1)
{
display(g_num);
}}
//定时器的中断
void timer0Isr() interrupt 1
{
TH0 =-50000 /
256;//赋初值
TL0 =-50000 % 256;
g_count++;
//display(g_num);
if(g_count > 19)
{
g_count = 0;
g_num++;
if(g_num == 9999)
g_num =
0;
}}
数码管动态显示的改进:
方案一:
用138译码器去控制位选,可以有效节省IO口资源,用573锁存器去锁存段选码。
方案二:
用两片573接同样的8个IO口,只是通过选通573来输入段选码还是位选码。
用573锁存位选和段选可以让数码管常亮,防止扫描时间过长带来的闪烁问题。