1、给出数码管的原理图
在上一篇文章中我们已经给出了数码管显示数组的列取方法,可根据该图辅助我们这次的理解。需要注意的是我的数码管是有4个片选的,所以可以显示的最大数值是9999,下面的代码例程也是最高显示到9999的。
现在我们给出可以显示从1-9999计时的代码例程:
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char //define 后方无分号;
uchar code PX[]={0XFE,0XFD,0XFB,0XF7};//片选
uchar code DX[]=
{
0XC0,0XF9,0XA4,0XB0,
0X99,0X92,0X82,0XF8,
0X80,0X90,0X88,0X83,
0XC6,0XA1,0X86,0X8E
}; //段选
void delay_1ms(uint n)//1ms的延迟函数
{
uint i,j;
for(i=n;i>0;i--)
{
for(j=400;j>0;j--);//调整1ms,400与单片机的固有频率有关
}
}
void display_1()
{
uint i,j,k,n,m,l,q;
n = 50;//表示帧 1000/n
m = 1000; //内容切换时间,1000表示1s
for(i=0;i<10000;i++)
{
if(i>=0&&i<=9)
{
P2 = PX[0];
P0 = DX[i];
delay_1ms(m);
}
else if(i>=10&&i<=99)
{
for(j=0;j<(m/n);j++)
{
for(k=0;k<2;k++)
{
P2 = PX[k];
switch(k)
{
case 0:P0 = DX[i%10]; break; //显示个位
case 1:P0 = DX[i/10]; break; //显示十位
}
delay_1ms(n/2);
}
}
}
else if(i>=100&&i<=999)
{
for(j=0;j<(m/n);j++)
{
for(k=0;k<3;k++)
{
P2 = PX[k];
switch(k)
{
case 0:P0 = DX[i%10]; break; //显示个位
case 1:P0 = DX[(i/10)%10]; break; //显示十位
case 2:P0 = DX [i/100]; break; //显示百位
}
delay_1ms(n/3);
}
}
}
else if(i>=1000&&i<=9999)
{
for(j=0;j<(m/n);j++)
{
for(k=0;k<4;k++)
{
P2 = PX[k];
switch(k)
{
case 0:P0 = DX[i%10]; break; //显示个位
case 1:P0 = DX[(i/10)%10]; break; //显示十位
case 2:P0 = DX [(i/100)%10]; break; //显示百位
case 3:P0 = DX[(i/1000)]; break;
}
delay_1ms(n/4);
}
}
}
}
}
void main()
{
while(1)
{
display_1();
}
}
for循环延时时间不好确定,尤其是在带流水线的单片机里,这么长的延时建议用定时器,较短的延时,可以先取个参考值,在STC的库函数里可以找到一些常用参考值,然后细调,但这个很容易受到其它指令影响,不可用于对时序要求严格的场合。