/*功能:实现按键计数,4位数码管上显示计数值, 实验目的:按键稳定消抖,按键按下一次只执行一次操作,*/
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- typedef unsigned char uint8;
- #include<reg52.h>
- #include<intrins.h>
- typedef unsigned char uint8;
- typedef unsigned int uint16;
- typedef unsigned long uint32;
- sbit KEYGND=P3^4; //矩阵按键的一条列线,此程序将KEYGND=0,模拟出3个独立按键的到地
- sbit K1 = P3^5;
- sbit K2 = P3^6;
- sbit K3 = P3^7;
- sbit LED = P1^7;
- uint8 code seg[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; //0-9段码
- uint8 dis[4]={0,0,0,0};//位显缓存
- uint16 count=0,ms;
- void KeyScan(void) //这里的松手检测很好用,值得记住,在定时中断函数中每20ms调用一次KeyScan(),非常完美,基本不会不影响其程序运行,
- { //按下只产生一次操作
- static bit KeyOnOff = 0; //这里一定要定义为静态变量或者全局变量
- if(K1==0||K2==0||K3==0) // 判断是否有按键按下
- {
- if(KeyOnOff == 0) // 自锁变量
- {
- KeyOnOff = 1; // 屏蔽这句话,将没有松手检测,数字加的快
- if(K1==0) //按K1加数
- {
- count++;
- }
- if(K2==0) //按K2减数
- {
- count--;
- }
- if(K3==0) //按K3归零
- {
- count=0;
- }
- }
- }
- else
- {
- KeyOnOff = 0; // 当没有按键按下时 解锁
- }
- }
- /*********************毫秒延时函数************************************/
- void delay1ms(unsigned char n)
- {
- unsigned char a,b,c;
- for(c=n;c>0;c--)
- for(b=102;b>0;b--)
- for(a=3;a>0;a--);
- }
- /**************************数据处理和刷新显示函数*********************/
- void disp_count() //数码管显示函数
- {
- uint8 i=0;
- dis[0]=count%10; //计数器显示用刷新函数
- dis[1]=count/10%10; //计数器显示用刷新函数
- dis[2]=count/100%10; //计数器显示用刷新函数
- dis[3]=count/1000%10; //计数器显示用刷新函数
-
- if(dis[3]==0)
- {
- dis[3]=0x0a; //高位为零不显示,
- if(dis[2]==0)
- {
- dis[2]=0x0a; //高位为零不显示,
- if(dis[1]==0)
- {
- dis[1]=0x0a; //高位为零不显示,
- }
- }
- }
- for (i=0;i<4;i++)
- {
- switch(i)
- {
- case 0: P0=0Xff; P2=0xfe;break; //这里的P0=0XFF的目的是消除鬼影
- case 1: P0=0Xff; P2=0xfd;break; //这里的P0=0XFF的目的是消除鬼影
- case 2: P0=0Xff; P2=0xfb;break; //这里的P0=0XFF的目的是消除鬼影
- case 3: P0=0Xff; P2=0xf7;break; //这里的P0=0XFF的目的是消除鬼影
- }
- P0=seg[dis[i]];
- delay1ms(1);
- }
- }
- /*************定时器初始化函数*************/
- void InitTimer0(void)
- {
- TMOD = 0x01;
- TH0 = 0xfc; //TH0=0xfc,TL0=0x66组合是1毫秒的初值
- TL0 = 0x66; //
- EA = 1;
- ET0 = 1;
- TR0 = 1;
- }
- /*****************************************主函数*******************************/
- void main()
- {
- P0=0xff; //4位数码管段码
- P2=0xff; //4位数码管位码
- KEYGND=0;
- InitTimer0(); //定时器初始化函数
- while(1)
- {
- disp_count(); //数码管显示函数
- delay1ms(1);
- }
- }
- /************************************INT0定时中断函数****************************/
- void Timer0Interrupt(void) interrupt 1
- {
- TH0 = 0xfc;
- TL0 = 0x66;
- ms++;
- if(ms%20==0) //每20ms执行一次按键检测
- {
- KeyScan();
- }
-
- }
复制代码
|