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

移植玩具应用到RTFM框架时,如何通过GPIO触发中断?

搞定RTFM框架下STM32F103的GPIO中断配置

看了你贴的代码,目前只完成了EXTI中断屏蔽和部分触发配置,还缺几个关键步骤,咱们一步步补全,把中断跑起来:

1. 补全EXTI触发方式的完整配置

你代码里ftsr的配置没写完,得明确是下降沿还是上升沿触发,比如要配置下降沿触发的话:

dp.EXTI.ftsr.write(|w| w.tr0().set_bit());
// 如果需要上升沿触发,还要加上这行:
// dp.EXTI.rtsr.write(|w| w.tr0().set_bit());

2. 关键:配置SYSCFG把GPIO引脚映射到EXTI线

STM32F1的EXTI必须通过SYSCFG来关联GPIO引脚,PA0对应EXTI0,所以得加这段配置:

// 先获取SYSCFG外设,注意要依赖APB2时钟
let mut syscfg = dp.SYSCFG.constrain(&mut rcc.apb2);
// 把PA0映射到EXTI0线
syscfg.exticr1.exti0().set_pa0();

这一步很容易忘,没做的话EXTI根本不知道要监听哪个GPIO引脚。

3. 在RTFM框架中声明中断资源

RTFM是基于宏的框架,必须在#[rtfm::app]里声明要使用的中断,才能让框架正确生成中断处理逻辑。完整的代码结构应该是这样:

#[rtfm::app(device = stm32f103xx, peripherals = true)]
const APP: () = {
    #[init]
    fn init(cx: init::Context) -> init::LateResources {
        let dp = cx.device;
        let mut rcc = dp.RCC.constrain();
        let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
        
        // 配置PA0为浮空输入
        let _int = gpioa.pa0.into_floating_input(&mut gpioa.crl);

        // 配置SYSCFG引脚映射
        let mut syscfg = dp.SYSCFG.constrain(&mut rcc.apb2);
        syscfg.exticr1.exti0().set_pa0();

        // 解除EXTI0的中断屏蔽
        dp.EXTI.imr.write(|w| w.mr0().set_bit());
        // 配置下降沿触发
        dp.EXTI.ftsr.write(|w| w.tr0().set_bit());

        init::LateResources {}
    }

    // 声明EXTI0的中断处理函数
    #[interrupt]
    fn EXTI0() {
        // 这里写你的中断处理逻辑
        // !!必须清除中断标志位,否则会一直触发中断!!
        cortex_m::interrupt::free(|cs| {
            let dp = stm32f103xx::Peripherals::steal(cs);
            dp.EXTI.pr.write(|w| w.pr0().set_bit());
        });
    }

    // 可选的空闲任务,让CPU进入低功耗等待中断
    #[idle]
    fn idle(_cx: idle::Context) -> ! {
        loop {
            cortex_m::asm::wfi();
        }
    }
};

4. 容易踩坑的注意点

  • 清除中断标志位:每次中断触发后一定要清除EXTI_PR寄存器对应的位,我在上面的中断处理函数里加了,这是最容易犯的错误,不清除的话中断会无限触发。
  • 时钟使能:确保SYSCFG和GPIO的时钟已经正确打开,RTFM的split和constrain方法一般会帮你处理,但手动配置时要留意。
  • RTFM中断声明:必须用#[interrupt]宏标记中断函数,框架才会把它加入中断向量表,否则写了也不会执行。

调试小妙招

如果中断还是不触发,可以按这个顺序排查:

  • 检查PA0的输入模式是否正确(浮空输入没问题,也可以根据需求用上拉/下拉)。
  • 用调试器查看SYSCFG_EXTICR1寄存器,确认PA0已经映射到EXTI0。
  • 检查EXTI的IMR、FTSR/RTSR寄存器配置是否正确。
  • 查看EXTI_PR寄存器,看看有没有中断标志位被置位,判断是没触发还是没处理。

内容的提问来源于stack exchange,提问作者Michael Böckling

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:21:26