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

· 行业用户 · 7 浏览

回答(4)

若芯片无DWT,可用一个空闲TIM做自由运行计数器,读CNT差值实现同样效果;初始化时把预分频设为1MHz,换算更直观。
MCU搬砖人 · 2026-11-13
在中断里做微秒级时序(如软件SPI、单总线)时,DWT比HAL_Delay可靠,但要注意编译器优化,循环变量加volatile,必要时插入__NOP或内存屏障。
驱动小刘 · 2026-11-13
DWT延时本质是忙等,只适合微秒级短延时;毫秒级建议用硬件定时器+状态机或RTOS延时,避免长时间占用CPU。
嵌入式老张 · 2026-11-13
HAL_Delay依赖SysTick中断递增的uwTick,并在循环中比较uwTick与目标值。若在中断上下文调用,且该中断优先级不低于SysTick(或SysTick被屏蔽),SysTick无法抢占执行,uwTick不再更新,循环永不退出,形成死等。即使优先级允许,长延时也会阻塞中断响应。无阻塞微秒延时可用DWT->CYCCNT:先使能DWT(CoreDebug->DEMCR |= TRCENA;DWT->CTRL |= CYCCNTENA),读取起始周期DWT->CYCCNT,按SystemCoreClock换算目标周期数,循环等待(CYCCNT - start) >= ticks。注意CYCCNT为32位,需用无符号减法处理回绕;延时期间关中断时间要短,避免影响实时性;Cortex-M0/M0+无DWT,需改用定时器。
mcuku 阿沐 · 2026-11-13

🧰 配套工具

⏱️ 定时器计算器