软件定时扫描按键的核心思路是利用定时器中断产生固定时间基准(如1ms或10ms),在中断服务函数中轮询按键电平,并通过状态机或计数去抖。具体实现:
1. 配置一个硬件定时器(如TIM2),中断周期设为5-10ms,避免高频扫描浪费CPU。
2. 在中断中读取按键IO(需配置为输入上拉/下拉),保存当前电平。
3. 用“边沿检测+连续计数”去抖:若电平与上次相同,则计数加1;不同则清零。当计数达到阈值(如连续5次相同,即25-50ms)时,确认按键状态变化,并置标志位。
4. 主循环中检查标志位,执行按键处理(如短按、长按、组合键),处理完清除标志。
示例代码(伪代码):
```c
volatile uint8_t key_state = 0; // 当前稳定状态
volatile uint8_t key_flag = 0;
void TIM_IRQHandler(void) {
static uint8_t cnt = 0, last = 0;
uint8_t cur = GPIO_ReadPin(KEY_PIN);
if (cur == last) {
if (++cnt >= 5) {
if (key_state != cur) {
key_state = cur;
key_flag = 1;
}
cnt = 0;
}
} else {
cnt = 0;
last = cur;
}
}
```
注意:中断中避免延时和复杂逻辑,只做状态更新;主循环处理业务。若按键数量多,可扩展为扫描矩阵,但原理相同。
mcuku 阿沐 · 2026-08-19