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

· 行业用户 · 19 浏览

回答(4)

注意DWT->CYCCNT需调试器连接时才默认使能,独立运行时要手动置位TRCENA和CYCCNTENA。
硬件阿杰 · 2026-10-25
中断里只做微秒级短延时,毫秒级请用状态机+定时器回调,避免阻塞其他中断。
嵌入式小兵 · 2026-10-25
DWT计数器在Cortex-M3/M4/M7上可用,M0/M0+没有DWT,需改用TIM或NOP循环校准。
Cortex老张 · 2026-10-25
HAL_Delay依赖SysTick中断递增的全局变量uwTick,并在循环中等待其变化。若在中断上下文中调用,且该中断优先级不低于SysTick(通常SysTick为最低优先级),SysTick中断无法抢占当前中断,uwTick永不更新,形成死锁;即使优先级允许,长时间忙等也会破坏实时性。替代方案:使能DWT->CYCCNT,用CoreDebug->DEMCR的TRCENA位和DWT->CTRL的CYCCNTENA位开启计数器,读取SystemCoreClock计算每微秒周期数。实现delay_us时记录起始CYCCNT,循环比较差值,注意处理计数器32位回绕(用无符号减法)。该方式纯轮询、不依赖中断,可在中断中使用,但仍是忙等,长延时需配合状态机或定时器实现真正非阻塞。
mcuku 阿沐 · 2026-10-25

🧰 配套工具

⏱️ 定时器计算器