[STM32L4] 如何配置 SysTick微妙级延时

[复制链接]
80|31
olivem55arlowe 发表于 2026-7-18 21:22 | 显示全部楼层
如何计算微秒对应的时钟周期?              
uptown 发表于 2026-7-18 21:58 | 显示全部楼层
延时过长可能导致计算出的ticks超出LOAD寄存器的最大值。例如72MHz下,单次最大约1.86秒
wailian1265k 发表于 2026-7-18 23:16 | 显示全部楼层
每微秒触发一次中断,这意味着CPU每秒要进一百万次中断。对于STM32L4来说,光是进出中断的开销(压栈出栈)可能就要几十个周期,这会导致你的主循环几乎跑不动,系统效率极低。如果不是非要靠中断计数,强烈建议用DWT的CYCCNT寄存器做轮询延时,那个精度够且不占CPU资源
大鹏2365 发表于 2026-7-19 08:23 | 显示全部楼层
如果你一定要用中断方式,记得把SysTick的优先级设为最高(数值最小),比如0。因为SysTick是内核外设,它的优先级配置和普通外设不一样,要用SCB->SHP寄存器或者直接调CMSIS的接口。另外,中断服务函数里千万别调HAL_Delay或者其他会挂起的函数,否则必死锁
sesefadou 发表于 2026-7-19 10:27 | 显示全部楼层
若需毫秒级延时,可通过循环调用微秒延时函数实现。
jackcat 发表于 2026-7-19 11:47 | 显示全部楼层
若使用中断方式实现延时,注意SysTick中断优先级不应低于其他关键中断,以免影响延时精度或导致其他中断响应延迟。
xiyaoko2365 发表于 2026-7-19 12:02 | 显示全部楼层
其实HAL库里有个HAL_Delay_us的弱定义函数(部分新版本支持),你可以重写它。底层直接用DWT计数器实现,这样既保留了HAL_Delay的微秒版本,又不用去动SysTick的配置,避免了和系统时基冲突。这是最稳妥的改法,兼容性也好
bartonalfred 发表于 2026-7-19 12:38 | 显示全部楼层
延时函数中如何避免中断干扰?              
zerorobert 发表于 2026-7-19 13:17 | 显示全部楼层
需明确SysTick的时钟源。              
i1mcu 发表于 2026-7-19 14:03 | 显示全部楼层
配置时钟源的具体步骤是什么?              
21mengnan 发表于 2026-7-19 16:17 | 显示全部楼层
延时函数用查询 COUNTFLAG,如果打开中断,SysTick 中断会打断阻塞等待,延时完全失效。
caoyunhj2301 发表于 2026-7-19 21:39 | 显示全部楼层
关于你说的卡死问题,除了优先级,还要检查是不是在中断里做了耗时操作。微秒级中断频率太高,如果ISR里稍微多几条指令,下一次中断就来了,导致堆栈溢出或者看门狗复位。建议把延时逻辑做成非阻塞的,或者干脆别用中断,直接用定时器PWM模式或者输入捕获模式去测时间
王派oo 发表于 2026-7-20 09:28 | 显示全部楼层
STM32L4的主频如果是80MHz或更高,一个机器周期才十几纳秒。你用SysTick做微秒延时,精度受限于中断响应延迟(Jitter)。对于要求不高的场合够用,但如果要精确控制时序,还是得用硬件定时器TIM。TIM可以配置成单脉冲模式,启动后自动计数,不需要CPU干预,精度比SysTick高得多
怎么总是重复啊 发表于 2026-7-20 13:24 | 显示全部楼层
解决办法是不调用SysTick_Config,而是直接写SysTick->LOAD和SysTick->VAL寄存器。配置完寄存器后,再手动使能SysTick。这样HAL_InitTick就不会干扰你的配置了。不过要注意,改了SysTick后,HAL_Delay毫秒级延时就不准了,需要自己重写毫秒级的基准
lxs0026 发表于 2026-7-21 10:30 | 显示全部楼层
楼主要注意,SysTick是24位计数器。如果你系统时钟是168MHz,想配1微秒中断,重装值就是168,这没问题。但如果系统时钟更高,或者你想配更短的时间,可能会溢出或者精度不够。而且频繁进中断会导致Cache命中率下降(如果L4带Cache的话),整体性能反而会降
grfqq325 发表于 2026-7-22 12:42 | 显示全部楼层
如果是为了驱动某些对时序敏感的传感器,比如DHT11或者单总线设备,别用SysTick中断。直接用GPIO模拟,中间穿插几个NOP或者简单的for循环延时就行。这种微秒级延时在关中断的情况下跑最稳,开了中断反而会被打断导致时序错乱
突然下起雨 发表于 2026-7-22 15:52 | 显示全部楼层
还有一个思路,用TIM6或TIM7这种基本定时器。它们可以产生更新中断,而且不占用IO口。你把定时器配成1微秒溢出,中断优先级设高。这样既不影响SysTick作为系统时基,又能实现你的微秒级触发需求。只是记得中断里只做标志位翻转,具体逻辑放主循环处理
天天向善 发表于 2026-7-24 22:48 | 显示全部楼层
在延时函数中,可以通过禁用中断或者使用中断服务例程(ISR)来避免中断干扰。
lllook 发表于 2026-7-27 12:01 | 显示全部楼层
微秒是时间单位,时钟周期是时钟频率的倒数,将微秒数乘以时钟频率,得到周期数。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部
0