IustitiaeのBlog
首页项目归档照片墙音乐说说笔记关于
封面
📓 笔记/📁 嵌入式/PWM脉冲宽度调制详解

PWM脉冲宽度调制详解

2026-06-27 13:00:00
# 单片机
# STM32
# PWM
# 舵机

引言

PWM(Pulse Width Modulation,脉冲宽度调制)是利用数字输出来模拟模拟电路控制的一种技术。它看似简单——只是控制高低电平的时间比例——但几乎是嵌入式系统中最常用的信号输出方式。从呼吸灯到电机调速,从舵机控制到音频合成,PWM 无处不在。

一、PWM 基本概念

关键参数

参数定义公式**周期(T)一个完整波形从开始到重复的时间T = 1/f频率(f)单位时间内完整周期的次数f = 1/T占空比(D)**高电平时间占整个周期的比例D = Ton / T × 100%分辨率占空比可调节的最小步距由 ARR 决定

例:5V 系统,占空比 50% → 等效输出电压 ≈ 2.5V

二、STM32 PWM 生成原理

STM32 通过定时器输出比较的 PWM 模式生成 PWM 信号。核心寄存器:

寄存器作用TIMx_PSC(预分频器)对时钟频率进行分频TIMx_ARR(自动重装载)决定 PWM 的周期/频率TIMx_CCRx(捕获/比较)决定 PWM 的占空比TIMx_CNT(计数器)当前计数值,不断与 CCRx 比较

工作流程(向上计数、PWM 模式 1)

高电平
  ↑     ┌──────┐        ┌──────┐
  │     │      │        │      │
  │─────┘      └────────┘      └────→
  │  ← CCRx →←── (ARR-CCRx) ──→
  │  ←─────── 一个周期 (ARR+1) ─────→
  1. 计数器 CNT 从 0 向上累加
  2. CNT < CCRx 时 → 输出高电平
  3. CNT ≥ CCRx 时 → 输出低电平
  4. CNT = ARR 时 → CNT 清零,开始下一个周期

三、频率与占空比计算公式

PWM 频率

PWM频率 = 定时器时钟频率 / [(PSC + 1) × (ARR + 1)]

占空比(PWM 模式 1)

占空比 = CCRx / (ARR + 1) × 100%

配置示例

目标:产生 1KHz、50% 占空比的 PWM
时钟:72MHz
• 设 PSC = 71 → 计数时钟 = 72MHz / 72 = 1MHz
• 设 ARR = 999 → PWM频率 = 1MHz / 1000 = 1KHz
• 设 CCRx = 500 → 占空比 = 500/1000 = 50%

四、频率与分辨率的权衡

这是 PWM 配置中最需要理解的设计权衡:

取舍说明**频率 ↑**ARR ↓ → 分辨率 ↓**分辨率 ↑**ARR ↑ → 频率 ↓

示例:计数时钟 1MHz
若要 100KHz PWM → ARR=9,分辨率仅 10 级
若要 1KHz PWM → ARR=999,分辨率达 1000 级(0.1% 精度)

五、PWM 模式选择

模式行为适用场景PWM Mode 1CNT < CCR → 高电平通用场合PWM Mode 2CNT ≥ CCR → 高电平需要反相波形时

极性设置(TIM_OCPolarity_High / TIM_OCPolarity_Low)可进一步反转输出电平。

六、HAL 库配置与代码

① CubeMX 配置

  1. 选择定时器(如 TIM3),Clock Source 设为 Internal Clock
  2. 选择通道(如 Channel 1),设为 PWM Generation CH1
  3. 设置参数:Prescaler、Counter Period(ARR)、Pulse(初始 CCRx)

② 呼吸灯示例

// 启动 PWM 输出
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

// 动态修改占空比实现呼吸灯
while (1) {
    for (uint16_t i = 0; i < 1000; i += 10) {
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, i);
        HAL_Delay(20);
    }
    for (uint16_t i = 1000; i > 0; i -= 10) {
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, i);
        HAL_Delay(20);
    }
}

③ 常用 API

函数/宏功能HAL_TIM_PWM_Start()启动 PWM 输出HAL_TIM_PWM_Stop()停止 PWM 输出__HAL_TIM_SET_COMPARE()动态修改占空比__HAL_TIM_GET_AUTORELOAD()获取 ARR 值

七、典型应用

应用PWM 频率占空比范围说明LED 呼吸灯1-2KHz0-100%频率高于人眼闪烁感知舵机 SG9050Hz(20ms周期)2.5%-12.5%0.5ms=0°,2.5ms=180°直流电机调速16-20KHz0-100%避开人耳听觉范围无源蜂鸣器1-4KHz50%输出音频频率

八、舵机控制详解

舵机是 PWM 最经典的应用之一。以 SG90 为例:

周期 = 20ms(50Hz)

高电平持续 0.5ms  →  舵机角度 0°
高电平持续 1.0ms  →  舵机角度 45°
高电平持续 1.5ms  →  舵机角度 90°
高电平持续 2.0ms  →  舵机角度 135°
高电平持续 2.5ms  →  舵机角度 180°

50Hz PWM 配置(72MHz 时钟):

PSC = 144 - 1 = 143        → CK_CNT = 72MHz / 144 = 500KHz
ARR = 10000 - 1 = 9999     → PWM周期 = 10000/500K = 20ms
CCR值范围 = 250 ~ 1250     → 0.5ms ~ 2.5ms

九、常见问题排查

问题检查项无 PWM 输出①定时器时钟是否使能 ②GPIO 是否配置为复用功能 ③是否调用了 HAL_TIM_PWM_Start()频率偏差检查 APB 预分频器设置、确认未启用 CKD 分频占空比异常确认 PWM 模式(Mode 1/2)与极性设置是否匹配高级定时器无输出TIM1/TIM8 需设置 TIM_BDTR->MOE 位使能主输出

总结

PWM 是输出比较最实用的形态。掌握了频率、占空比、分辨率三者的关系,你就能用一根信号线控制 LED 的明暗、电机的快慢、舵机的角度——这是数字世界对模拟世界最优雅的控制方式。

控制不在于力的强弱,而在于节奏的精妙。 —— Iustitiae

avatar

Iustitiae

在代码、单片机,电机控制模拟间穿梭的普通人。近期正埋头于 freerots学习。

2026年6月

一
二
三
四
五
六
日
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

Recent Records

比较器基础——输出级、输入范围与颤振的解决之道

2026-08-03 12:00:00

MOS管基础——从电压控制的电子开关到电源开关与防反接

2026-08-03 12:00:00

三极管基础——从小电流撬动大电流的放大器到电子开关

2026-07-29 12:00:00