从按键外形到程序逻辑,从电路原理到交互演示 —— 全面解析轻触按键的检测与消抖
认识轻触按键的外形特征、工作原理与核心功能
本演示使用的是经典的 6×6mm 四脚轻触按键,是电子设计中最常见的按键类型之一。其外观小巧,顶部有一个圆形按钮帽,底部有四个引脚。



按键内部有一个金属弹片( dome ),按下按钮帽时,弹片受力变形向下凸起,接触底部的两个触点,使电路导通;松开后弹片依靠自身弹性恢复原状,触点分离,电路断开。
在电路中,轻触按键相当于一个常开型开关。配合上拉电阻,可以实现"默认高电平、按下低电平"的检测方案:
原理图、PCB布局与引脚分配
| 外设 | 引脚 | GPIO模式 | 上下拉 | 初始电平 | 说明 |
|---|---|---|---|---|---|
| LED | PC13 | 推挽输出 (OUTPUT_PP) | 无 (NOPULL) | 高 (SET) | 板载LED,低电平点亮 |
| KEY | PB11 | 输入模式 (INPUT) | 上拉 (PULLUP) | 高 (默认) | 按下接地,读低电平 |
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO 端口时钟使能 */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/* LED 初始输出高电平(熄灭) */
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
/* LED 引脚配置:推挽输出 */
GPIO_InitStruct.Pin = LED_Pin; // PC13 */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出 */
GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉 */
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 低速即可 */
HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
/* KEY 引脚配置:上拉输入 */
GPIO_InitStruct.Pin = KEY_Pin; // PB11 */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 输入模式 */
GPIO_InitStruct.Pull = GPIO_PULLUP; // 内部上拉 */
HAL_GPIO_Init(KEY_GPIO_Port, &GPIO_InitStruct);
}
主循环逐行解读 — 按键检测、消抖与LED翻转
while (1)
{
// ① 检测按键是否按下(读到低电平 = RESET)
if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET)
{
HAL_Delay(10); // ② 延时10ms,软件消抖
if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET) // ③ 再次确认
{
while(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET); // ④ 等待松开
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); // ⑤ 翻转LED
}
}
}
if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET)HAL_GPIO_ReadPin() 读取 PB11 的电平。由于配置了内部上拉,未按下时为高电平(SET),按下时为低电平(RESET)。当读到 RESET,说明按键可能被按下。
HAL_Delay(10);机械按键在闭合瞬间,金属弹片会发生弹性抖动,导致电平在 0 和 1 之间快速跳变,持续约 5~10ms。HAL_Delay(10) 跳过这段抖动期,等信号稳定后再判断。
if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET)延时后再次读取引脚电平。如果仍为 RESET,确认是真正的按键按下(而非干扰噪声);如果恢复为 SET,说明之前的低电平是抖动或干扰,忽略本次触发。
while(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET);这是一个空循环,持续检测引脚电平。只要按键还按着(RESET),程序就停在这里等待。直到用户松开按键,电平恢复为 SET,循环退出。这一步保证"按一次只翻转一次"。
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);按键松开后,调用 HAL_GPIO_TogglePin() 翻转 PC13 的输出电平。如果当前是高(灭)→ 变低(亮);如果是低(亮)→ 变高(灭)。每次完整按压-松开周期,LED 切换一次状态。
完整的检测-消抖-响应流程
点击按钮体验完整的按键检测-消抖-LED翻转过程
STM32F103C8T6 轻触按键演示 | HAL库 | 按键检测+软件消抖+LED翻转
演示程序基于 STM32CubeMX 生成