一.什么是PWM?

PWM(Pulse Width Modulation,脉冲宽度调制)是一种数字信号调制技术,它通过周期性地输出 “高电平” 和 “低电平” 组成的脉冲信号,且高电平的持续时间在周期内的占比(占空比)可调节,从而用数字信号模拟出 “连续变化的模拟量”

举个最直观的例子:假设用 5V 电源给 LED 供电,直接通 5V(100% 高电平),LED 最亮;断开(0% 高电平),LED 熄灭。若让信号在 “5V(高电平)” 和 “0V(低电平)” 之间快速切换:比如 1 秒内,500ms 高电平、500ms 低电平,LED 会因为人眼 “视觉暂留” 效应,看起来是 “半亮”—— 这就是 PWM 的核心:用 “高频脉冲的平均效果” 模拟中间亮度。

二.PWM的三个核心基础参数

任何 PWM 信号都由这 3 个参数定义,是理解 PWM 的起点:

1.周期(T)一个完整脉冲(高电平 + 低电平)的持续时间(单位:秒,ms,μs 等)。

eg.1 个 PWM 信号,高电平持续 0.5ms,低电平持续 0.5ms,那么周期 T=1ms。

2.频率(f): 1 秒内包含的周期数(单位:Hz),与周期的关系是 f = 1/T

eg.周期 T=1ms(0.001 秒),则频率 f=1/0.001=1000Hz(1kHz)。

3.占空比(D):在一个周期内,高电平持续时间与周期的比值(通常用百分比表示)

占空比 D =(高电平时间 / 周期 T)× 100%

eg.周期 T=1ms,高电平持续 0.3ms,则 D=0.3/1×100%=30%。

4.分辨率:

三.为什么要使用PWM?

在嵌入式系统中,CPU 和数字电路只能输出 “0” 或 “1”(低电平或高电平),无法直接输出 “0~5V 之间的任意电压”(如 2.3V、3.7V 等模拟量)。PWM 的核心价值在于:用数字信号的 “占空比变化”,等效出连续的模拟量,无需额外的数模转换(D/A)硬件,降低成本且灵活可控。

eg.控制直流电机转速:5V 电源下,占空比 100%→全转速,50%→半转速,30%→低速(电机的机械惯性会 “平滑” 脉冲,实际输出平均功率与占空比成正比)。

四.PWM 生成原理

嵌入式中 PWM 主要通过定时器(Timer) 硬件生成,其核心是利用定时器的输出比较(Output Compare)功能实现。STM32 的定时器按功能可分为基本定时器(TIM6、TIM7)、通用定时器(TIM2-TIM5、TIM9-TIM14 等)和高级定时器(TIM1、TIM8),其中通用定时器和高级定时器支持 PWM 输出(基本定时器仅用于定时,无输出比较功能)。

<1>定时器的重点寄存器:

1. PSC(Prescaler,预分频器寄存器):16 位寄存器(部分定时器支持 32 位),存储预分频值,用于对定时器的 “时钟源” 进行分频,降低计数频率。定时器的原始时钟源(如 APB1/APB2 总线时钟)频率通常很高(如 72MHz、168MHz),通过 PSC 分频后得到 “计数时钟”,让计数器以合适的速度递增 / 递减。

分频公式为 计数频率 = 定时器时钟源频率 / (PSC + 1)(PSC 值范围 0~65535,+1 是因为从 0 开始计数)。

2. CNT(Counter,计数器寄存器):16 位或 32 位寄存器(取决于定时器型号),存储当前的计数值,是定时器的 “核心计数变量”。在计数时钟的驱动下,按照设定的计数模式(向上计数、向下计数、中央对齐)不断变化:向上计数:从 0 开始递增,直到等于 ARR 后重置为 0;向下计数:从 ARR 开始递减,直到等于 0 后重置为 ARR;中央对齐:从 0 递增到 ARR,再递减到 0,循环往复。实时反映当前计数状态,是连接 “分频后时钟” 和 “自动重装” 的中间变量。

3. ARR(Auto-Reload Register,自动重装寄存器):16 位或 32 位寄存器,存储计数器的 “最大值”(或 “目标值”)。决定计数器的 “计数周期”—— 当 CNT 计数到 ARR 时,会触发 “溢出事件”(或 “更新事件”),并根据计数模式重置 CNT(向上计数重置为 0,向下计数重置为 ARR)。

4. CCR(Capture/Compare Register,捕获比较寄存器):每个定时器通道(如 TIM3_CH1、CH2)对应一个 CCR(如 CCR1、CCR2),存储 “比较值”。用于 “比较逻辑”—— 当 CNT 的当前值与 CCR 的值相等时,会触发 “比较事件”,进而控制对应通道的输出电平(如 PWM 的高低电平切换)。是 PWM “占空比” 的核心决定因素,通过修改 CCR 的值可动态调整占空比。

<2>二、寄存器之间的核心关系(以 “向上计数模式” 为例)

四个寄存器的协作逻辑可概括为:“时钟分频→计数→溢出重置→比较控制输出”,具体关系通过公式和流程体现:

1.计数频率与 PSC 的关系:

定时器的原始时钟源(如 STM32F1 的 APB1 时钟为 36MHz,经倍频后可能为 72MHz)需通过 PSC 分频得到 “计数时钟”,这是 CNT 计数的速度基准

计数频率(f_cnt) = 定时器时钟源频率(f_clk) / (PSC + 1)

eg.若时钟源为 72MHz,PSC=71,则 f_cnt = 72MHz / (71+1) = 1MHz(即计数时钟周期为 1μs,CNT 每 1μs 加 1)。

2. 定时器周期(PWM 周期)与 ARR、PSC 的关系:

ARR 决定了 CNT 从 0 计数到重置的 “总计数次数”,结合计数频率可算出 “定时器周期”(即 PWM 的周期 T):

定时器周期(T) = (ARR + 1) / 计数频率(f_cnt)

(+1 是因为 CNT 从 0 开始计数,到 ARR 时共经历了 ARR+1 个计数单位,如 ARR=999 时,计数 0~999 共 1000 个单位)

T = (ARR + 1) × (PSC + 1) / f_clk

eg.时钟源 72MHz,PSC=71(f_cnt=1MHz),ARR=999 → T = (999+1)/1MHz = 1000μs = 1ms → 对应 PWM 频率为 1/T = 1kHz。

3. PWM 占空比与 CCR、ARR 的关系

在向上计数 + PWM 模式 1 下,当 CNT ≤ CCR 时输出高电平,CNT > CCR 时输出低电平。因此,高电平时间为(CCR + 1)个计数单位,占空比公式为:

占空比(D) = (高电平时间) / (总周期时间) = (CCR + 1) / (ARR + 1) × 100%  

这四个寄存器的配合,是定时器实现定时、PWM 输出等功能的核心。

<3>STM32 配置 PWM 的关键步骤

1.使能外设时钟:

定时器时钟(如 APB1 总线的 TIM3 时钟);对应 GPIO 时钟(PWM 输出引脚需复用为定时器输出)。

2.配置 GPIO 为复用功能:

PWM 输出引脚需配置为 “复用推挽输出”,并指定复用功能为对应定时器通道(如 PA6 复用为 TIM3_CH1)。

3.配置定时器基础参数(PSC、ARR):

设定计数频率和周期(如目标 PWM 频率 1kHz,时钟源为 72MHz):计数频率 = 72MHz / (PSC + 1),假设 PSC=71,则计数频率 = 1MHz(周期 1μs);周期 T=1/1kHz=1ms=1000μs,故 ARR=999(1000 个计数单位)。

4.配置 PWM 通道参数(CCR、模式):

选择 PWM 模式 1,设定初始占空比(如 50%,则 CCR=499)。

5.启动 PWM 输出:

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 启动通道1的PWM输出

6.动态修改占空比:

直接修改 CCR 寄存器的值(通过库函数),无需重新初始化

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 300); // 占空比30%(300/1000)

五.STM32 PWM 的两种模式

STM32 定时器的 PWM 模式通过CCMR寄存器的OCxM位配置,两种模式的电平切换逻辑是核心区别:

1.PWM 模式 1(最常用):

计数器向上计数时,当CNT(当前计数值)≤ CCR,输出高电平;当CNT > CCR,输出低电平。溢出(CNT=ARR)后计数器清零,重新开始计数,循环往复

2.PWM 模式 2

计数器向上计数时,当CNT ≤ CCR,输出低电平;当CNT > CCR,输出高电平。与模式 1 的电平状态完全相反。

模式 2 适用场景:需要 “低电平有效” 的场景(如某些电机驱动芯片的使能信号为低电平有效)。

六.PWM相关的面试问题

1.为什么 STM32 的 PWM 输出引脚需要配置为复用推挽模式?

“复用”:引脚功能由定时器模块控制(而非 GPIO 直接控制);“推挽”:确保高电平时能输出强电流(如驱动 LED、电机驱动芯片),避免高电平仅为弱上拉。

2.动态修改 PWM 占空比时,如何避免输出波形突变?

开启定时器的 “预装载寄存器”(通过CCMROCxPE位),使 CCR 的修改在计数器溢出后生效(而非立即生效),避免中途切换导致的波形异常。

3.高级定时器(如 TIM1)相比通用定时器,PWM 功能有何特殊之处?

支持 “互补输出” 和 “死区控制”,适合电机驱动(如三相桥电路),避免上下桥臂同时导通短路;可配置刹车功能(紧急情况下关闭 PWM 输出)。

4.为什么软件模拟 PWM 不适合高精度场景?

软件模拟依赖延时函数,而 CPU 在延时期间无法处理其他任务,占用资源;且延时精度受中断、其他任务影响,导致 PWM 周期和占空比误差较大。

5.WM 控制电机时,出现转速波动,可能的原因有哪些?

① 电源电压不稳定,导致电机供电波动;② PWM 频率过低,导致电机力矩波动;③ 定时器配置错误(如时钟源不稳定),导致 PWM 输出周期不准;④ 电机负载突变(如卡顿)。

6.PWM 频率过高或过低会有什么问题?如何选择频率?

频率过低会导致负载 “抖动 / 闪烁”(如 LED 频闪、电机抖动);频率过高会增加 MCU 功耗,且可能超出负载响应能力(如舵机仅支持 50Hz)。选择依据:负载特性(如电机推荐 20kHz+,LED 推荐 100Hz + 避免闪烁)、MCU 定时器性能(最高频率受系统时钟限制)。

7.用定时器生成 PWM 时,想提高控制精度,该调整哪个参数?

提高定时器的 “分辨率”,即增大 “自动重装载值(ARR)”(在频率不变的前提下,需同步降低预分频系数 PSC,保证 (PSC+1)*(ARR+1) 不变)。例如 8 位分辨率(ARR=255)提升到 10 位(ARR=1023),占空比最小步长从 0.39% 降至 0.097%。

8.PWM 输出没有信号,可能的原因有哪些?

1. 时钟未使能(定时器或 GPIO 时钟);2. GPIO 模式配置错误(未设为复用输出);3. 定时器未使能(TIM_Cmd未调用);4. PWM 通道未使能(TIM_CCxCmd未调用);5. 比较值 CCR 大于 ARR(此时占空比为 100%,看似无脉冲)。

9.调试常见问题与解决方案:

1.PWM 波形抖动定时器时钟不稳定(如使用外部晶振误差大)、中断抢占导致定时器更新延迟。

解决:使用内部高精度时钟(如 PLL 锁相环)、避免高优先级中断干扰定时器。

2.占空比与预期不符定时器配置错误(如 PSC/ARR 计算错误)、CCR 值超过 ARR 范围。

解决:重新核对频率 / 占空比计算公式,确保 CCR≤ARR。

3.电机异响 / LED 闪烁:PWM 频率过低,负载响应跟不上脉冲变化。

解决:提高频率至负载临界值以上(如电机调至 10kHz 以上)。

七.PWM 的分辨率(Resolution)

PWM 的分辨率(Resolution)是衡量其占空比调节精细程度的核心指标,直接决定了 PWM 信号能实现的最小占空比变化量。在嵌入式开发中,分辨率是 PWM 设计的关键参数(尤其在需要高精度控制的场景,如精密调光、电机转速平滑调节等)。

<1>分辨率的定义:

在固定周期下,占空比能被调节的最小步进值(即相邻两个不同占空比之间的差值)。若分辨率为 1%,则占空比只能调节为 0%、1%、2%...100%(步进 1%);若分辨率为 0.1%,则可调节为 0%、0.1%、0.2%...100%(步进 0.1%),调节更精细。

<2>分辨率的决定因素:

PWM 的分辨率由定时器的计数范围(即 “最大计数值”)决定,而计数范围通常由定时器的位数或配置的 “自动重装载值(ARR)” 决定。由定时器位数决定(默认最大范围)嵌入式芯片的定时器通常为 8 位、16 位、32 位等,其最大计数值为 2n−1(n 为位数,0 基计数)。此时,分辨率计算公式为:分辨率=1​/2^n×100%

eg.16 位定时器:最大计数值为 2^16−1=65535,分辨率为 1/65536≈0.0015%(步进约 0.0015%,精度远高于 8 位)。

<3>由实际配置的周期(ARR)决定(工程常用):

分辨率=1/ARR+11×100%

<4>分辨率与频率的权衡

分辨率与 PWM 频率存在此消彼长的关系若要提高频率(缩短周期),需减小 ARR,但 ARR 减小会导致分辨率降低(步进变大)。若要提高分辨率(减小步进),需增大 ARR,但会导致频率降低(周期变长)。

工程选择原则:在满足负载对频率要求的前提下,尽量增大 ARR 以提高分辨率。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐