01引言5 ~6 i" T3 e3 N' I/ j+ b- O 某客户设计需要启动定时器在 3ms 后产生中断,其后定时器不再运行,直至下一次软件要求再次启动定时器产生中断,实测代码后发现定时器启动后立即产生了超时中断。8 @8 [" I+ u+ P' J' w( L1 b 02调研' o4 ~! |; d* N O; q/ r. ~ 客户通过 STM32CubeMX 配置 TIM7 并生成工程,在主循环中添加定时器启动代码;在定时器中断处理函数处理 update event 回调时停止定时器,并翻转一个 I/O 脚指示定时器启停,代码如下:. n/ m( V9 |; o$ E 图1.启动定时器 图2.定时器中断回调 客户期待的结果是启动定时器时 I/O 拉高并保持 3ms,当 3ms 到达后产生中断拉低I/O,但实测时发现,定时器启动后立即产生了超时中断(高电平持续时间约 2us): : `' w& x( f. L' m" ` . H& a& ^2 v- S) o1 X9 C 图3.实测结果 4 }. d' d; x% x a9 N& Y03分析! J3 [- h6 y: C- U3 H0 r 应用代码在初始化定时器时会调用 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( )时又会立即产生中断,循环往复,详细时序和具体代码如下: " h2 C4 M3 k% t; y; N& |2 _ ! S( M1 u2 m5 Z6 k% R6 h 图4.问题产生时序描述 ; q$ t4 a" f ] 图5.定时器启动代码 $ \( @' _( Y5 o* y, ]% }- a S6 ~$ V; t& W8 N) v) h" z 04处理) A- X6 { v1 G/ a- x 修改代码,在启动定时器前强制停止定时器计数、清除中断位、清除 NVIC 挂起的中断后,再启动定时器,详见下图红框内代码; 图6.问题修正代码 图7.修正 BUG 后的运行结果 ; J3 D5 @& ?% e, d. U. D* T $ _$ S! ^" K+ x* A+ s2 \ ! _) o. X# [# J0 l) c$ x, H$ t6 L 05小结4 z+ J4 O/ Q( w Z 在碰到这类定时器异常问题时,可以利用 I/O 口指示运行状态,结合代码分析找到原因并加以解决。0 g, p* [, U% T5 W: M& m$ `( E& S 1 K9 h% G4 z1 p: V& T3 o' d! ^6 v $ F% v$ k) | W+ u, T& ~ 转载自: STM32单片机 g! C$ m6 l! X 如有侵权请联系删除 . O/ o/ j" A% |# i 8 V( z2 f7 o- Z( U |
基于STM32串口中断之缓存区溢出卡死经验分享
基于STM32数组越界异常中断经验分享
基于STM32之数组越界异常中断经验分享
定时器剩余通道是否可以做PWM输出呢?
基于STM32连接参数更新进程后导致断连的问题分析
基于STM32连接参数更新进程后导致断连的问题分析
基于STM32双定时器+ADC+DMA实战经验分享
基于STM32的定时器触发ADC时可能遇到的情形
【NUCLEO-U545RE-Q评测】5. 基本计时器
基于stm32用两个16位定时器级联成32位定时器经验分享