消抖是为了避免按键在物理接触时可能引起的抖动信号,从而导致多次触发中断回调函数。以下是一种常见的按键消抖方法:
- 在HAL_GPIO_EXTI_Callback函数中,使用延时函数(例如HAL_Delay)等待一个适当的时间,以确保消除按键的抖动。例如,可以延时10毫秒。
if(GPIO_Pin == KEY1_Pin) { HAL_Delay(10); // 其他处理代码 }
- 在按键的回调函数中,添加一个变量来记录上一次按键触发的时间戳。每次回调函数被调用时,检查当前时间与上一次触发的时间差。如果时间差小于一定阈值,忽略当前触发,否则执行相应的操作。
#define DEBOUNCE_DELAY 200 // 设置消抖延时为200毫秒
void Key_1_Callback(void)
{
static uint32_t lastTriggerTime = 0;
uint32_t currentTime = HAL_GetTick(); // 获取当前时间戳
if (currentTime - lastTriggerTime >= DEBOUNCE_DELAY)
{
// 执行按键触发的操作
// ...
lastTriggerTime = currentTime; // 更新上一次触发的时间戳
}
}
这种方法通过设置一个适当的延时和使用时间戳比较的方式,在一定程度上可以消除按键的抖动效应。
进阶:使用回调函数给每一个按键独立软件防抖
c
/*
* @Author: DuRuofu duruofu@qq.com
* @Date: 2023-08-02 12-02-17
* @LastEditors: DuRuofu
* @LastEditTime: 2023-08-03 15-28-12
* @FilePath: \Project\RedServo\STM32\User\KEY\key.c
* @Description: 键盘扫描
* Copyright (c) 2023 by duruofu@foxmail.com All Rights Reserved.
*/
#include "key.h"
#include "led.h"
#include "gui.h"
#include "yuntai.h"
#include "Buzzer.h"
#include "app.h"
#define KEY1_Pin KEY_1_Pin
#define KEY2_Pin KEY_2_Pin
#define KEY3_Pin KEY_3_Pin
#define KEY4_Pin KEY_4_Pin
#define KEY5_Pin KEY_5_Pin
#define KEY6_Pin KEY_6_Pin
#define KEY7_Pin KEY_7_Pin
#define KEY8_Pin KEY_8_Pin
#define KEY9_Pin KEY_9_Pin
#define KEY10_Pin KEY_10_Pin
#define KEY11_Pin KEY_11_Pin
#define DEBOUNCE_DELAY 250 // 设置消抖延时为200毫秒
//题目切换按钮
void Key_1_Callback(void)
{
//按键逻辑代码
}
// 急停按键
void Key_2_Callback(void)
{
//按键逻辑代码
}
//
/**
* @description: 按键检测,外部中断回调函数
* @param {uint16_t} GPIO_Pin
* @return {*}
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(GPIO_Pin);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_GPIO_EXTI_Callback could be implemented in the user file
*/
if(GPIO_Pin == KEY1_Pin)
{
Debounce(GPIO_Pin, Key_1_Callback);
}
else if(GPIO_Pin == KEY2_Pin)
{
// 按键2按下的处理代码
Debounce(GPIO_Pin, Key_2_Callback);
}
}
// 通用的按键消抖函数
void Debounce(uint16_t GPIO_Pin, void (*callback)(void))
{
static uint32_t lastTriggerTime = 0;
uint32_t currentTime = HAL_GetTick(); // 获取当前时间戳
if (currentTime - lastTriggerTime >= DEBOUNCE_DELAY)
{
Buzzer_ShortBeep();
callback(); // 调用传入的回调函数
lastTriggerTime = currentTime; // 更新上一次触发的时间戳
}
}
通过在每个按键回调函数中独立地记录和比较时间戳,可以确保每个按键都独立地进行消抖处理。这样可以避免一个按键的抖动影响到其他按键的触发。请根据实际情况适当调整消抖延时以满足你的需求。