这两个频率很容易产生混淆,特别是做延时函数的时候,其实是以计数频率为基础来处理的。
下面有几个问题可以很好的理解这两个概念
1,一个cnt计数的时间是多少?
一个计数周期的时间,就是定时器计数器每增加 1 所耗费的时间。它不是固定的,完全取决于你的配置。
你可以通过以下公式来计算:
一个计数周期的时间 =1 / (定时器时钟频率)
要得到定时器时钟频率,核心是看预分频器(Prescaler)的配置。
🧮 计算一个计数周期的时间
定时器的时钟源(通常是 72MHz)会先经过一个预分频器(Prescaler)分频,然后才送给计数器。
公式如下:定时器时钟频率 = 时钟源频率 / (预分频器值 + 1)
所以,一个计数周期的时间就是:计数周期 = (预分频器值 + 1) / 时钟源频率
在你的代码中,TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;就是将预分频器值设为了 71。
代入72MHz的时钟源频率计算:计数周期 = (71 + 1) / 72,000,000 = 72 / 72,000,000 = 0.000001秒 = 1微秒 (1μs)
因此,在你当前的配置下,定时器每计数一次,正好是 1 微秒 (1μs)。
2,再除以最大计数值是什么?
“再除以最大计数值”这个操作,本身没有直接的物理意义,但根据上下文,通常指向两个不同的概念:溢出周期(最大可测时间)或占空比(比例)。
为了帮你彻底理清,我们需要拆解定时器里的几个核心变量:
1. 正确理解“最大计数值”
在 STM32 定时器中,最大计数值通常指自动重装载寄存器(ARR)的值。计数器从0开始,数到ARR后产生溢出事件。
计数次数=
ARR + 1(因为包含了 0)。在你的代码中,
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;,所以ARR = 65535,计数次数=65536。
2. 三种常见的“除法”场景
根据你提到的“除以最大计数值”,可能对应以下三种情况:
① 如果是指“溢出周期”(最大可测量时间)
这应该是你真正想算的东西。
溢出时间= (ARR + 1) ×计数周期。
在你的配置中:(65535 + 1) × 1µs = 65536µs ≈ 65.5ms。
如果你再用溢出时间除以 (ARR+1),那么结果就又回到了计数周期(1µs),这是一个多余的循环计算。
② 如果是指“当前计数值对应的比例”(用于生成 PWM 或计算占空比)
当你用CNT(当前计数值)除以ARR(最大值),得到的是当前计数进度。
例如:CNT / ARR。
这通常用于计算PWM 的占空比(比较值 / 周期值),或者计算 ADC 采样的百分比进度,它与时间没有直接关系。
③ 如果是为了计算“溢出频率”(每秒溢出次数)
如果你用定时器时钟频率(72MHz / 72 = 1MHz)再除以 (ARR+1):1,000,000Hz / 65536 ≈ 15.26Hz。
这表示定时器每秒钟溢出 15.26 次,也就是你的定时器更新中断频率。
💎 总结一下
如果你想知道“计数器数满一次需要多久”,计算:
(ARR+1) × 计数周期,不需要再做除法。如果你想知道“当前计数值对应的百分比”,计算:
CNT / ARR。如果你想知道“定时器中断的频率”,计算:
定时器时钟 / (ARR+1)。
结合你之前“测量延时”的需求,你真正需要的通常是计数周期(1µs)和溢出时间(65.5ms)。只要确保你的延时测量小于 65.5ms(你的阈值是 50µs,完全满足),就不需要考虑溢出问题。
3,怎么简单的记忆?
计数频率是“节拍器”的速度,溢出频率是“打完一首歌”的速度。
🥁 核心比喻
把定时器想象成一个节拍器(Metronome)和一个计数器(Counter):
计数频率(节拍器的速度)
定义:计数器每秒钟“滴答”一次的速度,即CNT寄存器每秒钟增加1的次数。
由谁决定:预分频器(Prescaler)。
在你的代码中:
TIM_Prescaler = 72 - 1,所以计数频率 =72MHz / 72 = 1MHz。即每微秒计数一次。影响:决定了时间测量的精度。计数频率越高,测量越精细。
记忆口诀:“计数的快慢,由预分频说了算。”
溢出频率(打完一首歌的速度)
定义:计数器从
0数到ARR(自动重装载值)后溢出,每秒钟溢出的次数。由谁决定:自动重装载值(ARR)。
在你的代码中:
TIM_Period = 0xFFFF,所以溢出频率 =计数频率 / (ARR+1) = 1MHz / 65536 ≈ 15.26Hz。即每65.5ms溢出一次。影响:决定了定时器的最大可测量时间和更新中断的频率。
记忆口诀:“溢出的快慢,由ARR说了算。”
📊 一目了然的对比表
| 概念 | 简单定义 | 控制者 | 计算方式 | 影响什么 |
|---|---|---|---|---|
| 计数频率 | 节拍器的速度(每拍多快) | Prescaler | 计数频率 = 时钟源 / (Prescaler+1) | 计数周期(时间精度) |
| 溢出频率 | 打完一首歌的速度(多久循环一次) | ARR | 溢出频率 = 计数频率 / (ARR+1) | 中断频率、最大测量范围 |
💡 帮你区分的三个关键问答
Q1:我配置定时器时,先设置谁?
A:先设置Prescaler(决定计数频率/精度),再设置ARR(决定溢出频率/最大范围)。
Q2:我要测量一个50µs的延时,需要关心溢出频率吗?
A:不需要。只要50µs远小于溢出周期(如65ms),溢出就不会发生。你只需要关心计数频率是否足够(1µs的精度足够了)。
Q3:如果我要让定时器每1ms产生一次中断,应该改哪个?
A:应该改ARR。因为溢出频率决定了中断频率。例如,计数频率为1MHz,要让中断频率为1kHz(1ms),需要设置ARR = 1000 - 1。
🎯 一句话总结
Prescaler 决定了“节拍”多快,ARR 决定了“节拍数”多少。节拍越快(Prescaler小),测时越准;节拍越多(ARR大),测时越长。
(最后补充一个实用提示:对于你当前的输入捕获测量延时需求,你真正关心的是计数频率(1MHz),因为它决定了你能测到的最小时间单位(1µs)。而溢出频率(15Hz)只需要保证它能覆盖你所有测试用例的最长延时即可。)