2. 按键控制LED亮灭
任务目标
使用MCU的GPIO引脚连接一个按键和一个LED,通过读取按键状态控制LED的亮灭。按键按下时LED点亮,松开时LED熄灭,并实现按键消抖以避免机械抖动导致的误触发。
硬件连接
- LED正极通过限流电阻(约220Ω)连接至MCU的PB0引脚,负极接地
- 按键一端连接至MCU的PB1引脚,另一端接地(按下为低电平)
- PB1引脚内部启用上拉电阻,确保未按下时读取为高电平
完整代码(STM32F103 HAL库)
#include "stm32f1xx_hal.h"
// 引脚定义
#define LED_PIN GPIO_PIN_0
#define LED_PORT GPIOB
#define KEY_PIN GPIO_PIN_1
#define KEY_PORT GPIOB
// 简单延时函数(非精确,用于消抖)
static void delay_ms(volatile uint32_t ms) {
for (volatile uint32_t i = 0; i < ms * 4000; i++) {
__NOP();
}
}
int main(void) {
HAL_Init();
__HAL_RCC_GPIOB_CLK_ENABLE();
// 配置LED引脚为推挽输出
GPIO_InitTypeDef gpio_led = {0};
gpio_led.Pin = LED_PIN;
gpio_led.Mode = GPIO_MODE_OUTPUT_PP;
gpio_led.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_PORT, &gpio_led);
// 配置按键引脚为输入,启用内部上拉
GPIO_InitTypeDef gpio_key = {0};
gpio_key.Pin = KEY_PIN;
gpio_key.Mode = GPIO_MODE_INPUT;
gpio_key.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY_PORT, &gpio_key);
// 初始状态:LED熄灭
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET);
while (1) {
// 检测按键是否按下(低电平有效)
if (HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN) == GPIO_PIN_RESET) {
delay_ms(20); // 延时消抖
// 再次确认按键仍处于按下状态
if (HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN) == GPIO_PIN_RESET) {
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_RESET); // LED点亮
}
} else {
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET); // LED熄灭
}
}
}
编译与烧录
- 使用STM32CubeIDE创建新工程,选择对应MCU型号(如STM32F103C8T6)
- 将上述代码替换main.c中的默认内容
- 编译工程(Project → Build),确认无错误
- 通过ST-Link连接开发板,点击Run或Debug烧录程序
验证方法
- 程序烧录后,LED初始状态为熄灭
- 按下按键不放,LED应点亮;松开按键,LED立即熄灭
- 快速连续按动按键,LED状态应稳定跟随,不会出现闪烁或误动作(消抖生效)
若LED状态与按键动作完全同步且无抖动干扰,则判定案例通过。
关键说明
- 消抖原理:按键按下瞬间会产生约5~20ms的机械抖动,通过首次检测到低电平后延时20ms再确认一次,可过滤抖动信号
- 本例采用查询方式检测按键,适用于单按键场景;若需多按键或低功耗应用,可改用外部中断+定时器消抖方案
- delay_ms函数为软件延时,实际延时时间与系统时钟频率相关,本代码基于默认8MHz内部时钟估算