7. 输出比较—PWM

📌 本节学习目标
  • 理解 PWM 波形的基本参数
  • 掌握 STM32 定时器输出比较模式
  • 学会配置 PWM 输出控制 LED/电机
  • 掌握呼吸灯和直流电机调速实现

7.1 PWM 概述

PWM(Pulse Width Modulation,脉宽调制)是一种通过调节脉冲宽度(占空比)来实现模拟控制的数字技术。

PWM 基本参数

  • 周期 T:PWM 波形重复的时间间隔
  • 频率 f:f = 1/T,单位 Hz
  • 占空比 D:高电平时间占整个周期的比例,D = t_on / T × 100%

7.2 输出比较模式

STM32 定时器的输出比较模式可产生 PWM 波。其原理是:

  • 计数器 CNT 从 0 递增到 ARR(自动重装值)
  • 当 CNT 的值小于 CCRx(捕获比较寄存器)时,输出有效电平
  • 当 CNT 的值大于 CCRx 时,输出无效电平
  • 改变 CCRx 即可改变占空比

7.3 PWM 配置示例:呼吸灯

C 代码(TIM2_CH2 PWM 输出-PA1)
#include "stm32f10x.h"

// TIM2_CH2 (PA1) PWM 输出:20KHz
void PWM_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    // 使能时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // PA1 复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // TIM2 配置:20KHz(ARR=3599,PSC=0)
    // 72MHz / 3600 = 20KHz
    TIM_TimeBaseStructure.TIM_Period = 3599;
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    // PWM1 模式:CNT < CCR 时输出有效电平
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;              // 初始占空比 0%
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC2Init(TIM2, &TIM_OCInitStructure);        // 通道 2

    TIM_Cmd(TIM2, ENABLE);
}

// 设置占空比 (0~100)
void PWM_SetDuty(uint8_t duty)
{
    uint16_t pulse = (uint16_t)(3600 * duty / 100);
    TIM_SetCompare2(TIM2, pulse);
}

// 呼吸灯效果
void Breath_LED(void)
{
    uint8_t i;
    for (i = 0; i < 100; i++)
    {
        PWM_SetDuty(i);     // 逐渐变亮
        delay_ms(10);
    }
    for (i = 100; i > 0; i--)
    {
        PWM_SetDuty(i);     // 逐渐变暗
        delay_ms(10);
    }
}
💡 这段代码怎么用?
  1. PWM 配置 6 步:时钟 → GPIO(AF_PP) → TIM 时基 → 输出比较 → 预装载 → 使能,实验 15 在它的基础上加重映射
  2. ARR 决定周期(频率),CCRx 决定占空比——想改频率改 ARR,想改亮度/音量改 CCRx
  3. 呼吸灯就是在主循环里循环改 CCRx,配合延时控制渐变速度

7.4 PWM 的应用

应用原理典型参数
LED 呼吸灯改变占空比控制亮度1KHz~20KHz
直流电机调速改变占空比控制转速50Hz~20KHz
舵机控制特定脉宽对应角度50Hz(20ms 周期)
蜂鸣器控制特定频率驱动压电蜂鸣器2KHz~4KHz
📎 配套资料课件:7.输出比较—PWM.pptx | 实验:实验15:PWM | 视频:PWM 演示视频