带你一文搞懂PWM!

一、什么是PWM?

究竟什么是PWM?来看一下官方解释,PWM又叫脉冲宽度调制,简称脉宽调制。其实也就是调节脉冲宽度的一种技术。它是一种对模拟信号电平进行数字编码的方法。通过使用高分辨率的计数器,调制方波的占空比,从而实现对一个具体模拟信号的编码。PWM 信号本质上是一种周期性的方波信号,在每个周期内,信号会在高电平和低电平之间切换。

二、几个基本概念

PWM的核心概念包括:频率、周期、占空比和脉宽时间。接下来,让我们来逐一解释一下吧。

    2.1 周期

    周期T:指 PWM 信号完成一个完整的高低电平变化所需要的时间。也就是一个完整的脉冲信号的时间。

    2.2 频率

    周期(T)的倒数频率(F),即 f= T/1

    频率决定了 PWM 信号的变化速度,不同的应用场景需要不同的频率。例如,在电机控制中,频率过低可能会导致电机抖动,而频率过高则可能增加开关损耗。电机一般的频率建议控制在6-20khz。

    2.3 占空比

    占空比(D%):是 PWM 信号最重要的参数之一,它表示脉冲宽度与周期的比值。也就是高电平占整个周期T的比例。通过改变占空比,可以改变 PWM 信号的平均电压或功率,从而实现对被控对象的控制。

    比如:周期T为100ms(发生一次完整脉冲信号的时间),高电平的时间为60ms。那么它的占空比也就是60 / 100 = 60%。

    2.4 脉冲宽度

    脉冲宽度(t):指的是PWM 信号在一个周期内处于高电平的时间。

    三、PWM基本原理

    PWM 信号的产生通常依赖定时器或计数器。定时器按照设定的频率进行计数,当计数值达到某个预设的比较值时,输出信号的电平发生改变。以一个简单的向上计数定时器为例,计数从 0 开始,当计数值小于比较值时,输出高电平;当计数值大于等于比较值时,输出低电平。当计数值达到定时器的自动重装载值时,计数重新从 0 开始,如此循环,就产生了 PWM 信号。

    好了,原理我们大致懂了。主要关注的几个变量我们在复述一下:周期T、频率f、占空比D;以及定时器中的自动重装载值ARR、预分频系数psc。这里要注意一下,基本定时器是没有PWM输出的功能的。我们在选择的时候需要注意一下。

    四、示例代码

    4.1 举个🌰:用PWM驱动一个马达

    1. 先来看原理图,确认马达的接线。ML_PWM1->PA8。

    2. 开始写代码吧!这里用的是标准库函数。

    代码分为以下三个部分:

    第一部分:GPIO配置;第二部分:TIMx配置;第三部分:PWM配置;第四部分:调用。

    .c文件:
    // 定时器 1 PWM 初始化(对应 PA8)
    void TIM1_PWM_Init(u16 arr, u16 psc)
    {
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_OCInitTypeDef TIM_OCInitStructure;
    
        // 使能 GPIOA 和 TIM1 时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE);
    
        // 配置 PA8 为复用推挽输出
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    
        // 定时器 1 基本参数配置
        TIM_TimeBaseStructure.TIM_Period = arr;
        TIM_TimeBaseStructure.TIM_Prescaler = psc;
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
    
        // PWM 模式配置
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = arr / 2;  // 初始占空比 50%
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    
        // 使能定时器 1 主输出
        TIM_CtrlPWMOutputs(TIM1, ENABLE);
    
        // 使能定时器 1
        TIM_Cmd(TIM1, ENABLE);
    }
    
    .h文件:
    #define SET_MOTOR1_DUTY_CYCLE(x) TIM_SetCompare1(TIM1, x)
    
    main.c文件:
    int main(void)
    {
        /* Timer pwm Init */
        TIM1_PWM_Init(100-1, 72-1);
        TIM2_PWM_Init(100-1, 72-1);
    
        while(1)
        {
            SET_MOTOR1_DUTY_CYCLE(29);
            SET_MOTOR2_DUTY_CYCLE(29);
       }
    }
    

    五、psc、pwm周期(T)及频率(f)

    arr

    代表定时器的自动重装载值。当定时器的计数值达到 arr 时,定时器会重新从 0 开始计数,同时会产生一个更新事件。这个值决定了 PWM 信号的周期。

    psc

    用于设置定时器的预分频器值。预分频器的作用是对定时器的时钟源进行分频,降低定时器的计数频率。

    周期(T) = 1 / 频率(f)

    综述:

    假设系统时钟为 72MHz,APB2 总线时钟也为 72MHz,定时器 1 的时钟源来自 APB2 总线,其时钟频率为 72MHz。

    预分频器的作用:psc = 71 表示将定时器 1 的时钟源进行 72 分频(预分频器的值加 1),即定时器 1 的计数频率为 72MHz / (71 + 1) = 1MHz,也就是每个计数周期为 1us。

    自动重装载值的作用:arr = 999 表示定时器 1 从 0 开始计数,当计数值达到 999 时,会产生一个更新事件,然后重新从 0 开始计数。因此,定时器 1 的计数周期为 (999 + 1) * 1us = 1ms,这也就意味着生成的 PWM 信号的周期为 1ms,频率为 1 / 1ms = 1kHz。

    综上所述,通过将 arr 设置为 999,psc 设置为 71,可以使定时器 1 生成频率为 1kHz 的 PWM 信号。你可以根据实际需求调整这两个参数的值,从而改变 PWM 信号的频率。

    六、针对本章节如何计算arr及psc的值

    那我们来实际反推一下,假设现在想要马达20khz的频率,arr和psc分别是多少?

    前提条件:

    时钟频率为72MHz,psc我们自己设定为72-1,马达频率设置为20khz,就剩下arr需要我们计算了。

    这里注意:psc和arr都是有范围的,切记计算出来的值不可以超范围!

    PWM的周期(T) = 1 / (72MHZ / (psc + 1))* (arr + 1);

    PWM的频率(f) = 20KHZ = 1 / T = 1 / (1 / (72MHZ / (psc + 1))* (arr + 1)) = 72MHZ / ((psc + 1))* (arr + 1));

    自己带入一个合适的psc的值,就可以得到arr的值了。

    如有侵权,联系删除。

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值