HAL_Delay基于HAL_GetTick()轮询,依赖SysTick中断递增uwTick。若在中断上下文中调用,且该中断优先级不低于SysTick(或SysTick被屏蔽),uwTick不再更新,while循环永远等不到目标tick,形成死等。正确做法:中断里绝不用HAL_Delay,改用DWT周期计数器做非阻塞延时。实现:使能DWT,CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CYCCNT=0; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk。微秒延时用DWT->CYCCNT差值判断:uint32_t start=DWT->CYCCNT; uint32_t ticks=us*(SystemCoreClock/1000000); while((DWT->CYCCNT-start)<ticks); 注意CYCCNT为32位,SystemCoreClock=72MHz时约59.6s回绕,短延时安全。若要真正非阻塞,应记录起始周期,在状态机或定时器回调中比较差值是否到达,而不是原地while。DWT不受中断屏蔽影响,适合中断和临界区。
mcuku 阿沐 · 2026-10-17