//程序二:解决按键控制数码管带来闪灭显示问题的程序
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit add=P3^0;
sbit dec=P3^4;
uchar count;//定时器中断次数变量
uchar time;//按键定时器延时变量
uchar lingweiflag;//显示0标志位变量
uchar code weima[]={0xfe,0xfd,0xfb,0xf7};//数码管位码表
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共阴数码管段码数字0~9字码表,高电平点亮数码管段码数字0~9。
uint num;//数值变量
uint qian,bai,shi,ge;//定义拆字变量
/**ms级延时子程序**/
// void delay(uint x)
//{
// uint i,j;
// for(i=0;i<x;i++)
// for(j=0;j<110;j++);
// }
/**定时器ms级延时子程序**/
void time0_delay(uchar time)//注意这里不是普通延时,而是定时器延时函数。
{
count = 0;//需要定时器延时count,先清零,再循环检测是否计到count,是则退出。
while(1)
{
if(count>=time)
{
break;
}
}
}
// void display()
//{
// qian=num/1000;//转速/10000的余数/1000得到千位
// bai=num%1000/100;//取得百位
// shi=num%100/10;//取得十位数字
// ge=num%10;//取得个位数字
//
// P2=0xfe;//数码管千位显示位
// P1=table[qian];//数码管千位数值显示
// delay(2);//延时
//
// P2=0xfd;//数码管百位显示位
// P1=table[bai];//数码管百位数值显示
// delay(2);//延时
//
// P2=0xfb;//数码管十位显示位
// P1=table[shi];//数码管十位数值显示
// delay(2);//延时
//
// P2=0xf7;//数码管个位显示位
// P1=table[ge];//数码管个位数值显示
// delay(2);//延时
// }
void display()//显示程序
{
static uchar i;
P1=0x00;
P2=0xff;
switch(i)
{
case 0:
P2=weima[i];
P1=table[num/1000];
i++;
break;
case 1:
P2=weima[i];
P1=table[num%1000/100];
i++;
break;
case 2:
P2=weima[i];
P1=table[num%100/10];
i++;
break;
case 3:
P2=weima[i];
P1=table[num%10];
i++;
break;
default : break;//自定义
}
if(i>3)
i=0;
}
void keyscan()
{
// if(add==0)
// {
// delay(5);
// if(add==0)
// {
// num++;
// while(!add);
// lingweiflag=0;
// }
// }
if(add==0)
{
time0_delay(20);//注意这里不是普通延时,而是定时器延时函数。
if(add==0)
{
time0_delay(20);//注意这里不是普通延时,而是定时器延时函数。
while(!add);
num++;
lingweiflag=0;
}
}
// if(dec==0&&lingweiflag==0)
// {
// delay(5);
// if(dec==0)
// {
// num--;
// while(!dec);
// }
// }
if(dec==0&&lingweiflag==0)
{
time0_delay(20);//注意这里不是普通延时,而是定时器延时函数。
if(dec==0)
{
time0_delay(20);//注意这里不是普通延时,而是定时器延时函数。
while(!dec);
num--;
}
}
if(num>9999)
{
num=0;
}
if(num==0)
{
num=0;
lingweiflag=1;
}
}
void Time0_init()
{
TMOD=0x01;
TH0=(65536-2000)/256;//为什么取定时器中断时间为2000微妙,即2毫秒,亦0.002秒,则频率为1/0.002S=500Hz?由于人眼能看到数码管闪烁是源于人眼能识别高频率(人眼看不到闪烁的频率为50Hz)低于50Hz,即1/50Hz=0.02秒,因此要想让人眼看不到数码管闪烁,数管显示函数的显示频率至少是50Hz,即1/50Hz=0.02秒,也不是越高越好,还要结合按键扫描函数的按键延时来取出最恰当的显示频率。
TL0=(65536-2000)%256;
EA=1;
ET0=1;
TR0=1;
}
void time0() interrupt 1
{
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
count++;
display();
}
void main()
{
Time0_init();
while(1)
{
keyscan();
}
}
|