基础操作之按键消抖

机械弹性开关:

    当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上就稳定的接通,在断开时也不会一下子彻底断开,而是在闭合和断开的瞬间伴随了一连串的抖动

按键时间:按键稳定闭合时间长短是由操作人员决定的,通常都会在 100ms 以上,刻意快速按的话能达到 40-50ms 左右,很难再低了;大致时间可以通过在1s时间正常可按多少次来计算;


当检测到按键状态变化时,不是立即去响应动作,而是先等待闭合或断开稳定后再进行处理。即为按键消抖

按键消抖:可分为硬件消抖和软件消抖。

硬件消抖就是在按键上并联一个电容,如图 8-11 所示,利用电容的充放电特性来对抖动过程中产生的电压毛刺进行平滑处理,从而实现消抖。

   * 但实际应用中,这种方式的效果往往不是很好,而且还增加了成本和电路复杂度,所以实际中使用的并不多。绝大多数情况下,我们是用软件即程序来实现消抖的


软件消抖

(1):延时消抖

最简单的消抖原理,就是当检测到按键状态变化后,先等待一个 10ms 左右的延时时间,让抖动消失后再进行一次按键状态检测,如果与刚才检测到的状态相同,就可以确认按键已经稳定的动作了

    //按键处理函数 //输入模式选择:mode:0,不支持连续按;1,支持连续按
 //返回按键值=====================  ;
    //0,没有任何按键按下
    //1,KEY0按下
    //2,KEY1按下
    //3,KEY2按下 
    //4,WKUP按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!!
u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;//按键按松开标志
	if(mode)key_up=1;  //支持连按,如果模式1的时候,key_up在未松开的时候依然依然可烧描更新		  
	if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
	{
		key_up=0;    //如果模式是0,key_up在此处变为0之后,在未松开的时候无法扫描更新
		delay_ms(10);//去抖动 :通过延时实现 
		if(KEY0==0)
			return 1;
		else if(KEY1==0)
			return 2;
		else if(KEY2==0)
			return 3;
		else if(WK_UP==1)
			return 4;
	}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)
			key_up=1; 	    
 	return 0;// 无按键按下
}

(2):利用定时器消抖

举个例子:我们启用一个定时中断,每 2ms 进一次中断,扫描一次按键状态并且存储起来,连续扫描 8 次后,看看这连续 8 次的按键状态是否是一致的。8 次按键的时间大概是 16ms,这 16ms 内如果按键状态一直保持一致,那就可以确定现在按键处于稳定的阶段,而非处于抖动的阶段,如图 8-12:

/* T0 中断服务函数,用于按键状态的扫描并消抖 */
void InterruptTimer0() interrupt 1
{
static unsigned char keybuf = 0xFF; //扫描缓冲区,保存一段时间内的扫描值
TH0 = 0xF8; //重新加载初值
TL0 = 0xCD;
keybuf = (keybuf<<1) | KEY4; //缓冲区左移一位,并将当前扫描值移入最低位
if (keybuf == 0x00)
{ //连续 8 次扫描值都为 0,即 16ms 内都只检测到按下状态时,可认为按键已按下
KeySta = 0;
}
else if (keybuf == 0xFF)
{ //连续 8 次扫描值都为 1,即 16ms 内都只检测到弹起状态时,可认为按键已弹起
KeySta = 1;
}
else
{} //其它情况则说明按键状态尚未稳定,则不对 KeySta 变量值进行更新
}

利用之前的例子修改

u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;//按键按松开标志
	if(mode)key_up=1;  //支持连按		
	 	
	if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
	{
		delay_go=1;
		key_up=0;
		//delay_ms(10);//去抖动 
		if(flag_key_delay)
		{ 
			flag_key_delay=0;
			if(KEY0==0)
				return 1;
			else if(KEY1==0)
				return 2;
			else if(KEY2==0)
				return 3;
			else if(WK_UP==1)
				return 4;
		}
		
	}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)
			key_up=1; 	    
 	return 0;// 无按键按下
}


  • 35
    点赞
  • 157
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoxilang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值