一、什么是抖动

        按键在按下时,活动触点击打固定触点会有机械振动,因而造成输出波形抖动,因按键形态和触点材料的不同,抖动的过程一般会持续数毫秒,金属触点的按键可能达到10ms,而软性触点(如导电橡胶或薄膜)则可能在1ms以内甚至没有抖动。

二、为什么要去抖

        如果不进行去抖处理,那么CPU会误判按键的状态,将一次按键操作识别为多次按键操作,从而导致程序出现错误的响应。

三、如何实现高效的去抖

uint32_t falling_tick;
uint32_t rising_tick;
//上面两个变量分别为上升沿对应的时间Tr,下降沿对应的时间Tf。先定义,后面会用到。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
//	if (GPIO_Pin==KEY2_Pin){
//		HAL_Delay(10);
//		if (HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)== GPIO_PIN_RESET){
//			HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
//		}
//	}
//上面是一般方法 , 用HAL_DELAY去抖,执行效率低。中断的设计初衷是为了能够及时响应外部事件,以保证系统对实时性事件的处理能力。而 delay 函数是一种阻塞式的延时方式,当在中断响应函数中调用 delay 时,CPU 会进入等待状态,在延时期间无法处理其他任务。这意味着在去抖的这段时间内,系统无法响应其他的中断请求,严重影响了系统的实时性。

//下面是用tick作差方法去抖
	if (GPIO_Pin==KEY2_Pin){
    //先判断是不是KEY2的中断请求,这一步至关重要
		if ((HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==GPIO_PIN_RESET)){
        //如果触发信号为低电平
			falling_tick=HAL_GetTick();
        //获取下降沿对应的时间Tf
		}
		else if (HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==GPIO_PIN_SET && falling_tick!=0){
        //如果是高电平,*并*且*之*前*获*取*了*Tf(不能在无Tf时直接取Tr,不然很容易出错)
			rising_tick=HAL_GetTick();
        //获取Tr
			if((rising_tick-falling_tick)>50){
        //在工程中,一般认为Tr-Tf大于50ms就不是抖动
				HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
        //反转输出给LED灯的电平(点亮/熄灭),这里可以是其他外设
			}
			rising_tick=falling_tick=0;
            //判断完成后归0以供下次使用
		}
	}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐