STM32F411CEU6中断中调用HAL_GetTick致uwTick停滞求助
STM32 UART中断内HAL_GetTick停滞问题分析与解决
可能的原因
- 中断优先级实际配置不符:CubeIDE界面显示SysTick优先级更高,但实际代码里可能存在配置偏差。SysTick的优先级由
HAL_NVIC_SetPriority(SysTick_IRQn, x, y)设置,UART中断由HAL_NVIC_SetPriority(USART1_IRQn, a, b)设置。如果UART的**抢占优先级(a)**数值比SysTick的(x)小(数值越小优先级越高),或抢占优先级相同但子优先级配置导致SysTick无法抢占,那么UART中断执行期间,SysTick中断无法触发,uwTick自然不会递增,表现为停滞。 - UART中断执行时间过长:哪怕SysTick优先级更高,如果UART中断里的代码执行时间超过了SysTick的定时周期(比如SysTick设为1ms,中断代码跑了1.5ms),这段时间内SysTick还没来得及触发,uwTick也会停止更新。
- HAL库中断屏蔽影响:
HAL_UART_IRQHandler执行过程中,可能会临时调用__disable_irq()关闭全局中断,后续恢复时如果出现异常,或者你的自定义代码在中断屏蔽未完全恢复的阶段执行,会导致SysTick中断无法响应。
是否需要改用定时器计时方案?
如果上述问题难以排查或修复,改用定时器读取计数器的方案是可靠的替代方案,优势如下:
- 定时器计数器是硬件独立运行的,不受中断嵌套、屏蔽的影响,计时更稳定。
- 不依赖SysTick中断,彻底规避优先级相关问题。
- 可灵活配置分频和计数周期,适配不同精度需求(比如us级或ms级计时)。
实现思路:
- 选一个空闲通用定时器(如TIM2),配置为向上计数模式,设置合适分频系数让计数器按预期步长递增(比如分频后每1us计数1次)。
- 直接读取
TIMx->CNT寄存器获取计数值,或封装成类似HAL_GetTick的函数返回。
如果想继续用HAL_GetTick,可以尝试以下修复:
- 核对
MX_NVIC_Init()中的优先级配置,确保SysTick的抢占优先级高于UART。比如设置HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0)(抢占优先级0为最高),UART1的抢占优先级设为1或更高数值。 - 精简UART中断内的自定义代码,把耗时操作(如数据处理、打印)移到主循环,中断只做接收缓存和标记,缩短中断执行时间。
- 检查
HAL_UART_IRQHandler执行前后的中断状态,必要时在自定义代码前手动调用__enable_irq()(需确认不会引发其他问题),确保SysTick中断能正常触发。
内容的提问来源于stack exchange,提问作者Electromosaw
相关产品推荐
相关产品推荐

