STMCU小助手
发布时间:2023-11-26 15:24
|
01引言2 q- f S- R0 G. O8 A# ]# [ 某客户设计需要启动定时器在 3ms 后产生中断,其后定时器不再运行,直至下一次软件要求再次启动定时器产生中断,实测代码后发现定时器启动后立即产生了超时中断。 . m7 ~5 r0 Y( N, ^3 ^- k 02调研 客户通过 STM32CubeMX 配置 TIM7 并生成工程,在主循环中添加定时器启动代码;在定时器中断处理函数处理 update event 回调时停止定时器,并翻转一个 I/O 脚指示定时器启停,代码如下: % s0 B8 S" w2 a! f
图1.启动定时器 f% e2 ^# O+ h2 h" A& d* ^% L
图2.定时器中断回调 客户期待的结果是启动定时器时 I/O 拉高并保持 3ms,当 3ms 到达后产生中断拉低I/O,但实测时发现,定时器启动后立即产生了超时中断(高电平持续时间约 2us):' R4 s4 d: I" H7 `; h- i# K/ s3 @ ' g; {+ ^# h& r& y- F: `4 a8 P( X
图3.实测结果 0 G7 K5 p0 i9 j. {03分析0 M X- K) \8 L 应用代码在初始化定时器时会调用 HAL_TIM_Base_Init( )接口,此接口会调用TIM_Base_SetConfig( ) 配置定时器,并产生更新事件(TIMx->EGR = TIM_EGR_UG)加载寄存器,此事件标志 UIF 会被置位,在调用 HAL_TIM_Base_Start_IT( ) 启动定时器,在此使能定时器中断时,由于 UIF 已经置位,所以会立即触发并进入中断处理函数,中断回调函数会停止定时器计数,并禁止定时器中断;但当从中断处理函数返回继续执行HAL_TIM_Base_Start_IT( )时,此接口会使能定时器开始计数,进而在下一次调用HAL_TIM_Base_Start_IT( )时又会立即产生中断,循环往复,详细时序和具体代码如下: ! n( c- {4 u3 j9 E) B/ O
图4.问题产生时序描述
图5.定时器启动代码 B* ?1 F; k/ G% o2 h# y2 i6 |' ?, y04处理 修改代码,在启动定时器前强制停止定时器计数、清除中断位、清除 NVIC 挂起的中断后,再启动定时器,详见下图红框内代码; ' C1 w- q' A% L4 y- b- i . v+ j, k3 w( m5 c$ A' }4 e i
图6.问题修正代码 2 Y6 c) d& Y8 B
图7.修正 BUG 后的运行结果 8 j# F1 I0 b# J1 [ + N8 V7 u. l8 ^ 05小结8 l9 b- Z+ r8 S( A2 b+ v& _2 ] 在碰到这类定时器异常问题时,可以利用 I/O 口指示运行状态,结合代码分析找到原因并加以解决。& Z2 v" A/ ~& j5 {/ Z. u \ " h! \3 @0 A) d3 X. k! @ 转载自: STM32单片机 如有侵权请联系删除 ; U) L, E. p* ^% k |
【福利三:雨露均沾·逢7狂欢】之一:STM32F1外部中断异常故障的解决办法
经验分享 | 利用TIMER定时和捕获功能实现编解码演示
STM32 LSE 不起振排查指南:五大核心原因与快速解决方案
我心中的ST中文论坛
经验分享 | 利用STM32 TIMER实现同频跟随输出示例
2025软件工具兔哥知道
经验分享 | 利用STM32 TIMER实现同频跟随输出示例
经验分享 | 一个基于TIMER事件的中断响应话题_续
经验分享 | 一个基于TIMER事件的中断响应话题
11张图学会STM32定时器!
微信公众号
手机版