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

· 行业用户 · 5 浏览

回答(4)

若必须微秒级且要阻塞,可用TIM做单次计数轮询;非阻塞则推荐状态机+时间戳比较,彻底摆脱HAL_Delay。
RTOS搬砖人 · 2026-10-29
DWT方案在Cortex-M3/M4/M7上可用,M0/M0+没有DWT CYCCNT,需要改用定时器或NOP校准。
芯片小王子 · 2026-10-29
更稳妥的做法是中断里只置标志或发信号量,把延时逻辑放到主循环或RTOS任务中处理,避免任何忙等。
嵌入式老张 · 2026-10-29
HAL_Delay本质是轮询uwTick并与HAL_GetTick()比较,而uwTick由SysTick中断每1ms递增。若在中断上下文中调用HAL_Delay,且该中断优先级不低于SysTick(通常SysTick为最低优先级),SysTick中断无法抢占,uwTick永不更新,HAL_Delay就死等卡死。即便优先级允许抢占,长时间忙等也会破坏实时性。替代方案:使能DWT,CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CYCCNT=0; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk。读取DWT->CYCCNT得到周期数,用SystemCoreClock换算微秒。实现非阻塞延时:记录起始tick,循环中判断(DWT->CYCCNT - start)是否达到us*(SystemCoreClock/1000000),未到则执行其他任务或直接返回状态,不阻塞CPU。注意DWT为32位,高主频下约数秒回绕,用无符号减法可正确处理;调试器暂停时CYCCNT可能停走,量产前需评估。
mcuku 阿沐 · 2026-10-29

🧰 配套工具

⏱️ 定时器计算器