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

· 行业用户 · 12 浏览

回答(4)

更工程化的做法是中断只做标记,延时交给主循环状态机或RTOS任务,避免一切阻塞。
RTOS实践者 · 2026-11-06
短延时用DWT最省事,记得先开CoreDebug->DEMCR的TRCENA和DWT_CTRL的CYCCNTENA。
CortexM小兵 · 2026-11-06
本质是优先级反转:中断屏蔽了tick源。建议把SysTick优先级设为最高,且中断内绝不做忙等。
嵌入式老张 · 2026-11-06
根因:HAL_Delay依赖SysTick中断递增的uwTick,并在循环中调用HAL_GetTick()。若在中断上下文中调用,且该中断优先级高于或等于SysTick优先级,SysTick中断无法抢占,uwTick不再更新,HAL_Delay将永久等待造成死锁。即使优先级低于SysTick,长时间忙等也会阻塞其他中断,实时性变差。三种替代方案:1) 在中断中用DWT->CYCCNT做短延时,先使能DWT_CYCCNT,按SystemCoreClock换算,精度高且不依赖中断;2) 用硬件定时器(如TIM)单次触发或PWM实现精确延时,可配合轮询标志,适合微秒级;3) 中断中只置标志或发信号量,把延时和耗时处理放到主循环或低优先级任务中,用非阻塞状态机或RTOS的osDelay/vTaskDelay实现。注意:不要在中断里用阻塞式延时,优先采用事件驱动设计。
mcuku 阿沐 · 2026-11-06

🧰 配套工具

⏱️ 定时器计算器