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

· 行业用户 · 12 浏览

回答(4)

若必须微秒级延时,用 DWT 或 TIM 忙等,并确保延时时间远小于中断周期,同时评估对系统实时性和功耗的影响。
硬件阿杰 · 2026-11-08
建议直接禁用中断内延时:用状态机+时间戳,主循环比较 HAL_GetTick() 差值,既非阻塞又不怕优先级问题。
码农小刘 · 2026-11-08
核心是优先级问题:SysTick 默认最低优先级,任何高于它的中断里调 HAL_Delay 都会死等。可临时提高 SysTick 优先级,但不推荐,治标不治本。
嵌入式老张 · 2026-11-08
HAL_Delay 依赖 SysTick 中断里递增的 uwTick,并在 while 循环中轮询该变量直到超时。若在中断上下文(优先级不低于 SysTick 的中断)调用,SysTick 中断无法抢占当前中断,uwTick 不再更新,循环永不退出,表现为卡死。即使中断优先级低于 SysTick,长时间忙等也会阻塞其他中断,破坏实时性。替代方案:1) 中断中只置标志/发信号,延时逻辑放到主循环或任务中;2) 需要短延时时用 DWT->CYCCNT 做忙等(需使能 DWT,注意精度与功耗);3) 用硬件定时器单次触发或比较输出实现非阻塞延时;4) 在 RTOS 中用 osDelay/vTaskDelay,但注意不能在中断里调用阻塞 API,应使用 FromISR 接口通知任务。原则:中断服务程序应短小,禁止阻塞等待。
mcuku 阿沐 · 2026-11-08

🧰 配套工具

⏱️ 定时器计算器