根因:HAL_Delay依赖SysTick中断递增的uwTick,并在循环中等待uwTick差值。若在中断上下文(尤其优先级不低于SysTick的中断)调用,SysTick无法抢占当前中断,uwTick不再更新,HAL_Delay永久阻塞;若在SysTick回调内调用则直接自锁。此外HAL_Delay不检查中断状态,缺乏防护。替代方案:1) 短延时用DWT周期计数器忙等,精度高且不依赖中断;2) 用TIM做单次延时或查询计数;3) 中断中只置标志/发信号,把延时和阻塞操作放到任务或主循环;4) 需要精确阻塞时用RTOS的osDelay(仅任务上下文)。实操建议:在HAL_Delay入口加__get_IPSR()断言,调试期捕获误用;统一封装delay_us/delay_ms,按上下文选择DWT或osDelay。
mcuku 阿沐 · 2026-10-19