这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 单片机消除按键抖动的三种方法及对比

共34条 1/4 1 2 3 4 跳转至

单片机消除按键抖动的三种方法及对比

工程师
2021-10-03 22:18:38     打赏

单片机消除按键抖动的三种方法及对比


1、没有消除抖动的原始代码:

  1. #include <REGX52.H>

  2. #include <intrins.h>

  3. sbit KeyValue=P3^7;

  4. unsigned char code segment[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

  5. //定义数码管显示0~9

  6. void main(){

  7.         static char count=1;

  8.         P2=segment[0]; //开始运行显示0

  9.         while(1){

  10.                 if(KeyValue==0){

  11.                         P2=segment[count];

  12.                         count++;

  13.                         if(count>=10){   //超过0~9,数码管显示回到0

  14.                                 count=0;

  15.                         }

  16.                 }

  17.         }

  18. }


2、延时消除抖动

存在如下缺点:

delay()延时函数会占用大量时间;

  1. #include <REGX52.H>

  2. #include <intrins.h>

  3. sbit KeyValue=P3^7;

  4. unsigned char code segment[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

  5. void delay(){ //延时程序

  6.         unsigned int i=20500;

  7.         while(i--);

  8. }

  9. void main(){

  10.         static char count=1;

  11.         P2=segment[0];

  12.         while(1){

  13.                 if(KeyValue==0){//按键按下

  14.                         delay();//延时一段时间

  15.                         if(KeyValue==0){//重新判断按键状态

  16.                                 P2=segment[count];

  17.                                 count++;

  18.                                 if(count>=10){

  19.                                 count=0;

  20.                                 }

  21.                         }

  22.                 }

  23.         }

  24. }


3、使用定时器消抖

原理说明:1次按下+1次抬起构成一个按键动作,当同时检测到这两个动作时,才完成一次按键操作。按下时,将按键值存储为0;抬起时,将按键值存储为1。在前一次的按键值为0的前提下,检测当前按键值是否为1,如果为1,表示此次按键有效,否则此次按键无效。

缺点:会占用一个定时

  1. #include <REGX52.H>

  2. #include <intrins.h>

  3. sbit KeyValue=P3^7;

  4. bit  KeyStatus=1;

  5. unsigned char code segment[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};


  6. void main(){

  7.         bit KeySave=1;

  8.         unsigned char count=0;

  9.         P2=segment[0];

  10.         /**************开启中断**************************/

  11.         EA=1;

  12.         TMOD=0x01;

  13.         TH0=0xF8;

  14.         TL0=0xCD;

  15.         ET0=1;

  16.         TR0=1;

  17.         while(1){

  18.                 if(KeyStatus!=KeySave){//检测按键值是否改变,初始时按键值为1,在此检测按键值是否变为0,为0则继续

  19.                         if(KeySave==0){//如果前一次的按键值为0,说明本次按键抬起,本次按键有效;否则为按键按下操作,跳转到最后一步,将按键值取反

  20.                                 count++;//对按键值+1

  21.                                 if (count>=10){

  22.                                         count=0;

  23.                                 }

  24.                                 P2=segment[count];

  25.                         }

  26.                         KeySave=~KeySave;

  27.                 }

  28.         }

  29. }

  30. void InterruptTimer0() interrupt 1 {

  31.         static unsigned KeyBuff=0xff;

  32.         TH0=0xF8;

  33.         TL0=0xCD;

  34.         KeyBuff=(KeyBuff<<1)|KeyValue;

  35.         switch(KeyBuff){

  36.           case 0xff:

  37.                         KeyStatus=1;

  38.                   break;

  39.           case 0x00:

  40.                         KeyStatus=0;

  41.                   break;

  42.           default:

  43.                   break;

  44.   }        

  45. }





关键词: 按键     抖动     消抖    

专家
2021-10-03 22:19:51     打赏
2楼

感谢分享        


工程师
2021-10-03 22:27:18     打赏
3楼

还可以搞两个for嵌套循环! 最外层记录按了多少次,用来处理多次连续按键。内层在规定时间内有按键动作记为真,超过规定时间记为假,这样可以高效消抖


工程师
2021-10-03 22:31:10     打赏
4楼

还是用定时器的好!


工程师
2021-10-03 22:36:37     打赏
5楼

我记的网上有人利用标志位进行消抖,用延时的话有点困难


工程师
2021-10-03 22:41:26     打赏
6楼

一般都是用状态机实现


专家
2021-10-04 00:02:55     打赏
7楼

感谢楼主的分享,很实用了。


专家
2021-10-04 00:06:48     打赏
8楼

感谢分享


院士
2021-10-04 00:08:44     打赏
9楼

来看看


工程师
2021-10-04 00:11:34     打赏
10楼

感谢楼主的分享,很实用了。


共34条 1/4 1 2 3 4 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]