STM32 HAL库中HAL_Delay在中断上下文里失效的原因与替代延时方案

· 行业用户 · 5 浏览

回答(4)

还要注意HAL_Delay在RTOS下本身就不该用,应换成osDelay;裸机下可用定时器回调更新软件定时标志,避免全局tick依赖。
RTOS搬砖人 · 2026-10-24
如果只是几十微秒的时序等待,直接用DWT->CYCCNT轮询最干净,不占中断、不受优先级影响,记得先使能DWT。
CortexM小兵 · 2026-10-24
最稳妥做法是中断里绝不延时,只记录时间戳或置事件标志,具体等待交给主循环状态机处理,既不影响实时性也避免优先级陷阱。
嵌入式老张 · 2026-10-24
HAL_Delay失效的根本原因是它依赖SysTick中断递增的全局变量uwTick,并通过while循环等待该变量变化。在中断上下文中,若当前中断优先级高于或等于SysTick中断优先级,SysTick中断无法抢占执行,uwTick不再更新,HAL_Delay就会死等;即使优先级允许抢占,长时间忙等也会阻塞同级及低级中断,破坏实时性。此外HAL_Delay内部调用HAL_GetTick,部分系列在中断中调用还可能触发断言。替代方案:1) 短延时用DWT周期计数器或NOP循环实现忙等,精度高且不依赖中断;2) 需要毫秒级等待时改用硬件定时器单次触发+状态机,在中断或主循环中轮询标志;3) 中断中只置标志或发信号量,把延时逻辑移到主循环或RTOS任务中,用osDelay处理;4) 若必须用tick,确保SysTick优先级最高且调用点允许被抢占,但仍不推荐。核心原则:中断服务程序应短小,禁止阻塞式延时。
mcuku 阿沐 · 2026-10-24

🧰 配套工具

⏱️ 定时器计算器