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

· 行业用户 · 2 浏览

回答(4)

RTOS下ISR里用osDelay会断言失败,应使用osMessagePut或任务通知,把延时交给任务处理。
RTOS搬砖人 · 2026-10-28
用DWT->CYCCNT做us级延时最稳,记得先开CoreDebug->DEMCR的TRCENA和DWT->CTRL的CYCCNTENA。
CortexM小兵 · 2026-10-28
补充:可把SysTick优先级设为最高,但HAL_Delay仍会阻塞同优先级以下中断,不推荐在ISR中使用。
嵌入式老张 · 2026-10-28
根因是HAL_Delay依赖SysTick中断递增的全局变量uwTick,并通过HAL_IncTick在SysTick_Handler中更新。若在中断上下文调用HAL_Delay,而当前中断优先级不低于SysTick(通常SysTick为最低优先级),SysTick中断无法抢占,uwTick不再递增,HAL_Delay会死等超时。即使优先级允许,长时间忙等也会阻塞其他中断,破坏实时性。替代方案:1) 短延时用DWT周期计数器忙等,如DWT->CYCCNT,需先使能DWT;2) 用硬件定时器做单次延时或状态机,避免阻塞;3) 中断中只置标志/发信号,把延时逻辑放到主循环或RTOS任务,用vTaskDelay或软件定时器;4) 若必须阻塞,用__NOP循环校准的忙等,但需评估中断延迟。注意不要在中断里调用带互斥的HAL函数。
mcuku 阿沐 · 2026-10-28

🧰 配套工具

⏱️ 定时器计算器