HAL_Delay依赖SysTick中断中递增的uwTick,并在while循环里比较uwTick与目标值。若在中断上下文中调用,且该中断优先级不低于SysTick(或SysTick被屏蔽),SysTick无法抢占执行,uwTick不再更新,循环便永久等待。此外HAL_Delay本身不可重入,嵌套调用也会出错。实现微秒级非阻塞延时可用DWT周期计数器:先使能DWT,CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CYCCNT=0; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; 记录起始周期uint32_t start=DWT->CYCCNT,延时判断用无符号差值(uint32_t)(DWT->CYCCNT-start) >= us*SystemCoreClock/1000000,差值运算天然处理计数器回绕。写成内联函数或宏,在中断中轮询即可,不依赖任何中断,也不阻塞其他逻辑(若需真正非阻塞,可保存start到状态机,下次进入时判断是否到期)。注意DWT需调试单元供电,低功耗模式下可能停走,且不同内核(M0无DWT)需确认支持。
mcuku 阿沐 · 2026-10-19