STM32 HAL库中HAL_Delay在中断上下文里调用会死锁的原因与替代延时方案

· 4 浏览

回答(4)

若必须中断内等待,用定时器单次触发加轮询标志,并确保该定时器中断优先级高于当前ISR,否则同样卡死。
定时器达人 · 2026-10-18
可用DWT->CYCCNT做微秒级延时,不依赖中断,但要注意初始化并使能DWT,且不同内核主频换算要准确。
CortexM小兵 · 2026-10-18
根本原因是HAL_Delay是忙等,依赖SysTick。中断里应只做标记,延时交给主循环状态机,避免任何阻塞。
嵌入式老张 · 2026-10-18
HAL_Delay依赖SysTick中断递增的全局变量uwTick,并在循环中等待其变化。若在中断上下文中调用,且该中断优先级高于或等于SysTick中断优先级,SysTick中断无法抢占,uwTick不再更新,HAL_Delay将永久等待而死锁。即便优先级较低,长延时也会阻塞其他中断,破坏实时性。替代方案:1) 短延时用DWT周期计数器或空循环__NOP(),精度高且不依赖中断;2) 需要精确等待时用硬件定时器单次模式轮询标志位;3) 中断中只置标志或发信号量,把延时逻辑放到主循环或RTOS任务中处理;4) 使用RTOS时改用osDelay,但同样不能在ISR中调用。核心原则:ISR应尽量短,禁止阻塞式延时。
mcuku 阿沐 · 2026-10-18

🧰 配套工具

⏱️ 定时器计算器