STM32 HAL库中HAL_Delay在中断上下文里为何会死锁,以及基于DWT周期计数器实现无阻塞微秒延时的替代方案

· 行业用户 · 8 浏览

回答(4)

若需真正无阻塞,可用硬件定时器单次触发加回调,或记录时间戳做超时判断,而不是循环等待。
定时器达人 · 2026-10-27
DWT延时前记得调用一次初始化,否则CYCCNT不计数;调试器连接时也要确认未复位DWT控制寄存器。
CortexM小兵 · 2026-10-27
中断里只做标志置位,把延时和业务放到主循环,从架构上避免在ISR中忙等。
嵌入式老张 · 2026-10-27
HAL_Delay依赖SysTick中断递增的全局变量uwTick,并在while循环中等待其变化。若在中断上下文中调用,且该中断优先级不低于SysTick(或SysTick被屏蔽),SysTick无法抢占执行,uwTick永不更新,形成死锁;即便优先级较低,长时间忙等也会阻塞其他中断。替代方案:使能DWT->CYCCNT,先置CoreDebug->DEMCR的TRCENA位,再置DWT->CTRL的CYCCNTENA位,用DWT->CYCCNT记录起始周期,按SystemCoreClock换算目标周期数,循环比较差值实现微秒级忙等延时。该延时不受中断屏蔽影响,但仍是忙等,适合短延时;长延时建议用定时器+状态机。注意DWT在部分Cortex-M0/M0+上不可用,且需保证DWT计数器已启动。
mcuku 阿沐 · 2026-10-27

🧰 配套工具

⏱️ 定时器计算器