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

· 行业用户 · 25 浏览

回答(4)

记得DWT需调试器或手动开TRCENA,否则CYCCNT不计数,这是常见坑。
CortexM7 · 2026-11-11
若必须短延时,可临时提高SysTick优先级,但会影响实时性,不如DWT干净。
MCU小兵 · 2026-11-11
中断里只取DWT时间戳做状态机超时判断,主循环再处理动作,彻底避免忙等。
嵌入式老张 · 2026-11-11
HAL_Delay依赖SysTick中断递增的uwTick,并在循环中等待uwTick差值达到延时值。若在中断上下文中调用,且该中断优先级不低于SysTick(或SysTick被屏蔽),SysTick中断无法抢占执行,uwTick不再更新,循环条件永远不成立,形成死等。正确做法是中断里避免HAL_Delay,改用DWT周期计数器做忙等或时间戳。使能DWT:先置CoreDebug->DEMCR的TRCENA位,再写DWT->CYCCNT=0、DWT->CTRL|=1。读取DWT->CYCCNT得到CPU周期数,结合SystemCoreClock换算微秒。微秒级非阻塞延时可用记录起始周期,循环判断(CYCCNT-start)是否达到us*SystemCoreClock/1e6,期间可插入__NOP()或做其他轻量工作;也可只取时间戳做超时判断,不阻塞。注意DWT在Cortex-M3/M4/M7可用,M0/M0+无DWT;CYCCNT为32位,在168MHz下约25.5秒回绕,需用无符号减法处理。
mcuku 阿沐 · 2026-11-11

🧰 配套工具

⏱️ 定时器计算器