3. 占空比与频率的数学关系及计算
做脉冲宽度控制,绕不开两个核心参数:频率和占空比。很多新手容易把它们搞混,或者觉得“不就是个公式嘛,套进去算就行了”。其实不然。我在项目中踩过好几次坑,都是因为没搞清楚这两个参数之间的数学约束。
今天我们就把它彻底说透。
3.1 基本定义:周期、频率、脉宽、占空比
先统一一下概念。一个方波信号,有四个基本量:
| 参数 | 符号 | 单位 | 含义 |
|---|---|---|---|
| 周期 | T | 秒 (s) | 一个完整脉冲波形的时间长度 |
| 频率 | f | 赫兹 (Hz) | 每秒重复的周期数,f = 1/T |
| 脉宽 | ton | 秒 (s) | 一个周期内高电平持续的时间 |
| 占空比 | D | 百分比 (%) | 高电平时间占整个周期的比例,D = (ton / T) × 100% |
说白了,频率决定了脉冲的“快慢”,占空比决定了脉冲的“胖瘦”。
核心公式:
f = 1 / T
D = (ton / T) × 100%
ton = D × T = D / f
3.2 频率与占空比的相互约束
这里有个关键点,我刚开始做嵌入式时没太在意——频率和占空比不是完全独立的。
你想想看,占空比是脉宽除以周期。如果你把频率提高(周期变短),但脉宽不变,占空比就会自动变大。反过来,如果你要维持一个固定的占空比,频率变了,脉宽也必须跟着变。
举个例子:
- 频率 1 kHz(周期 1 ms),占空比 50% → 脉宽 = 0.5 ms
- 频率 10 kHz(周期 0.1 ms),占空比 50% → 脉宽 = 0.05 ms
看到了吗?同样的占空比,频率越高,脉宽越窄。这在硬件上会带来一个实际问题:你的定时器能不能产生那么窄的脉冲?
避坑提醒:
我曾经在一个电机驱动项目里,把PWM频率设到了 100 kHz,占空比要求 1%。算下来脉宽只有 0.1 μs。结果MCU的定时器根本输出不了这么窄的脉冲,波形直接失真了。后来我不得不降低频率,或者改用更高精度的定时器。
3.3 分辨率与精度的权衡
频率越高,每个周期的时间越短。如果你的定时器时钟频率是固定的,那么可调节的脉宽步进(分辨率)就会变粗。
假设定时器时钟是 72 MHz,你要产生一个 20 kHz 的PWM:
- 周期计数值 = 72 MHz / 20 kHz = 3600
- 占空比分辨率 = 1 / 3600 ≈ 0.028%
但如果频率提高到 200 kHz:
- 周期计数值 = 72 MHz / 200 kHz = 360
- 占空比分辨率 = 1 / 360 ≈ 0.278%
分辨率差了10倍。所以,高频下很难做到精细的占空比调节。
| PWM频率 | 定时器时钟 72 MHz | 周期计数值 | 占空比步进 |
|---|---|---|---|
| 1 kHz | 72 MHz | 72000 | 0.0014% |
| 20 kHz | 72 MHz | 3600 | 0.028% |
| 100 kHz | 72 MHz | 720 | 0.139% |
| 1 MHz | 72 MHz | 72 | 1.389% |
我个人的习惯是:先确定应用需要的频率范围,再反推占空比分辨率是否满足要求。如果分辨率不够,要么降低频率,要么换更高时钟的MCU。
3.4 实际计算案例:LED调光 vs 电机控制
不同的应用场景,对频率和占空比的要求完全不同。我拿两个最常见的例子来说明。
3.4.1 LED调光
LED调光对频率不敏感,人眼能感知的闪烁频率大约在 60 Hz 以下。所以通常用 1 kHz 左右的PWM就够了。占空比从 0% 到 100% 精细调节,实现亮度渐变。
计算示例:
- 目标频率:1 kHz → 周期 T = 1 ms
- 定时器时钟:72 MHz → 预分频后得到 1 MHz 计数时钟
- 周期计数值 = 1 MHz / 1 kHz = 1000
- 占空比步进 = 1/1000 = 0.1%
- 要输出 50% 占空比:脉宽计数值 = 1000 × 50% = 500
3.4.2 直流电机调速
电机控制对频率有要求。频率太低,电机会发出“嗡嗡”声甚至抖动;频率太高,MOS管开关损耗增大。一般直流电机用 10 kHz ~ 20 kHz 比较合适。
计算示例:
- 目标频率:20 kHz → 周期 T = 50 μs
- 定时器时钟:72 MHz → 直接使用,不分频
- 周期计数值 = 72 MHz / 20 kHz = 3600
- 占空比步进 = 1/3600 ≈ 0.028%
- 要输出 75% 占空比:脉宽计数值 = 3600 × 75% = 2700
我的经验:
做电机控制时,我一般会留一点余量。比如计算出来周期计数值是 3600,我会把自动重装载值设为 3599,避免边界溢出。另外,占空比不要设到 0% 或 100% 的极端值,有些MOS驱动芯片在极端占空比下会工作异常。
3.5 知识结构图:频率与占空比的关系
下面这张图帮你理清整个逻辑链条:
3.6 常见计算场景与代码实现
最后,我给出一个实际的代码片段。这是我在STM32上配置PWM的常用写法,你可以直接参考:
// 假设定时器时钟 TIM_CLK = 72 MHz
// 目标频率 20 kHz,目标占空比 50%
uint32_t target_freq = 20000; // 20 kHz
uint32_t target_duty = 50; // 50%
// 计算周期计数值
uint32_t period = TIM_CLK / target_freq; // 3600
// 计算脉宽计数值
uint32_t pulse = period * target_duty / 100; // 1800
// 配置定时器
TIM_TimeBaseInitTypeDef TIM_InitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_InitStruct.TIM_Period = period - 1; // 自动重装载值
TIM_InitStruct.TIM_Prescaler = 0; // 不分频
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_Pulse = pulse; // 脉宽计数值
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStruct);
TIM_Cmd(TIM2, ENABLE);
关键点总结:
- 频率和占空比通过周期和脉宽相互关联
- 高频下占空比分辨率会下降,这是硬件限制
- 实际配置时,记得给边界留余量(period - 1)
- 不同应用(LED、电机、加热)对频率的要求不同,不要一刀切
嗯,这部分内容就到这里。你只要把公式吃透,再结合实际的定时器配置,就不会在频率和占空比上栽跟头了。