这几天在捣鼓一个老项目,里面有个模块涉及到脉冲信号的控制,那个占空比(duty cycle)的计算搞了我一下午。说起来简单,但真要拿捏准了,还真得翻翻笔记。
咱们先明确一下,这个占空比是干嘛的。简单说,就是在一个周期内,信号是“开”着的时间占总时间的比例是多少。这个比例一变,输出的能量或者控制效果就不一样。
我的实践过程
我这回遇到的场景是,需要根据一个输入值来动态调整一个PWM(脉冲宽度调制)信号的占空比,好控制一个直流电机的转速。一开始我只是凭感觉调,结果电机忽快忽慢,根本稳不住。
我立刻停下来,拿起笔在草稿纸上开始推公式。我记得核心就那么几个,搞清楚了,后面的代码实现就是水到渠成了。

第一个公式:最基础的定义
占空比的定义是最直接的,我写下这个:
- $DutyCycle = (\text{High Time} / \text{Total Period}) \times 100\%$
这玩意儿是理论基础。High Time就是信号是高电平(比如5V)的时间,Total Period就是信号重复一次需要多长时间,就是高电平时间加低电平时间。我当时就想,我要是能精确控制这两个时间,那占空比就随便调了。
第二个公式:用频率来算
在嵌入式里头,我们通常设定一个固定的周期(Period),然后通过改变高电平的持续时间来控制占空比。周期和频率是倒数关系:
- $\text{Period} = 1 / \text{Frequency}$
如果我设定了工作频率,比如1kHz,那么总周期就是$1\text{ms}$。如果我想做到50%的占空比,那么高电平时间就得是$0.5\text{ms}$。

我当时是这样计算出高电平时间的:
- $\text{High Time} = \text{DutyCycle} \times \text{Period}$
当我把这个和第二个公式一结合,发现我的控制逻辑就清晰了:先定死频率,算好周期,然后根据我想要的百分比去算出高电平要拉多久。
第三个公式:电平计数值的转换
在实际操作中,尤其是在单片机或者FPGA这种数字电路里,时间不是直接设的,我们设的是计数值。比如定时器溢出的计数值。
假设我的系统定时器是按固定时钟频率跑的,假设是$N$个时钟周期代表一个时间单位。那么我的“高电平计数值”就得这么算:
- $\text{High Count} = \text{DutyCycle} \times \text{Total Count in a Period}$
这个$\text{Total Count in a Period}$就是周期内总共跑了多少个时钟滴答。我把我的目标占空比(比如$0.75$)乘以这个总计数,就得到了我定时器需要设置的“开”的时间计数值。
实操的校验
我把这套逻辑在我的开发板上跑起来。我设置了$10\text{kHz}$的工作频率,这意味着周期是$100\mu\text{s}$。总计数值我设成了1000(为了好算,假设我的计数器最大值能方便地对标这个周期)。
如果我要$25\%$的占空比,那么我计算出来的高电平计数值就是 $0.25 \times 1000 = 250$。
我把程序里负责设置占空比的那个寄存器(或者变量)赋值为250,然后启动PWM输出。然后拿出示波器一看,好家伙,波形瞬间就对了,高电平确实占了总时长的四分之一。
我又试着把占空比调到$70\%$,计数是$700$。示波器上显示的结果也完全符合预期。这回的踩坑经历让我深刻理解,搞硬件控制,公式才是王道,别老想着用经验去蒙。









