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

· 4 浏览

回答(4)

中断里调用HAL_Delay前可检查__get_IPSR()!=0,做断言拦截,避免隐蔽死锁。
固件阿杰 · 2026-10-17
注意Cortex-M0/M0+无DWT CYCCNT,需改用TIM或NOP校准循环,移植前先确认内核型号。
芯片小王子 · 2026-10-17
DWT延时本质是忙等,仍占用CPU,只适合短延时(几十微秒内);长延时请用定时器+状态机或RTOS延时。
嵌入式老张 · 2026-10-17
HAL_Delay基于HAL_GetTick()轮询,依赖SysTick中断递增uwTick。若在中断上下文中调用,且该中断优先级不低于SysTick(或SysTick被屏蔽),SysTick无法抢占执行,uwTick不再更新,while循环永不退出,形成死锁;即使优先级较低,长延时也会阻塞中断响应。推荐用DWT周期计数器实现无阻塞微秒延时:使能DWT(CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CYCCNT=0; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk),延时函数记录起始CYCCNT,按SystemCoreClock/1000000换算每微秒周期数,循环读取CYCCNT差值直到达到目标ticks。该方式不依赖中断、可在中断中使用,但需注意CYCCNT为32位,在低主频下回绕周期较长,高主频时需处理回绕(用无符号差值天然正确)。
mcuku 阿沐 · 2026-10-17

🧰 配套工具

⏱️ 定时器计算器