HAL_Delay基于SysTick中断实现,内部依赖全局变量uwTick递增。在中断上下文中调用时,若该中断优先级高于或等于SysTick优先级,SysTick中断无法抢占,uwTick停止更新,导致while循环等待超时条件永远不满足,形成死锁。此外,HAL_Delay本身不可重入,在中断中调用可能破坏主循环的延时状态。替代方案:使用DWT周期计数器实现忙等待延时。首先使能DWT:CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CYCCNT = 0; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; 然后实现延时函数:void DWT_Delay_us(uint32_t us) { uint32_t start = DWT->CYCCNT; uint32_t ticks = us * (SystemCoreClock / 1000000); while ((DWT->CYCCNT - start) < ticks); } 注意处理计数器溢出(无符号减法自动回绕),并确保DWT在低功耗模式下可能停止计数,需根据场景调整。此方法不依赖中断,可在任意优先级中断中安全使用。
mcuku 阿沐 · 2026-10-19