单片机按键去抖动的方法

在使用按键时,我们想按一次按键,但在实际中却经常发现我们要的”一次“,实际上去并不是”一次“而可能是多次。为什么呢?这是因为,我们使用的机械按键,在我们按下时,并非只是接触一次,因为存在机械抖动,导致接触多次。因此,按键检测去抖动就很有必要了。下面,我就向大家介绍按键去抖动的方法。
一、stc15w408as按键电路
二、按键按下和松开时的波形
下面的图形中显示的是按键按下和松开时的理想状态和实际状态。
三、按键去抖动方法
理想波形:没有按下为高电平,按下之后为低电平,松开之后又为高电平。
实际波形:按下之后,存在机械抖动,需要过一段时间才会稳定成低电平,然后,松开时又会产生机械抖动。机械式按键在按下或者释放时,由于机械弹性的影响,通常会伴随有一定的时间触电机械抖动,然后其触电才稳定下来。在触点抖动期间检测按键的通与断,可能会导致错误,也就是有可能被认为进行了多次操作,这种情况是不允许出现的。
因此,在单片机检测键盘是否按下都要加上去抖动操作,按键少时,可采用硬件消抖,按键较多时,采用软件消抖。
我们在编写单片机的按键检测程序时,一般在检测按下时加入去抖动延时(10~20ms即可),也就是当检测到按键输入口是低电平时,延时20ms再检测一次按键的状态是不是还是低电平。如果还是低电平,则认为按键被真正按下一次。
四、按键检测去抖动关键代码
if(!getkey_high()) //如果检测到按键低电平{ delay20ms(); //延时20ms if(!getkey_high()) //如果还是检测到按键低电平 { bkeydown=true; //确认按键已按下 mnum++; //按键次数加1 } while(!getkey_high()); //等待按键松开}* //1ms定时中断函数timer0_isr()void timer0_isr (void) interrupt 1{ if(mdelay >0)//如果mdelay >0 { mdelay--; //则中断到来时,mdelay减1 }}* //20ms延时函数delay20ms()void delay20ms(void){ mdelay=20; //设置mdelay的值为20 while(mdelay >0); //等待mdelay在中断中减到0}* //500ms延时函数delay500ms()void delay500ms(void){ mdelay=500; while(mdelay >0);}五、本例完整源程序
#define fosc 11059200l#define t1ms (65536-fosc/1000) // 1 t模式#define bit0 0x01#define bit1 0x02#define bit2 0x04#define bit3 0x08#define bit4 0x10#define bit5 0x20#define bit6 0x40#define bit7 0x80#define true 1#define false 0#define pin_led p32#define pin_led_m1 p3m1#define pin_led_m0 p3m0#define pin_led_bit bit2#define pinled_high() pin_led=1#define pinled_low() pin_led=0#define pin_key p12#define pin_key_m1 p1m1#define pin_key_m0 p1m0#define pin_key_bit bit2#define getkey_high() pin_key==1#define bool unsigned char#define uint unsigned intvoid pinled_dirout(void);void pinkey_dirin(void);void timer0_init(void);void delay20ms(void);void delay500ms(void);void ledflash(uint num);bool bkeydown=false;uint mdelay=0;uint mnum=0;void main(void){ pinkey_dirin(); pinled_dirout(); pinled_high(); timer0_init(); while(true) { if(!getkey_high()) { delay20ms(); if(!getkey_high()) { mnum++; bkeydown=true; } while(!getkey_high()); } if(bkeydown) { bkeydown=false; ledflash(mnum); } } }void pinkey_dirin(void){ pin_key_m1 &=~pin_key_bit; pin_key_m0 &=~pin_key_bit; }void pinled_dirout(void){ pin_led_m1 &=~pin_led_bit; pin_led_m0 |=pin_led_bit; }void timer0_init(void){ auxr |= 0x80; //定时器0为1t模式 tmod = 0x00; //设置定时器为模式0(16位自动重装载) tl0 = t1ms; //初始化计时值 th0 = t1ms > > 8; tr0 = 1; //定时器0开始计时 et0 = 1; //使能定时器0中断 ea = 1;}// 1msvoid timer0_isr (void) interrupt 1{ if(mdelay >0) { mdelay--; } }void delay20ms(void){ mdelay=20; while(mdelay >0);}void delay500ms(void){ mdelay=500; while(mdelay >0);}//为了方便检验效果,我写了下面这个led闪动函数,第1次按下,led闪动1次,第2次按下,led闪动2次,依次类推。void ledflash(uint num){ uint i; for(i=0;i< num;i++) { pinled_low(); delay500ms(); pinled_high(); delay500ms(); }}

东方集成:电子测试测量租赁热
情怀重生,四台苹果7抵不过一台诺基亚3310
尽管特斯拉股价不断下跌 但其业务表现却并不糟糕
通信用后备式铁锂电池系统有什么特点?
争夺优秀人才教育你会支持孩子上人工智能(AI)嘛?
单片机按键去抖动的方法
最新iPad 3谍照曝光:外形不变Home键保留(图文)
关于OLED拼接屏,有哪些知名厂商?
2021年的智能手机市场会怎么样?
足坛也即将“高考”了!选购华为P20就有机会去俄罗斯见梅西
基于STM32单片机的心电图系统设计
智能魔镜,让家居生活“镜”在掌控
蓝光三维扫描仪手持式与拍照式的区别
新iPhone它们不附带EarPods或包装盒中的充电器
华为首创的全球首个ARM芯片的华为云鲲鹏云手机正式公测
中兴通讯授予Altera全球优秀合作伙伴奖
数字电视机顶盒的工作原理
ESP8266 WEB配网 掉电记忆
传苹果已将折叠式iPhone送入富士康进行测试
您有一封邀请函,请查收!