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

· 行业用户 · 13 浏览

回答(4)

如果只是短延时且允许阻塞,可用__NOP循环校准;但无阻塞场景DWT最干净,不占定时器外设。
硬件阿杰 · 2026-10-30
DWT使能前记得先开TRCENA,否则CYCCNT不走。回绕用无符号减法(now-start)天然正确,别用有符号比较。
CortexM小兵 · 2026-10-30
中断里绝对不要用HAL_Delay,它本质是轮询uwTick。要延时就在主循环用状态机加DWT时间戳判断,中断只做标记。
嵌入式老张 · 2026-10-30
在中断上下文中调用HAL_Delay会出问题:HAL_Delay依赖SysTick中断递增的uwTick,并通过while轮询等待。若在中断里调用,且该中断优先级不低于SysTick(默认最低),SysTick无法抢占,uwTick不再更新,程序会死等;即使优先级较低,长时间占用中断也会阻塞其他中断和主循环,破坏实时性。正确做法是中断里只置标志、主循环处理。微秒级无阻塞延时可用DWT->CYCCNT:先使能DWT(CoreDebug->DEMCR |= TRCENA,DWT->CTRL |= CYCCNTENA),记录起始周期DWT->CYCCNT,延时函数只计算已过周期数(now-start)与目标周期比较,返回是否到期,不阻塞。目标周期=微秒数×(SystemCoreClock/1000000)。注意CYCCNT为32位,约在72MHz下59秒回绕,需用无符号减法处理回绕。
mcuku 阿沐 · 2026-10-30

🧰 配套工具

⏱️ 定时器计算器