01引言 某客户设计需要启动定时器在 3ms 后产生中断,其后定时器不再运行,直至下一次软件要求再次启动定时器产生中断,实测代码后发现定时器启动后立即产生了超时中断。 02调研 客户通过 STM32CubeMX 配置 TIM7 并生成工程,在主循环中添加定时器启动代码;在定时器中断处理函数处理 update event 回调时停止定时器,并翻转一个 I/O 脚指示定时器启停,代码如下: ! {! E. u% }! K L. R7 J ; p, E5 N' x9 E, L3 W( Z 图1.启动定时器 图2.定时器中断回调 ; n6 d# L$ ~- T' b客户期待的结果是启动定时器时 I/O 拉高并保持 3ms,当 3ms 到达后产生中断拉低I/O,但实测时发现,定时器启动后立即产生了超时中断(高电平持续时间约 2us): 图3.实测结果 9 D0 _! A8 m) Q) X03分析3 R$ a- I* K5 p% I% C* a' x. K 应用代码在初始化定时器时会调用 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( )时又会立即产生中断,循环往复,详细时序和具体代码如下:6 U+ k4 s/ \4 [# d4 c 4 s! K0 d: r5 V- x. e, m ! |7 {; T& v6 o2 f 图4.问题产生时序描述 8 X. o4 ?* Z, r7 `1 t% ]& L 图5.定时器启动代码 3 ] P1 h3 A2 T' Y* N1 B04处理; |; |4 K- @* R1 k' { 修改代码,在启动定时器前强制停止定时器计数、清除中断位、清除 NVIC 挂起的中断后,再启动定时器,详见下图红框内代码;& @. q% A0 u V' a7 s9 E* a 8 B# ^# d& `* L m1 D N; \' Z 图6.问题修正代码 3 g- a( k" f* d; R; k 图7.修正 BUG 后的运行结果 1 j% h& `9 ?9 f& W7 u, S + _1 t( d4 O9 A& ]' e: C( j4 w4 P) K0 n 05小结 在碰到这类定时器异常问题时,可以利用 I/O 口指示运行状态,结合代码分析找到原因并加以解决。 转载自: STM32单片机' _/ ~. `. u+ L. ^ 如有侵权请联系删除 0 y. h4 ^+ b+ P1 i/ h . h( t; s0 _. }' v: `6 }8 L2 y 0 p( ]! Z# K9 A* f/ L; j& N: w |
狂欢三】STM32C031使用TIM定时器DMA方式实现WS2812彩灯输出(三)
【狂欢三】STM32C031使用TIM定时器DMA方式实现PWM输出(二)
【狂欢三】STM32C031使用TIM定时器PWM输出
stm32使用定时器触发dma传输,启动dma没反应的几种情况的解决方法
基于STM32串口中断之缓存区溢出卡死经验分享
基于STM32数组越界异常中断经验分享
基于STM32之数组越界异常中断经验分享
定时器剩余通道是否可以做PWM输出呢?
基于STM32连接参数更新进程后导致断连的问题分析
基于STM32连接参数更新进程后导致断连的问题分析