TIM — PWM 输出
难度: ⭐⭐(需要了解定时器基本概念)
固件库: AT32F403A_407_Firmware_Library V2.2.2
源文件:project/at_start_f403a/examples/tmr/pwm_output_tmr3/src/main.c
这个实验是干嘛的?
PWM(Pulse Width Modulation,脉冲宽度调制)是一种用数字信号模拟模拟信号的技术。
简单说:MCU 只能输出 0V 或 3.3V,不能输出 1.5V。但如果你快速地在 0V 和 3.3V 之间切换,改变高电平的占比,就能模拟出不同的"平均电压":
|
|
本实验用 TMR3 的 4 个通道输出 4 路不同占空比的 PWM:
- 通道 1:50% 占空比
- 通道 2:37.5%
- 通道 3:25%
- 通道 4:12.5%
硬件准备
- AT32F403A 开发板
- 示波器(看波形)或 LED(看亮度变化)
PWM 输出引脚(TMR3 的 4 个通道):
| 通道 | 引脚 | 占空比 |
|---|---|---|
| CH1 | PA6 | 50% |
| CH2 | PA7 | 37.5% |
| CH3 | PB0 | 25% |
| CH4 | PB1 | 12.5% |
如果接 LED:PA6 的 LED 最亮,PB1 的 LED 最暗。
PWM 核心概念
关键参数
| 参数 | 含义 | 本例数值 |
|---|---|---|
| ARR(重装载值) | 定时器计数到多少归零 | 665 |
| PSC(预分频器) | 时钟分频系数 | 系统时钟/24MHz - 1 |
| CCR(比较值) | 计数到多少时翻转输出 | 通道不同值不同 |
| 占空比 | CCR / (ARR+1) | 50%, 37.5%, 25%, 12.5% |
| PWM 频率 | 时钟 / (PSC+1) / (ARR+1) | 24MHz / 1 / 666 ≈ 36KHz |
PWM 工作原理
|
|
- 计数器从 0 向上计数到 ARR,然后归零重新开始
- 计数 < CCR 时,输出高电平
- 计数 ≥ CCR 时,输出低电平
- CCR 越大,高电平时间越长,占空比越大
完整代码
|
|
代码分段讲解
1. GPIO 复用模式
|
|
关键点:PWM 输出的引脚必须配置为复用模式(MUX),不是普通输出模式(OUTPUT)。
为什么?因为引脚的控制权要交给定时器硬件,而不是 CPU。定时器自动翻转引脚电平,CPU 不用管。
2. 预分频器
|
|
定时器的时钟源是系统时钟(比如 240MHz),太快了。预分频器把它降频:
- PSC = 9 → 定时器时钟 = 240MHz / 10 = 24MHz
- 定时器每 41.67ns 计数一次
3. ARR 和 CCR
|
|
- ARR = 665:计数器从 0 计到 665 就归零,一个周期 = 666 个计数
- CCR = 333:计数到 333 时输出翻转
- 占空比 = 333 / 666 ≈ 50%
4. PWM 模式 A vs B
|
|
- PWM 模式 A:计数 < CCR 时输出高电平(最常用)
- PWM 模式 B:计数 < CCR 时输出低电平(反相)
实验现象
用示波器观察 4 个引脚:
- PA6:50% 占空比的方波
- PA7:37.5% 占空比
- PB0:25% 占空比
- PB1:12.5% 占空比
如果接 LED:PA6 最亮,PB1 最暗。
如何动态改变占空比?
|
|
new_ccr 范围:0 ~ ARR(0 ~ 665)
new_ccr = 0→ 占空比 0% → LED 灭new_ccr = 333→ 占空比 50% → LED 半亮new_ccr = 665→ 占空比 100% → LED 全亮
常见问题
Q: 引脚没有 PWM 输出?
- GPIO 是否配置为复用模式(MUX)?普通输出模式不行
- 定时器时钟是否使能?
tmr_counter_enable()是否调用?
Q: PWM 频率不对?
- 检查 PSC 和 ARR 的值
- PWM 频率 = 定时器时钟 / (PSC+1) / (ARR+1)
- 确认系统时钟是否正确(
system_core_clock)
Q: 想生成 50Hz PWM(控制舵机)?
- 舵机需要 50Hz(20ms 周期)
- 假设定时器时钟 24MHz:ARR = 24000000 / 50 / (PSC+1) - 1
- PSC = 11 → ARR = 39999 → 50Hz
- CCR 范围:1000
5000 对应 0.5ms2.5ms → 0°~180°
小结
| 概念 | 说明 |
|---|---|
| PWM | 用数字信号模拟模拟信号 |
| ARR | 重装载值,决定 PWM 周期 |
| CCR | 比较值,决定占空比 |
| 占空比 | CCR / (ARR+1),高电平占比 |
| 复用模式 | GPIO 必须配置为 MUX 模式 |
| 预装载 | 缓冲写入,避免毛刺 |
学了 PWM 能做什么?
PWM 是嵌入式中最实用的"万能模拟器":
LED 控制
| 项目 | 原理 | 难度 |
|---|---|---|
| LED 呼吸灯 | CCR 从 0 渐增到 ARR 再渐减 | ⭐⭐ |
| RGB 调色 | 3 路 PWM 控制红绿蓝,混合出任意颜色 | ⭐⭐ |
| 背光调节 | LCD/键盘背光亮度无级调节 | ⭐ |
电机控制
| 项目 | 原理 | 难度 |
|---|---|---|
| 直流电机调速 | PWM + MOS 管 → 改变占空比 = 改变转速 | ⭐⭐ |
| 舵机控制 | 50Hz PWM,脉宽 0.5~2.5ms → 0°~180° | ⭐⭐ |
| 步进电机驱动 | PWM 控制细分驱动器 | ⭐⭐⭐ |
| 无刷电机(BLDC) | 6 路互补 PWM + 死区控制 | ⭐⭐⭐⭐ |
音频与信号
| 项目 | 原理 | 难度 |
|---|---|---|
| 蜂鸣器播放音乐 | 不同频率 PWM = 不同音调 | ⭐⭐ |
| 简易信号发生器 | 改变频率和占空比输出方波 | ⭐⭐ |
| DAC 替代 | PWM + RC 滤波 → 模拟电压输出 | ⭐⭐⭐ |
| 红外遥控发射 | 38KHz PWM 载波 + 数据调制 | ⭐⭐⭐ |
电源与通信
| 项目 | 原理 | 难度 |
|---|---|---|
| 开关电源 | PWM 控制 MOS 管 → DC-DC 降压/升压 | ⭐⭐⭐⭐ |
| 充电控制 | PWM 控制充电电流(恒流充电) | ⭐⭐⭐ |
| 可控硅调光 | PWM 控制双向可控硅导通角 | ⭐⭐⭐ |
核心思路:PWM 的本质是"用时间换精度"。只要控制高电平的时间占比,就能模拟出任意电压、任意频率的信号。LED 亮度、电机转速、声音音调、电源电压……所有需要"连续调节"的场景,PWM 都能搞定。
下一步:学会了 PWM,可以学 DMA,了解如何用 DMA 配合定时器实现更高级的波形生成。