【BUG】STM32程序卡在B .即Default_Handler处

记录代码进入Default_Handler错误的解决办法

问题表述

在一次调试代码的时候,发现代码卡死在启动文件 startup_stm32f0xx_.s 的222行,即 B. 处

B.是汇编代码,B:跳转到一个标号,这里跳转到一个‘.’,即表示无限死循环

通过在Debug窗口可以定位到,程序是进入Default_Handler错误

在这里插入图片描述

根本原因分析:

底层原理

1. 中断向量表结构
STM32启动文件预先定义了完整的中断向量表,包含所有可能的异常和中断处理程序入口地址。其中的典型定义形式为:

g_pfnVectors:
  .word  _estack
  .word  Reset_Handler
  .word  NMI_Handler
  ...
  .word  DMA1_Channel1_IRQHandler
  ...  // 共百余个中断向量

2. 弱符号定义规则
启动文件通过.weak指令将默认Handler设为弱符号(模板代码可见下图):
启动文件中的弱符号定义
这种设计允许开发者在外设驱动文件中重写同名中断服务函数,当链接器检测到重载时会优先选择用户定义版本。

3. 中断触发流程

[中断触发] → [NVIC查找向量表] → [执行对应ISR]
    ↑                           ↓
    └─若未注册有效ISR → 执行Default_Handler

一、底层原理打比方

假设你有一栋大楼(STM32芯片),楼里每个房间都装了应急按钮(外设中断)。你给每个按钮都写了贴纸标签(启动文件中的中断服务函数名)。但有个特殊情况:所有按钮都默认连接到同一间喇叭房(Default_Handler),只有当工人在你的总控系统(项目代码)里给具体房间接线(实现正确的中断函数)时,对应的按钮才会连接到真正的功能房间。

二、分步骤详细解释

2.1 为什么程序会"死循环"?

正常情景
当你正确配置一个外设(比如串口DMA)中断时:
真按钮 → 连接到功能房(用户实现的DMA1_Handler)→ 正常工作

故障情景
配置了外设中断,却没有实现对应的处理函数:

假按钮 → 默认连接到喇叭房(启动文件的Default_Handler)→ B.死循环(持续报警)

中断配置原理示意图

2.2 两个关键设计特性
  1. "假功能房"设计(弱符号声明)
    启动文件里预先写了各种DMA1_Handler这样的空函数,例如:
// 这是启动文件的预先声明(赋予低优先级)
__weak void DMA1_Channel1_IRQHandler(void) {
    while(1); // 危险设计:堵在这里
}

标注__weak表示:这个函数可以被你的代码覆盖取代。

  1. "按钮标签强行对应"规则
    中断向量表强制要求每个按钮必须对应一个处理函数。当出现以下情况都会被导向Default_Handler:
  • 函数名称写错(如DMA_Handler漏写"Channel1")
  • 忘记实现函数
  • 中断配置错误

三、快速自检口诀

当你遇到"卡死在B.死循环"时,三步口诀定位:

1、查外设——是否开启了没用到的中断?
2、对名称——中断函数名是否与启动文件完全一致?
3、看调用——通过CallStack回溯哪个中断被触发?

总结
在开启了某个中断,但是又忘记编写配套的中断服务程序或者函数名写错,代码会进入Default_Handler错误,即 B. 死循环

参考链接:
关于STM32程序卡在B .即Default_Handler处的解决方法
【玩转STM32】:Default_Handler问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值