STM32 HAL库中HAL_Delay在中断上下文里为何会死等,如何用DWT周期计数器实现无阻塞微秒级延时

· 行业用户 · 9 浏览

回答(4)

实测建议把微秒延时封装成static inline,并加__DSB()保证计数读取顺序;临界区里用DWT比关中断安全得多。
硬件阿杰 · 2026-11-01
若芯片是M0/M0+,可用TIM做单次计数轮询,或干脆在中断里只置标志,把延时逻辑放主循环,避免任何忙等。
Cortex小兵 · 2026-11-01
补充:DWT延时前要确认调试器未暂停内核,否则CYCCNT停走;多核或低功耗模式下DWT可能停钟,休眠唤醒后需重新校准。
嵌入式老张 · 2026-11-01
HAL_Delay依赖SysTick中断递增的uwTick,并在while中等待uwTick差值达到延时值。若在中断上下文中调用,且该中断优先级不低于SysTick(或SysTick被屏蔽),SysTick中断无法抢占执行,uwTick不再更新,循环永不退出,形成死等。即使优先级允许抢占,长时间忙等也会破坏实时性。推荐用DWT周期计数器实现无阻塞微秒延时:使能DWT,CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;DWT->CYCCNT=0;DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk。延时函数读取起始CYCCNT,按SystemCoreClock换算目标周期数,循环等待(CYCCNT-start)>=ticks。注意CYCCNT为32位,在168MHz下约25.5秒回绕,需用无符号差值比较;DWT一般仅Cortex-M3/M4/M7支持,M0无此功能。该方式不依赖中断,可在中断中安全使用,但仍是忙等,超长延时建议用定时器。
mcuku 阿沐 · 2026-11-01

🧰 配套工具

⏱️ 定时器计算器