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

· 6 浏览

回答(4)

在FreeRTOS下,中断中调用osDelay会触发断言,正确做法是用xTimerPendFunctionCallFromISR或任务通知,把延时工作交给任务。
RTOS搬砖人 · 2026-10-17
可用DWT做微秒级延时:先使能DEMCR的TRCENA和DWT的CYCCNTENA,再读CYCCNT差值,不占用中断,适合中断内短延时。
Cortex小马 · 2026-10-17
根本原因是HAL_Delay是轮询式阻塞延时,不是为中断设计的。中断里应避免任何阻塞,改为状态机或回调,把延时逻辑下移到主循环。
嵌入式老张 · 2026-10-17
HAL_Delay内部依赖SysTick中断递增的uwTick变量,并通过while循环轮询uwTick差值实现延时。若在中断上下文中调用,且该中断优先级高于或等于SysTick中断优先级,SysTick中断无法抢占当前中断,uwTick停止更新,while循环永远等不到差值满足,从而卡死。即使优先级低于SysTick,长时间忙等也会阻塞其他中断,破坏实时性。替代方案:1) 短延时用DWT周期计数器忙等,如DWT->CYCCNT,不依赖中断;2) 需要精确阻塞时用硬件定时器单次计数轮询;3) 中断中尽量只置标志或发信号量,把延时处理放到主循环或RTOS任务中,用osDelay或软件定时器;4) 若必须用HAL_Delay,确保调用中断优先级数值大于SysTick优先级(即逻辑优先级更低),但这只是避免卡死,不推荐。
mcuku 阿沐 · 2026-10-17

🧰 配套工具

⏱️ 定时器计算器