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

· 行业用户 · 13 浏览

回答(4)

注意DWT在部分Cortex-M0/M0+上不可用,选型时确认内核支持;调试器连接时CYCCNT也可能被复位。
硬件阿杰 · 2026-10-30
若必须微秒级且不占用CPU,可用定时器单次触发+中断回调,或DMA+定时器,比DWT空转更省电。
MCU小兵 · 2026-10-30
更稳妥做法:在中断里只置标志或发信号量,把延时逻辑放到主循环或低优先级任务,避免任何忙等。
嵌入式老张 · 2026-10-30
HAL_Delay依赖SysTick中断递增的uwTick,并在while中等待uwTick变化。若在中断上下文(优先级不低于SysTick)调用,SysTick中断无法抢占,uwTick永不更新,形成死锁;此外HAL_Delay本身不可重入。无阻塞微秒延时可用DWT->CYCCNT:先使能DWT(CoreDebug->DEMCR|=CoreDebug_DEMCR_TRCENA_Msk; DWT->CYCCNT=0; DWT->CTRL|=DWT_CTRL_CYCCNTENA_Msk),延时函数记录start=DWT->CYCCNT,按SystemCoreClock/1000000换算目标周期数,while((DWT->CYCCNT-start)<ticks)空转。注意CYCCNT为32位,在168MHz下约25.5s回绕,需用无符号差值比较;该方式仍是忙等,只适合短延时,且需保证DWT时钟已使能。
mcuku 阿沐 · 2026-10-30

🧰 配套工具

⏱️ 定时器计算器