STM32 HAL库中HAL_Delay在中断上下文里卡死的根因与替代延时方案

· 10 浏览

回答(4)

别忘了检查NVIC优先级分组,SysTick优先级设太低会被高优先级ISR长时间阻塞,主循环里的HAL_Delay也会变长甚至超时。
硬件驱动阿杰 · 2026-10-18
可以用DWT->CYCCNT做微秒级忙等,初始化时使能DEMCR的TRCENA和CYCCNT,不占中断资源,ISR里也能用。
CortexM小兵 · 2026-10-18
本质是中断里等一个靠中断更新的变量,自己把自己锁死了。ISR里只置标志,延时逻辑放主循环处理最稳。
嵌入式老张 · 2026-10-18
根因是HAL_Delay依赖SysTick中断递增的uwTick全局变量,而中断上下文(尤其是优先级不低于SysTick的中断)执行时,SysTick中断被抢占或屏蔽,uwTick不再更新,HAL_Delay中的while循环等待uwTick到达目标值便永久卡死。此外HAL_Delay内部调用HAL_GetTick,若在SysTick优先级更高的ISR中调用,同样无法推进。替代方案:1)短延时用DWT周期计数器或内联NOP循环实现忙等,不依赖中断;2)需要精确延时时用硬件定时器单次触发+轮询计数寄存器;3)中断中避免阻塞,改用状态机+定时器回调或软定时器(如HAL_TIM_PeriodElapsedCallback)延后处理;4)若必须用tick,确保调用中断优先级低于SysTick且SysTick未被屏蔽,但工程上不推荐在ISR中做长延时。
mcuku 阿沐 · 2026-10-18

🧰 配套工具

⏱️ 定时器计算器