给你改写了,只用两个键,一个用于设置选项,一个多功能键。用外部中断计数。仿真正常,你自己完善其它硬件。
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit K1=P2^4;
- sbit K2=P2^5;
- sbit OUT=P2^6;
- sbit buzzer=P2^7;
- uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳LED段码表
- uchar displayData[4];//显示数据缓存
- uchar qian,bai,shi,ge;
- uchar Cnt5ms;
- uchar KeySec=0;
- uint num;
- int count;
- bit flashing=0;//闪烁标志
- void Timer0Init(void) //5毫秒@12.000MHz
- {
- TMOD |= 0x01; //设置定时器模式
- TL0 = 0x78; //设置定时初始值
- TH0 = 0xEC; //设置定时初始值
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- }
- //按键扫描
- void keyscan()
- {
- static unsigned int time=0;
- static bit sign=0;
- if(!K1||!K2)
- {
- if(++time>=15 && sign==0)//短按消抖
- {
- sign=1;
- if(!K1)
- {
- KeySec++;
- if(KeySec>=5)
- {
- KeySec=0;
- count=0;
- }
- }
- if(!K2 && KeySec==0)
- {
- if(count!=num)
- {
- EA = ~EA;//暂停/继续
- OUT=EA;
- }
- else
- {
- count=0;
- EA = 1; //开始
- OUT= 1;
- buzzer=1;//蜂鸣器复位
- }
- }
- if(!K2 && KeySec!=0)
- {
- if(KeySec)
- {
- switch(KeySec)
- {
- case 1: qian= ++qian%10; break;
- case 2: bai = ++bai%10; break;
- case 3: shi = ++shi%10; break;
- case 4: ge = ++ge%10; break;
- }
- num=(qian*1000)+(bai*100)+(shi*10)+ge;
- // num写入EEPROM保存,下次上电直接调用
- }
- }
- }
- }
- else
- {
- time=0;
- sign=0;
- }
- }
- void display()//显示
- {
- static uchar i=0;
- if(KeySec==0)
- {//显示计数值
- displayData[0] = tab[count/1000%10];
- displayData[1] = tab[count/100%10];
- displayData[2] = tab[count/10%10];
- displayData[3] = tab[count%10];
- }
- if(KeySec!=0)
- {//显示设定值
- displayData[0] = tab[num/1000%10];
- displayData[1] = tab[num/100%10];
- displayData[2] = tab[num/10%10];
- displayData[3] = tab[num%10];
- }
- P2&=0xf0;//消隐
- if(KeySec==1 && i==0 && flashing==0)
- P0=0xff;//千位闪烁
- else if(KeySec==2 && i==1 && flashing==0)
- P0=0xff;//百位闪烁
- else if(KeySec==3 && i==2 && flashing==0)
- P0=0xff;//十位闪烁
- else if(KeySec==4 && i==3 && flashing==0)
- P0=0xff;//个位闪烁
- else
- P0=displayData[i];
- P2|=0x01<<i;
- i++;i%=4;
- }
- void main()//主函数
- {
- OUT=0;
- Timer0Init();//初始化定时器
- // num=读取EEPROM
- IT0 = 1;// 外部下降沿中断
- EX0 = 1;
- // EA = 1;
- while(1)
- {
- if(TF0)//查询定时器中断请求位
- {
- TF0=0;
- TL0 = 0x78; //设置定时初始值
- TH0 = 0xEC; //设置定时初始值
- Cnt5ms++;
- if(Cnt5ms==40)
- {
- Cnt5ms=0;
- flashing=~flashing;
- }
- keyscan(); //按键扫描
- display(); //数码管显示
- }
- }
- }
- void exint0() interrupt 0
- {
- count++;
- if(count>=num)
- {
- buzzer=0;
- EA = 0;
- OUT= 0;
- }
- }
复制代码
|