单片机怎么实现软件定时扫描按键?

嵌入式 · 1 浏览
单片机怎么实现软件定时扫描按键?

回答(4)

记得在中断里关掉其他中断或使用临界区保护共享变量,防止主循环读取时数据不一致。
硬件工程师李工 · 2026-08-19
如果MCU资源紧张,可以不用定时器,用主循环的delay+非阻塞计数,但实时性差些,适合简单场景。
码农小王 · 2026-08-19
建议用状态机管理按键,比如空闲、按下、确认、释放,这样能区分短按和长按,代码更清晰。
嵌入式老张 · 2026-08-19
软件定时扫描按键的核心思路是利用定时器中断产生固定时间基准(如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