本帖最后由 51黑电子会员 于 2020-5-22 08:40 编辑
- //按键短按加或减,长按连加或连减,四位一体数码管显示0~9999。
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define key_short 10//宏定义短按20ms
- #define key_long 50//宏定义长按100ms
- #define key_middle 40//宏定义长按间隔80ms
- sbit led=P1^4;//启停指示灯
- sbit addkey=P3^0;//位定义加键
- sbit deckey=P3^2;//位定义减键
- sbit qiting=P3^4;//位定义启动按键端口
- sbit tingzhi=P3^6;//位定义停止按键端口
- //uchar i;//数码管位数变量
- uchar flag;//显示函数标志位变量
- uchar qitingnum;//声明启停次数变量
- uint num;//数值变量
- uint addcount,deccount;//计数变量
- uint qian,bai,shi,ge;//定义拆字变量
- //uchar code weima[]={0xfe,0xfd,0xfb,0xf7};//数码管位码表
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共阴数码管段码数字0~9字码表,高电平点亮数码管段码数字0~9。
- /**ms级延时子程序**/
- void delay(uint x)
- {
- uint i,j;
- for(i=0;i<x;i++)
- for(j=0;j<110;j++);
- }
- void display()
- {
- qian=num/1000;//取得千位数字
- bai=num%1000/100;//取得百位数字
- shi=num%100/10;//取得十位数字
- ge=num%10;//取得个位数字
- P2=0xfe;//数码管千位显示位
- P0=table[qian];//数码管千位数值显示
- delay(2);//延时
- P2=0xfd;//数码管百位显示位
- P0=table[bai];//数码管百位数值显示
- delay(2);//延时
- P2=0xfb;//数码管十位显示位
- P0=table[shi];//数码管十位数值显示
- delay(2);//延时
- P2=0xf7;//数码管个位显示位
- P0=table[ge];//数码管个位数值显示
- delay(2);//延时
- }
- void qidongkeyscan()//启动函数
- {
- if(qiting==0)
- {
- delay(15);
- if(qiting==0)
- {
- qitingnum++;
- TR0=1;
- flag=0;
- while(qiting==1);
- }
- }
- }
- void tingzhikeyscan()//关掉函数
- {
- if(tingzhi==0)
- {
- delay(15);
- if(tingzhi==0)
- {
- led=1;
- flag=1;
- TR0=0;
- P2=0xff;
- P0=0x00;
- qitingnum=0;
- while(tingzhi==1);
- }
- }
- }
- void keyscan()//设置函数
- {
- if(qitingnum==1)
- {
- led=0;
- if(!addkey)
- {
- addcount++;
- // delay(10);
- if(addcount>=key_long)//增加长按
- {
- if(num<9999)
- num++;
- addcount=key_middle;//为什么存在addcount=key_middle,由于一直按着按键,addcount计数会溢出,设定addcount=key_middle能让addcount在这个addcount=key_middle基础上反复累积计数,从而不会出现计数溢出的情况。
- }
- }
- else
- {
- if(key_short<addcount&&addcount<key_long)//增加短按,为什么不可以是key_short<addcount<key_long,假若是key_short<addcount<key_long,就相当于按键还没按下,条件已经满足,按键再按下去就没意义啦。
- {
- if(num<9999)
- num++;
- }
- addcount=0;
- }
- if(!deckey)
- {
- deccount++;
- // delay(10);
- if(deccount>=key_long)//减少长按
- {
- if(num>0)
- num--;
- deccount=key_middle;//为什么存在deccount=key_middle,由于一直按着按键,deccount计数会溢出,设定deccount=key_middle能让addcount在这个deccount=key_middle基础上反复累积计数,从而不会出现计数溢出的情况。
- }
- }
- else
- {
- if(key_short<deccount&&deccount<key_long)//减少短按,为什么if条件不可以是key_short<deccount<key_long,假若是key_short<deccount<key_long,就相当于按键还没按下,条件已经满足,按键再按下去就没意义啦。
- {
- if(num>0)
- num--;
- }
- deccount=0;
- }
- }
- }
- // void display()//显示程序
- //{
- //// static uchar i;
- // P0=0x00;
- // P2=weima[i];
- // switch(i)
- // {
- // case 0:
- // P0=table[num/1000];
- // break;
- // case 1:
- // P0=table[num%1000/100];
- // break;
- // case 2:
- // P0=table[num%100/10];
- // break;
- // case 3:
- // P0=table[num%10];
- // break;
- // }
- // i++;
- // i%=4;
- // }
- /**定时器0初始化子程序**/
- void Time0_init()
- {
- TMOD=0X01;//模式选定时器0、计数器1,工作方式选定时器0定时模式1、计数器1计数模式1。
- TH0=(65536-5000)/256;//定时器0高8位定时50毫秒
- TL0=(65536-5000)%256;//定时器0低8位定时50毫秒
- EA=1;//打开总中断
- ET0=1;//打开定时器0的中断
- TR0=0;//打开定时器0
- }
- void Timer0() interrupt 1//定时器0中断子程序
- {
- TH0=(65536-5000)/256;//重装定时器0高8位定时50毫秒
- TL0=(65536-5000)%256;//重装定时器0低8位定时50毫秒
- keyscan();//设置函数
- if(flag==0)
- display();//显示函数
- tingzhikeyscan();//关掉函数
- }
- void main()//主函数
- {
- Time0_init();//定时器0初始化子程序
- while(1)
- {
- qidongkeyscan();//启动函数
- }
- }
复制代码
|