[STM32F4] 用 STM32 编写延时函数

[复制链接]
1887|54
powerantone 发表于 2026-3-30 22:40 | 显示全部楼层
延时函数可能未使用volatile修饰变量,编译器优化导致循环次数被缩减。
probedog 发表于 2026-3-30 22:41 | 显示全部楼层
可能中断优先级冲突导致SysTick中断被其他中断长时间抢占。
发GV第几啊 发表于 2026-3-31 23:54 | 显示全部楼层
1111111111
公羊子丹 发表于 2026-4-1 08:25 | 显示全部楼层
这问题挺常见的!你升频到64MHz后肯定没更新SystemCoreClock,SysTick基准直接乱了,先调用SystemCoreClockUpdate再初始化延时。
公羊子丹 发表于 2026-4-1 08:25 | 显示全部楼层
这问题在F4系列特别典型,主频改了以后SystemCoreClock没同步更新,SysTick延时基准直接跑偏,记得先调用更新函数再初始化。
周半梅 发表于 2026-4-1 08:28 | 显示全部楼层
我怀疑你是用软件循环延时,没把循环次数和时钟绑定,64MHz下指令跑太快,延时直接变短失效,改用宏定义按频率折算。
周半梅 发表于 2026-4-1 08:28 | 显示全部楼层
我怀疑你用的是纯软件循环延时,64MHz下指令执行速度翻几倍,延时直接变短,最好按主频做动态计算,别写死循环次数。
帛灿灿 发表于 2026-4-1 08:30 | 显示全部楼层
你检查过Flash等待周期没?F411跑64MHz必须设正确延时,不然内核取指异常,延时函数直接跑飞。
帛灿灿 发表于 2026-4-1 08:30 | 显示全部楼层
你检查过SysTick的时钟源配置没?改成64MHz后要重新设定分频,不然定时周期完全不对,延时肯定不准。
童雨竹 发表于 2026-4-1 08:33 | 显示全部楼层
我建议直接用DWT外设做微秒延时,不占中断、不依赖系统时钟,改频不用动代码,精准又稳定。
童雨竹 发表于 2026-4-1 08:33 | 显示全部楼层
我建议直接用DWT计数器做延时,不依赖系统时钟、不占中断,主频随便改都精准,F411用这个方案最稳。
万图 发表于 2026-4-1 08:35 | 显示全部楼层
大概率是SysTick时钟源还是HCLK/8,升频后没重新配置,导致定时基准不对,重新初始化SysTick就好。
万图 发表于 2026-4-1 08:35 | 显示全部楼层
编译器开优化后很容易把延时循环优化掉,把循环变量加上volatile关键字,就能避免被编译器“偷偷删掉”了。
Wordsworth 发表于 2026-4-1 08:36 | 显示全部楼层
编译器优化很容易坑人!把延时循环变量加volatile,不然-O2优化会直接删掉循环,延时就失效了。
Wordsworth 发表于 2026-4-1 08:36 | 显示全部楼层
想问下你升频后有没有重新配置Flash等待周期?F411跑64MHz必须设置正确,不然取指异常,延时直接乱掉。
Bblythe 发表于 2026-4-1 08:37 | 显示全部楼层
想问下你用的是HAL_Delay吗?升频后要重新调用HAL_InitTick校准,不然滴答定时器周期全错。
Bblythe 发表于 2026-4-1 08:37 | 显示全部楼层
我踩过一模一样的坑,主频切换后没有硬件复位,旧时钟配置残留,重新上电复位一次,延时立马恢复正常。
Pulitzer 发表于 2026-4-1 08:38 | 显示全部楼层
我踩过同样的坑,升频后没复位系统,旧时钟配置残留在寄存器,硬复位一次再跑延时就正常了。
Pulitzer 发表于 2026-4-1 08:38 | 显示全部楼层
如果你用的是HAL_Delay,升频后必须重新调用HAL_InitTick,不然滴答定时器的频率还是按16MHz算的。
Uriah 发表于 2026-4-1 08:40 | 显示全部楼层
别用__NOP写延时,流水线和缓存会影响精度,F411最好用定时器或DWT,改频也不会出问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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