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

· 行业用户 · 7 浏览

回答(4)

注意HAL_Delay在RTOS下也应避免,建议用osDelay让出CPU;裸机中断内则用DWT方案最稳。
RTOS实践者 · 2026-11-14
若芯片不支持DWT(如部分Cortex-M0),可用TIM做单次计数查询,或直接用循环计数配合示波器校准。
MCU小兵 · 2026-11-14
补充一点:DWT延时是忙等,会阻塞同优先级及以下中断,中断里尽量只延时几微秒,长延时改用状态机或定时器。
嵌入式老张 · 2026-11-14
HAL_Delay依赖SysTick中断递增的uwTick全局变量,其实现是while((HAL_GetTick()-tickstart)<wait)空转。若在中断上下文中调用,且该中断优先级高于或等于SysTick中断(默认最低优先级),SysTick中断无法抢占,uwTick不再更新,循环条件永远成立,形成死等。即便优先级较低,长时间阻塞也会破坏实时性。替代方案:使能DWT->CYCCNT,先置CoreDebug->DEMCR的TRCENA位,再置DWT->CTRL的CYCCNTENA位,读取SystemCoreClock计算每微秒周期数。delay_us实现为记录起始CYCCNT,while((DWT->CYCCNT-start)<us*cyclesPerUs)空转,注意处理32位计数器回绕(用无符号减法天然正确)。该方式不依赖中断,可在中断中安全使用,精度达CPU周期级。使用前需确保调试组件时钟已开,且不要在低功耗模式下依赖它。
mcuku 阿沐 · 2026-11-14

🧰 配套工具

⏱️ 定时器计算器