STM32G031J6芯片TIM2溢出未触发TIM2_IRQHandler中断问题咨询
问题根因与修复方案
核心错误点
- 中断服务函数内错误调用
__WFE():中断服务函数需要尽快执行完毕并返回,你在TIM2_IRQHandler最后调用__WFE()会让内核在中断上下文里进入低功耗模式等待事件,无法正常退出中断,直接导致程序跑飞进入默认异常处理。
- 中断服务函数内错误调用
- UG更新事件触发未清标志隐患:你在配置TIM2时调用
TIM2->EGR |= TIM_EGR_UG触发更新事件,硬件会自动置位TIM_SR_UIF溢出标志,虽然你在run_app中清了一次,但如果中间逻辑顺序有变动很容易出现一开中断就直接触发异常的问题。
- UG更新事件触发未清标志隐患:你在配置TIM2时调用
- 中断向量未正确链接(概率性问题):如果使用C++编译环境,或者函数名拼写、大小写与启动文件中向量表定义的入口名不一致,会导致自定义的
TIM2_IRQHandler无法覆盖启动文件里的弱定义默认中断入口,溢出时直接进默认死循环中断导致崩溃。
- 中断向量未正确链接(概率性问题):如果使用C++编译环境,或者函数名拼写、大小写与启动文件中向量表定义的入口名不一致,会导致自定义的
修复代码步骤
1. 修正TIM2中断服务函数,删除__WFE()调用
建议把清中断标志操作放在入口处,避免中断延迟触发:
void TIM2_IRQHandler(void) { // 优先清除TIM2更新中断标志 TIM2->SR &= ~TIM_SR_UIF; // 翻转PA11(引脚5)电平 GPIOA->ODR ^= (0x1u << 11); }
2. 修复TIM2配置逻辑,触发UG后立即清溢出标志
在config_blink_timer函数中补充清标志操作:
// 触发更新事件复位定时器、应用配置 TIM2->EGR |= TIM_EGR_UG; // 清除UG事件自动触发的UIF溢出标志 TIM2->SR &= ~TIM_SR_UIF; // 开启TIM2中断通道 NVIC_EnableIRQ(TIM2_IRQn);
3. 确认中断向量链接正确
- 检查函数名
TIM2_IRQHandler的拼写、大小写完全和启动文件中向量表定义的入口名一致 - 如果是C++编译环境,需要在函数声明前加
extern "C"修饰,避免名字修饰导致链接不上向量表:
#ifdef __cplusplus extern "C" { #endif void TIM2_IRQHandler(void); #ifdef __cplusplus } #endif
额外优化建议
如果仅需要输出50kHz方波不需要额外逻辑,可以直接用TIM2的输出比较功能硬件翻转PA11,不需要进中断,输出精度更高还能节省CPU资源。
内容的提问来源于stack exchange,提问作者Christian M.
相关产品推荐
相关产品推荐

