You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F4如何交替使用按键中断的上升沿与下降沿实现LED控制

按键控制LED交替状态问题

需求说明

  • 按键需实现两种状态交替:
    1. 第一次按键上升沿时点亮LED,按键下降沿时保持LED点亮;
    2. 下一次按键的下降沿时熄灭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中断
}

问题分析与修复方案

你的代码存在两个核心逻辑错误:

  1. LED操作逻辑错误:每次中断触发就直接翻转LED状态,违背了“上升沿点亮、下降沿熄灭”的分步需求;
  2. 初始触发模式错误:初始状态未设置为上升沿触发,导致第一次触发逻辑就偏离需求。

修复后的代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 11:29:55