电路图如下:
MCU采用89C52单片机,晶振12MHZ。
1、没有消除抖动的原始代码:
- #include <REGX52.H>
- #include <intrins.h>
- sbit KeyValue=P3^7;
- unsigned char code segment[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- //定义数码管显示0~9
- void main(){
- static char count=1;
- P2=segment[0]; //开始运行显示0
- while(1){
- if(KeyValue==0){
- P2=segment[count];
- count++;
- if(count>=10){ //超过0~9,数码管显示回到0
- count=0;
- }
- }
- }
- }
复制代码 2、延时消除抖动
存在如下缺点: - delay()延时函数会占用大量时间;
- 需要while循环不断的扫描按键,对单片机运算资源的浪费。
- #include <REGX52.H>
- #include <intrins.h>
- sbit KeyValue=P3^7;
- unsigned char code segment[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- void delay(){ //延时程序
- unsigned int i=20500;
- while(i--);
- }
- void main(){
- static char count=1;
- P2=segment[0];
- while(1){
- if(KeyValue==0){//按键按下
- delay();//延时一段时间
- if(KeyValue==0){//重新判断按键状态
- P2=segment[count];
- count++;
- if(count>=10){
- count=0;
- }
- }
- }
- }
- }
复制代码
3、使用定时器消抖
原理说明:1次按下+1次抬起构成一个按键动作,当同时检测到这两个动作时,才完成一次按键操作。按下时,将按键值存储为0;抬起时,将按键值存储为1。在前一次的按键值为0的前提下,检测当前按键值是否为1,如果为1,表示此次按键有效,否则此次按键无效。
缺点:会占用一个定时
- #include <REGX52.H>
- #include <intrins.h>
- sbit KeyValue=P3^7;
- bit KeyStatus=1;
- unsigned char code segment[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- void main(){
- bit KeySave=1;
- unsigned char count=0;
- P2=segment[0];
- /**************开启中断**************************/
- EA=1;
- TMOD=0x01;
- TH0=0xF8;
- TL0=0xCD;
- ET0=1;
- TR0=1;
- while(1){
- if(KeyStatus!=KeySave){//检测按键值是否改变,初始时按键值为1,在此检测按键值是否变为0,为0则继续
- if(KeySave==0){//如果前一次的按键值为0,说明本次按键抬起,本次按键有效;否则为按键按下操作,跳转到最后一步,将按键值取反
- count++;//对按键值+1
- if (count>=10){
- count=0;
- }
- P2=segment[count];
- }
- KeySave=~KeySave;
- }
- }
- }
- void InterruptTimer0() interrupt 1 {
- static unsigned KeyBuff=0xff;
- TH0=0xF8;
- TL0=0xCD;
- KeyBuff=(KeyBuff<<1)|KeyValue;
- switch(KeyBuff){
- case 0xff:
- KeyStatus=1;
- break;
- case 0x00:
- KeyStatus=0;
- break;
- default:
- break;
- }
- }
复制代码
|