You need to enable JavaScript to run this app. STM32G071KBU EXTI中断触发HardFault_Handler错误问题求助
优惠活动
大模型
产品
解决方案
定价
更多

STM32G071KBU EXTI中断触发HardFault_Handler错误问题求助

故障原因排查

  • 核心诱因是按键机械抖动未做处理:普通机械按键按下/松开时会产生数ms~数十ms的电平抖动,对应产生多个连续的上升/下降沿,你的EXTI配置为下降沿触发且中断优先级为最高级0,抖动会导致短时间内连续触发上百次中断。
  • 最终触发HardFault的根因是栈溢出:最高优先级中断连续触发时,主程序无法运行,中断请求会不断嵌套压栈,栈空间耗尽后程序跑飞进入HardFault_Handler,这也是你用LL库、HAL库都能复现问题的核心原因,和库实现无关。
  • 次要潜在问题:当前用自增操作修改m_led_status仅为切换LED状态无必要,虽不会直接触发故障,但存在无意义的变量溢出风险。

解决方案

1. 新增按键消抖逻辑(必改)

二选一即可,优先推荐硬件消抖实现最简单:

  • 硬件消抖:在按键的信号引脚和GND之间并联100nF~1μF的陶瓷电容,直接滤除抖动产生的窄脉冲尖峰,无需修改软件。
  • 软件消抖:在EXTI中断触发后先关闭PB2对应的EXTI中断,同时启动一个10ms的硬件定时器,定时器溢出中断中再清除EXTI挂起标志、重新打开EXTI中断,避免抖动重复触发。

示例软件消抖修改参考:

// 新增全局变量记录中断有效标记
volatile static uint8_t g_exti_valid = 1;

void EXTI2_3_IRQHandler(void)
{
  if (LL_EXTI_IsActiveFallingFlag_0_31(LL_EXTI_LINE_2) != RESET)
  {
    LL_EXTI_ClearFallingFlag_0_31(LL_EXTI_LINE_2);
    // 消抖期直接忽略无效触发
    if (g_exti_valid) {
        g_exti_valid = 0;
        m_led_status ^= 1; // 替换自增为直接翻转,更安全
        // 这里启动你配置的10ms定时器即可
        LL_TIM_EnableCounter(TIM2);
        LL_TIM_EnableIT_UPDATE(TIM2);
    }
  }
}

// 定时器更新中断服务函数
void TIM2_IRQHandler(void) {
  if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) {
    LL_TIM_ClearFlag_UPDATE(TIM2);
    LL_TIM_DisableCounter(TIM2);
    g_exti_valid = 1;
  }
}

2. 辅助优化项

  • 检查启动文件中Stack_Size配置,建议至少设置为0x400(1KB),避免栈空间过小导致偶发溢出。
  • 无需将EXTI中断优先级设为最高级0,可调整为2或更低,避免阻塞内核异常处理逻辑。
  • 替换m_led_status++为m_led_status ^= 1,直接实现状态翻转,消除无意义的变量溢出。

内容的提问来源于stack exchange,提问作者Marco Arigliani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 20:36:01