论坛» 嵌入式开发» MCU

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

工程师
2021-10-03 22:18 1楼

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


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

  1. #include

  2. #include

  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

  2. #include

  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

  2. #include

  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 2楼

感谢分享

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

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

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

还是用定时器的好!

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

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

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

一般都是用状态机实现

专家
2021-10-04 00:02 7楼

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

专家
2021-10-04 00:06 8楼

感谢分享

院士
2021-10-04 00:08 9楼

来看看

工程师
2021-10-04 00:11 10楼

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

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

回复

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