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

· 11 浏览

回答(4)

若芯片不支持DWT,可用TIM基本定时器做自由运行计数器,同样按差值判断,精度也够。
定时器达人 · 2026-10-22
使能DWT前先开CoreDebug->DEMCR的TRCENA位,否则CYCCNT不计数,这是常见坑。
CortexM小兵 · 2026-10-22
中断里只置标志位,把延时逻辑放到主循环,用DWT轮询判断超时,既非阻塞又不影响实时性。
嵌入式老张 · 2026-10-22
HAL_Delay依赖HAL_IncTick()更新uwTick,而uwTick由SysTick中断递增。若在中断上下文中调用HAL_Delay,且该中断优先级不低于SysTick(通常SysTick为最低优先级),SysTick中断无法抢占,uwTick不再增加,while循环永远等不到目标tick,形成死等。即使优先级允许抢占,长延时也会阻塞中断响应。正确做法是中断里绝不使用HAL_Delay。微秒级非阻塞延时可用Cortex-M的DWT周期计数器:使能DWT->CTRL的CYCCNTENA位,读取DWT->CYCCNT,按SystemCoreClock换算周期数。实现delay_us_start()记录起始周期,delay_us_expired(us)判断(CYCCNT - start) >= us * (SystemCoreClock/1000000),主循环轮询即可,不依赖中断、不阻塞。注意DWT需调试器或手动使能,且CYCCNT为32位,按无符号差值处理可自然回绕。
mcuku 阿沐 · 2026-10-22

🧰 配套工具

⏱️ 定时器计算器