2. 按键输入检测与消抖

任务目标

使用STM32微控制器的GPIO输入功能读取按键状态,通过软件延时消抖处理机械按键的抖动问题,实现按键按下时翻转LED的亮灭状态。本案例以STM32F103系列为例,使用标准外设库完成GPIO输入模式配置与按键检测逻辑。

硬件连接

  • 按键一端接PA0引脚,另一端接地(低电平有效)
  • LED正极通过限流电阻接PC13引脚,负极接地(高电平点亮)
  • PA0需配置为上拉输入模式,确保按键未按下时引脚为高电平

关键代码


#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

// 延时函数(简单软件延时,约1ms @72MHz)
void Delay_ms(uint32_t ms) {
    uint32_t i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 7200; j++);
}

// 按键消抖检测函数:返回1表示确认按下(已消抖),返回0表示未按下
uint8_t Key_Scan(void) {
    if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) {  // 检测到低电平
        Delay_ms(20);                                     // 延时20ms跳过抖动区
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) { // 再次确认仍为低电平
            while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0); // 等待按键释放
            return 1;  // 确认一次有效按下
        }
    }
    return 0;
}

int main(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能GPIOA和GPIOC时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
    
    // 配置PA0为上拉输入(按键输入)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  // 上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置PC13为推挽输出(LED控制)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    GPIO_SetBits(GPIOC, GPIO_Pin_13);  // 初始状态:LED灭
    
    while (1) {
        if (Key_Scan()) {
            // 翻转LED状态
            if (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13) == 0) {
                GPIO_SetBits(GPIOC, GPIO_Pin_13);   // 置高,LED灭
            } else {
                GPIO_ResetBits(GPIOC, GPIO_Pin_13); // 置低,LED亮
            }
        }
    }
}

编译与运行

  1. 使用Keil MDK或IAR创建工程,选择对应STM32F103型号,添加上述代码
  2. 在工程配置中启用标准外设库(STM32F10x_StdPeriph_Lib)
  3. 编译生成HEX文件,通过ST-Link或J-Link下载至开发板

验证方法

程序下载后,按下按键并释放,观察LED状态是否翻转。快速连续按动按键,每次按下释放后LED应恰好翻转一次,不会出现多次翻转或闪烁现象。若LED状态不稳定或一次按键多次翻转,说明消抖延时不足或按键释放检测逻辑有误,可适当增加延时时间至30~50ms。

消抖原理说明

机械按键在按下和释放瞬间会产生约5~10ms的电平抖动,表现为引脚电平在高低之间快速跳变。本案例采用“检测低电平→延时20ms→再次检测”的软件消抖方法:若第一次检测到低电平后延时20ms仍为低电平,则判定为有效按下;随后等待按键释放,确保一次按键只触发一次动作。这种消抖方式不依赖额外硬件,适用于大多数按键场景。