STM32F4如何交替使用按键中断的上升沿与下降沿实现LED控制
按键控制LED交替状态问题
需求说明
- 按键需实现两种状态交替:
- 第一次按键上升沿时点亮LED,按键下降沿时保持LED点亮;
- 下一次按键的下降沿时熄灭LED,之后循环上述逻辑。
当前问题
我编写了如下代码,但实际运行时LED仅在按键按下时熄灭,不符合需求:
volatile unsigned int pressed; volatile unsigned int state; int main(void){ pressed = 0; state = 0; LD_Init(); Interrupt_Init(); /* Loop forever */ while(1) { if (pressed) { if (state == 0) { EXTI->FTSR |= (1<<13); // 使能EXTI下降沿触发 EXTI->RTSR &= ~(1<<13); // 关闭EXTI上升沿触发 } if (state == 1){ EXTI->FTSR &= ~(1<<13); // 关闭EXTI下降沿触发 EXTI->RTSR |= (1<<13); // 使能EXTI上升沿触发 } GPIOA->ODR ^= (1<<5); pressed = 0; state = !state; } } } void EXTI15_10_IRQHandler(void){ pressed = 1; EXTI->PR |= (1<<13); // 清除PR标志以重新使能EXTI中断 }
问题分析与修复方案
你的代码存在两个核心逻辑错误:
- LED操作逻辑错误:每次中断触发就直接翻转LED状态,违背了“上升沿点亮、下降沿熄灭”的分步需求;
- 初始触发模式错误:初始状态未设置为上升沿触发,导致第一次触发逻辑就偏离需求。
修复后的代码
volatile unsigned int pressed; volatile unsigned int state; // 0: 等待上升沿点亮LED;1: 等待下降沿熄灭LED int main(void){ pressed = 0; state = 0; LD_Init(); Interrupt_Init(); // 初始状态:使能上升沿触发,对应第一次按键点亮LED的需求 EXTI->RTSR |= (1<<13); EXTI->FTSR &= ~(1<<13); while(1) { if (pressed) { if (state == 0) { // 上升沿触发:直接点亮LED,切换到等待下降沿的状态 GPIOA->ODR |= (1<<5); EXTI->FTSR |= (1<<13); // 切换为下降沿触发 EXTI->RTSR &= ~(1<<13); state = 1; } else if (state == 1) { // 下降沿触发:直接熄灭LED,切换回等待上升沿的状态 GPIOA->ODR &= ~(1<<5); EXTI->RTSR |= (1<<13); // 切换为上升沿触发 EXTI->FTSR &= ~(1<<13); state = 0; } pressed = 0; } } } void EXTI15_10_IRQHandler(void){ // 注:实际硬件建议添加消抖逻辑,比如短暂延时后再次检测按键状态,避免误触发 pressed = 1; EXTI->PR |= (1<<13); // 清除中断挂起标志 }
关键修改点
- 移除LED翻转操作,改为根据当前状态直接点亮/熄灭,避免逻辑混乱;
- 修正初始触发模式,启动时默认使能上升沿触发,匹配第一次按键点亮的需求;
- 每个状态对应唯一的触发沿配置,确保状态切换与触发逻辑严格绑定;
- 建议在中断中添加按键消抖,解决硬件抖动导致的误触发问题。
内容的提问来源于stack exchange,提问作者jerxe
相关产品推荐
相关产品推荐

