1. PWM基础概念与工作原理
PWM(Pulse Width Modulation,脉冲宽度调制)是一种通过数字信号模拟模拟量输出的经典技术。它的核心原理是在固定周期内,通过调节高电平信号的持续时间(脉宽)来改变输出的平均电压或功率。这种技术之所以重要,是因为它完美解决了数字系统(如单片机)无法直接输出模拟信号的问题。
想象一下,你正在用开关控制一盏灯的亮度。如果开关只有开(1)和关(0)两种状态,那么灯要么全亮要么全灭。但如果你以极快的速度反复开关,并且控制"开"的时间比例,人眼就会因为视觉暂留效应而看到不同的亮度效果——这就是PWM最直观的体现。
在实际应用中,PWM有三个关键参数:
- 周期(T):一个完整PWM波形重复的时间长度
- 频率(f):周期的倒数,f=1/T
- 占空比(D):高电平时间占整个周期的比例,D=Thigh/T×100%
2. PWM的硬件实现机制
2.1 定时器的工作原理
大多数微控制器(如STM32)都通过定时器硬件模块产生PWM信号。定时器的核心是一个计数器(CNT),它会按照设定的时钟频率进行递增或递减计数。当计数器值达到预设的自动重装载值(ARR)时,就会产生溢出并重新开始计数,形成周期性循环。
以向上计数模式为例:
- CNT从0开始递增
- 当CNT=CCRx(捕获/比较寄存器值)时,触发比较事件
- CNT继续递增直到ARR值
- 达到ARR后CNT归零,开始下一个周期
2.2 PWM生成的关键寄存器
在STM32等MCU中,配置PWM主要涉及两个关键寄存器:
-
TIMx_ARR(Auto-Reload Register):决定PWM的周期
- 周期T = (ARR+1)/f_cnt(f_cnt为定时器时钟频率)
- 频率f = f_cnt/(ARR+1)
-
TIMx_CCRx(Capture/Compare Register):决定PWM的占空比
- 占空比D = CCRx/(ARR+1)×100%
重要提示:实际应用中,定时器时钟通常经过预分频器(PSC)分频得到f_cnt。完整公式应为:
T = (ARR+1)×(PSC+1)/f_sys(f_sys为系统时钟频率)
2.3 PWM输出模式解析
STM32支持多种PWM输出模式,最常用的是PWM Mode 1和Mode 2:
PWM Mode 1(边沿对齐,向上计数):
- CNT < CCRx:输出有效电平(可配置高或低)
- CNT ≥ CCRx:输出无效电平
- 适用于大多数标准PWM应用
PWM Mode 2(中心对齐):
- 计数器先递增后递减
- 在递增和递减阶段分别与CCRx比较
- 适合电机控制等需要对称PWM的应用
3. PWM的典型应用场景
3.1 LED亮度调节
通过改变PWM占空比,可以线性调节LED的平均电流,从而实现无级亮度控制。这是PWM最基础的应用之一。
实现要点:
- 频率选择:通常1kHz-10kHz(避免可见闪烁)
- 占空比范围:0-100%对应亮度从关闭到最大
- 注意事项:LED有最小导通电压,占空比过小可能无法点亮
3.2 直流电机调速
PWM通过改变施加在电机上的平均电压来控制转速。相比直接调节电压,PWM方式效率更高,发热更小。
关键参数:
- 频率选择:5kHz-20kHz(超出听觉范围)
- 占空比与转速:基本呈线性关系
- H桥驱动:需要配合电机驱动芯片使用
3.3 舵机控制
舵机(如SG90)通过PWM脉宽识别目标角度,是PWM在位置控制中的典型应用。
控制特性:
- 标准周期:20ms(50Hz)
- 脉宽范围:0.5ms-2.5ms对应0°-180°
- 角度精度:通常可达±1°
3.4 D类音频放大器
PWM技术可以用于构建高效率的D类音频放大器,通过高频PWM(几百kHz)和低通滤波还原音频信号。
4. STM32 PWM配置实战
4.1 硬件连接示例
以STM32F103驱动SG90舵机为例:
- 舵机红线:接5V电源
- 舵机棕线:接GND(必须与MCU共地)
- 舵机橙线:接MCU的PWM输出引脚(如TIM3_CH2→PB5)
注意:舵机工作电流较大(峰值可达500mA),建议使用独立电源供电,避免MCU稳压器过载。
4.2 定时器配置步骤
以下是使用STM32标准外设库配置PWM的典型流程:
- 使能时钟
c复制RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
- GPIO配置(以PB5为例)
c复制GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
- 定时器时基配置(50Hz PWM)
c复制TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_TimeBaseStruct.TIM_Period = 20000 - 1; // ARR
TIM_TimeBaseStruct.TIM_Prescaler = 72 - 1; // PSC (72MHz/72=1MHz)
TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);
- PWM输出配置(通道2)
c复制TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_Pulse = 1500; // 初始1.5ms脉宽
TIM_OC2Init(TIM3, &TIM_OCInitStruct);
- 启动定时器
c复制TIM_Cmd(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM3, ENABLE);
4.3 动态调节占空比
在运行时,可以通过修改CCR值实时调整PWM占空比:
c复制// 设置舵机角度(0.5ms-2.5ms脉宽)
void SetServoAngle(uint8_t angle) {
uint16_t pulse = 500 + angle * 2000 / 180; // 角度转脉宽(us)
TIM_SetCompare2(TIM3, pulse); // 更新CCR2
}
5. 高级应用与优化技巧
5.1 死区时间配置
在H桥电机驱动等应用中,需要配置死区时间(Dead Time)防止上下管直通。
配置方法:
c复制TIM_BDTRInitTypeDef TIM_BDTRInitStruct;
TIM_BDTRInitStruct.TIM_DeadTime = 0x5F; // 具体值需计算
TIM_BDTRInitStruct.TIM_Break = TIM_Break_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStruct);
5.2 互补输出与刹车功能
高级定时器(如TIM1)支持互补输出和紧急刹车功能,适合电机控制等安全关键应用。
5.3 DMA控制PWM
对于需要频繁更新PWM参数的场景(如LED渐变),可以使用DMA自动传输CCR值,减轻CPU负担。
5.4 频率与分辨率权衡
PWM的频率和占空比分辨率存在制约关系:
- 高频率:适合电机控制等需要快速响应的应用
- 高分辨率:适合需要精细调节的场景(如LED调光)
计算公式:
分辨率(位)= log2(ARR+1)
实际可用分辨率受定时器位数限制(通常16位)
6. 常见问题排查
6.1 无PWM输出
- 检查时钟是否使能(GPIO、定时器、AFIO)
- 确认GPIO模式配置为复用功能(AF_PP)
- 验证定时器是否已启动(TIM_Cmd)
- 检查硬件连接是否正确(示波器测量引脚)
6.2 PWM频率不正确
- 确认系统时钟频率(如STM32F103通常为72MHz)
- 检查ARR和PSC值计算是否正确
- 注意预分频器实际值为PSC+1
6.3 舵机抖动或不稳定
- 确保供电充足(5V,电流≥1A)
- 检查PWM周期是否为20ms(50Hz)
- 确认脉宽在0.5ms-2.5ms范围内
- 添加电源滤波电容(100μF+0.1μF)
6.4 电机响应异常
- 检查PWM频率是否合适(通常5kHz-20kHz)
- 验证死区时间配置(如有H桥)
- 确保电机驱动芯片使能信号正确
7. 实际项目经验分享
在多年的嵌入式开发中,我总结了以下PWM应用的心得:
-
电源设计至关重要:PWM驱动大电流负载(如电机)时,电源质量直接影响系统稳定性。建议:
- 使用低ESR的滤波电容
- 大功率负��单独供电
- 添加TVS二极管保护
-
软件滤波改善性能:对于需要平滑变化的PWM输出,可以采用:
- 指数移动平均滤波
- 斜坡函数生成器
- S曲线加速算法
-
充分利用硬件特性:
- 使用定时器的预装载功能确保参数同步更新
- 对于复杂波形,可以组合使用多个定时器
- 高级定时器的刹车功能可以快速关断PWM
-
调试技巧:
- 先用示波器验证基础PWM波形
- 逐步增加负载观察系统响应
- 记录关键参数的变化曲线
-
安全注意事项:
- 避免PWM频率落入人耳敏感范围(20Hz-20kHz)
- 电机堵转时及时降低占空比
- 高温环境下降低PWM频率减少开关损耗
