2. 按键输入检测

任务目标

使用GPIO输入模式读取按键状态,实现按下按键点亮LED、松开熄灭的功能,并掌握按键消抖的基本处理方法。本案例以STM32F103系列MCU为硬件平台,通过标准外设库完成GPIO初始化和状态读取。

硬件连接

  • 按键:一端接PA0,另一端接GND(按下为低电平)
  • LED:正极经限流电阻接PC13,负极接GND(高电平点亮)
  • 注意:STM32F103最小系统板上PC13通常连接板载LED,PA0为自由引脚

核心代码


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

// 按键消抖延时函数(简单软件延时)
static void Delay(void) {
    uint32_t i;
    for (i = 0; i < 0x1FFFF; i++);  // 约10ms(72MHz主频)
}

void GPIO_Config(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);
    
    // 初始状态:LED熄灭
    GPIO_SetBits(GPIOC, GPIO_Pin_13);
}

int main(void) {
    GPIO_Config();
    
    while (1) {
        // 检测按键是否按下(PA0为低电平)
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) {
            // 软件延时消抖
            Delay();
            // 再次确认按键状态
            if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) {
                GPIO_ResetBits(GPIOC, GPIO_Pin_13);  // 点亮LED
            }
        } else {
            GPIO_SetBits(GPIOC, GPIO_Pin_13);  // 松开按键,熄灭LED
        }
    }
}

编译与烧录

  1. 创建STM32标准外设库工程,添加上述代码到main.c
  2. 编译生成HEX文件(需包含STM32F10x标准外设库的GPIO和RCC驱动源文件)
  3. 使用ST-Link或J-Link通过SWD接口烧录到STM32F103开发板

验证方法

  • 上电后LED应处于熄灭状态
  • 按下按键(PA0接地),LED应立即点亮
  • 松开按键,LED应立即熄灭
  • 快速连续按动按键,LED状态应稳定跟随,无闪烁或误触发

通过条件:按键按下时LED稳定点亮,松开后稳定熄灭,且按键过程中无抖动导致的LED闪烁现象。

关键说明

本案例采用上拉输入模式,按键按下时引脚读到低电平。消抖采用“检测到低电平→延时→再次确认”的软件方法,延时约10ms可覆盖典型机械按键的抖动时间。若使用其他MCU平台,需根据GPIO寄存器差异调整初始化代码,但消抖逻辑和输入读取原理完全通用。