STM32——PWM基本知识及配置过程

STM32——PWM基本知识及配置过程

STM32——PWM基本知识及配置过程
将通用定时器分为四个部分:
      1,选择时钟
      2,时基电路
      3,输入捕获
      4,输出比较
本节定时器PWM输出主要涉及到定时器框图右下方部分,即输出比较部分

和上一讲相同,时基时钟来源于内部默认时钟

对此有疑问请参考 : 定时器中断实验 中 定时器时钟选择部分 和 定时器时钟来源部分

什么是PWM
脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
PWM工作过程
每个定时器有四个通道,每一个通道都有一个捕获比较寄存器, 
将寄存器值和计数器值比较,通过比较结果输出高低电平,实现PWM信号

先简单说明一下: 


如图为向上计数:
     定时器重装载值为ARR,比较值CCRx
     t时刻对计数器值和比较值进行比较
     如果计数器值小于CCRx值,输出低电平
     如果计数器值大于CCRx值,输出高电平
 
PWM的一个周期
    定时器从0开始向上计数
    当0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平
    t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平
    当TIMx_CNT值达到ARR时,定时器溢出,重新向上计数...循环此过程
    至此一个PWM周期完成
 
影响因素
    ARR : 决定PWM周期(在时钟频率一定的情况下,当前为默认内部时钟CK_INT)
    CCRx : 决定PWM占空比(高低电平所占整个周期比例)
PWM工作过程(以通道1为例)


1,TIMx_CCMR1寄存器的OC1M[2:0]位,设置输出模式控制器
    110:PWM模式1
    111:PWM模式2
 
2,计数器值TIMx_CNT与通道1捕获比较寄存器CCR1进行比较,通过比较结果输出有效电平和无效电平
    OC1REF=0 无效电平
    OC1REF=1 无效电平
 
3,通过输出模式控制器产生的信号
TIMx_CCER寄存器的CC1P位,设置输入/捕获通道1输出极性
    0:高电平有效
    1:低电平有效
 
4,TIMx_CCER:CC1E位控制输出使能电路,信号由此输出到对应引脚
    0:关闭
    1:开启
PWM如何输出高低电平
计数器值TIMx_CNT与捕获比较寄存器值CCRx比较后,最终输出高电平还是低电平, 
由TIMx_CCMR1:OC1M位和TIMx_CCER:CC1P位共同决定

1,TIMx_CCMR1寄存器的OC1M[2:0]位,设置PWM模式1或模式2

通过设置模式1或模式2,决定了比较结果输出有效或无效电平

2,TIMx_CCER寄存器的CC1P位,设置输入/捕获通道1输出极性

通过设置输出极性,确定有效或无效电平为最终输出的高电平或低电平

总结:
     模式1:
          CNT<CCR为有效电平 //(OC1REF = 1)
          CNT>CCR为无效电平 //(OC1REF = 0)
     模式2:
          CNT<CCR为无效电平 //(OC1REF = 0)
          CNT>CCR为有效电平 //(OC1REF = 1)
     CC1P:
          0:高电平有效
          1:低电平有效


PWM模式配置

TIM_OC1PreloadConfig函数:
     作用:TIM_CCMRx寄存器OCxPE位使能相应的预装在寄存器
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
 
TIM_ARRPreloadConfig函数:
     作用:操作TIMx_CR1寄存器ARPE位,使能自动重装载的预装载寄存器
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
ARPE的使能-ARR变更生效配置


ARPE=1,ARR立即生效
ARPE=0,ARR下周期生效
定时器3输出通道引脚
定时器3的4个通道对应的引脚及重映射

PWM输出库函数
1,定时器通道初始化-TIM_OC1Init
经过上面的讲解,我们知道了要想使用PWM需要配置

配置参数对应框图位置如下:

1,TIMx_CCMR1寄存器的OC1M[2:0]位,设置输出模式控制器
2,TIMx_CCER寄存器的CC1P位,设置输入/捕获通道1输出极性
3,TIMx_CCER:CC1E位控制输出使能电路,信号由此输出到对应引脚
初始化定时器输出比较通道

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
1
TIM_OCInitTypeDef结构体

typedef struct
{
  uint16_t TIM_OCMode;         // PWM模式1或者模式2
  uint16_t TIM_OutputState;    // 输出使能 OR失能
  uint16_t TIM_OutputNState;   // PWM输出不需要
  uint16_t TIM_Pulse;          // 比较值,写CCRx,可以有次函数
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
写入,这里暂时不设置。 
 uint16_t TIM_OCPolarity; // 比较输出极性 
  uint16_t TIM_OCNPolarity; // PWM输出不需要 
  uint16_t TIM_OCIdleState; // PWM输出不需要 
  uint16_t TIM_OCNIdleState; // PWM输出不需要
 } TIM_OCInitTypeDef;
 

2,设置比较值函数-TIM_SetCompare1
作用:外部改变TIM_Pulse值,即改变CCR的值

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
1
3,使能输出比较预装载-TIM_OC1PreloadConfig
作用:TIM_CCMRx寄存器OCxPE位使能相应的预装在寄存器

void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
1
4,使能自动重装载的预装载寄存器允许位-TIM_ARRPreloadConfig
作用:操作TIMx_CR1寄存器ARPE位,使能自动重装载的预装载寄存器

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
 
5,修改通道极性
作用:操作TIMx_CCER的CC1P位,修改通道极性

void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
1
PWM输出实验
使用定时器3初始PWM信号,输出占空比可变的PWM波驱动LED(PB5引脚),实现LED亮度变换

LED:低电平点亮,高电平熄灭,占空比越大,一个周期中高电平持续时间越长,亮度越大,反之越暗.

查找手册PB5引脚为定时器3的通道2,需要部分重映射

PWM输出实验步骤
1,使能定时器3和相关IO时钟(LED-PB5)
    使能定时器3时钟:RCC_APB1PeriphClockCmd();
    使能GPIOB时钟:RCC_APB2PeriphClockCmd();
 
2,初始化IO口为复用功能输出 GPIO_Init();
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 
3,PB5输出PWM(定时器3通道2),需要部分冲突映射
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟设置
    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);//部分重映射
 
4,初始化定时器 (重装载值ARR,与分频系数PSC等)
    TIM_TimeBaseInit();//决定PWM周期
 
5,初始化输出比较参数:
    TIM_OC2Init();//通道2输出比较初始化
 
6,使能预装载寄存器
    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//定时器3 通道2
 
7,使能定时器
    TIM_Cmd();
 
8,不断改变比较值CCRx,达到不同的占空比效果
    TIM_SetCompare2(); //通道2,改变比较值CCRx
代码实现
基于 定时器中断实验 代码进行编写

timer.h添加PWM初始化函数定义 void TIM3_PWM_Init(u16 arr,u16 psc);

 

#ifndef  __TIMER_H
#define  __TIMER_H
#include "sys.h"
 
void TIM3_PWM_Init(u16 arr,u16 psc);
 
#endif
 

 

timer.c 实现定时器PWM初始化函数

 

#include "timer.h"
 
//TIM3 PWM初始化
//arr   重装载值
//psc   预分频系数
void TIM3_PWM_Init(u16 arr,u16 psc)
{
    GPIO_InitTypeDef     GPIO_InitStrue;
    TIM_OCInitTypeDef     TIM_OCInitStrue;
    TIM_TimeBaseInitTypeDef     TIM_TimeBaseInitStrue;
    
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);        //使能TIM3和相关GPIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);// 使能GPIOB时钟(LED在BP5引脚),使能AFIO时钟(定时器3通道2需要重映射到BP5引脚)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    
    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_5;     // TIM_CH2
    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;    // 复用推挽
    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;    //设置最大输出速度
    GPIO_Init(GPIOB,&GPIO_InitStrue);                //GPIO端口初始化设置
    
    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);
    
    TIM_TimeBaseInitStrue.TIM_Period=arr;    //设置自动重装载值
    TIM_TimeBaseInitStrue.TIM_Prescaler=psc;        //预分频系数
    TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up;    //计数器向上溢出
    TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1;        //时钟的分频因子,起到了一点点的延时作用,一般设为TIM_CKD_DIV1
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue);        //TIM3初始化设置(设置PWM的周期)
    
    TIM_OCInitStrue.TIM_OCMode=TIM_OCMode_PWM2;        // PWM模式2:CNT>CCR时输出有效
    TIM_OCInitStrue.TIM_OCPolarity=TIM_OCPolarity_High;// 设置极性-有效为高电平
    TIM_OCInitStrue.TIM_OutputState=TIM_OutputState_Enable;// 输出使能
    TIM_OC2Init(TIM3,&TIM_OCInitStrue);        //TIM3的通道2PWM 模式设置
 
    TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);        //使能预装载寄存器
    
    TIM_Cmd(TIM3,ENABLE);        //使能TIM3
    
}
主程序的设计:

进行pwm的设置

  TIM_SetCompare2(TIM3,led0pwmval);        //改变比较值TIM3->CCR2达到调节占空比的效果

 

int main(void)
 {    
    u8 i=1;         // 设置方向 0:变暗 1:变亮
    u16 led0pwmval;        // 设置CCR值
    delay_init();             // 延时函数初始化
    LED_Init();                // LED初始化
    TIM3_PWM_Init(899,0); //设置频率为80KHz,公式为:溢出时间Tout=(arr+1)(psc+1)/Tclk
                                                //Tclk为通用定时器的时钟,如果APB1没有分频,则就为系统时钟,72MHZ
                                                //PWM时钟频率=72000000/(899+1) = 80KHZ,设置自动装载值899,预分频系数0(不分频)
    while(1)
    {    
        delay_ms(10);            
        if(i)led0pwmval++;        // 由暗变亮
            else led0pwmval--;        // 由亮变暗
        
        if(led0pwmval==0)i=1;        // 已达到最亮,开始变暗
        if(led0pwmval>100)i=0;    // 已达到最暗,开始变亮
        
        TIM_SetCompare2(TIM3,led0pwmval);        //改变比较值TIM3->CCR2达到调节占空比的效果
        
    }
 }
//此处led0pwmval值最大可以设置到899,输出pwm波基本全为1,大小随意设定。
 

内容概要:本文详细介绍了基于Simulink平台构建的锂电池供电与双向DCDC变换器智能切换工作的仿真模型。该模型能够根据锂离子电池的状态荷电(SOC)自动或手动切换两种工作模式:一是由锂离子电池通过双向DCDC变换器向负载供电;二是由直流可控电压源为负载供电并同时通过双向DCDC变换器为锂离子电池充电。文中不仅提供了模式切换的具体逻辑实现,还深入探讨了变换器内部的电压电流双环控制机制以及电池热管理模型的关键参数设定方法。此外,针对模型使用过程中可能遇到的问题给出了具体的调试建议。 适用人群:从事电力电子、新能源汽车、储能系统等领域研究和技术开发的专业人士,尤其是那些希望深入了解锂电池管理系统及其与电源转换设备交互机制的研究者和工程师。 使用场景及目标:适用于需要评估和优化锂电池供电系统的性能,特别是涉及双向DCDC变换器的应用场合。通过学习本文提供的理论知识和实践经验,可以帮助使用者更好地理解和掌握相关技术细节,从而提高实际项目的设计效率和可靠性。 其他说明:为了确保仿真的准确性,在使用该模型时需要注意一些特定条件,如仿真步长限制、电池初始SOC范围以及变换器电感参数的选择等。同时,对于可能出现的震荡发散现象,文中也提供了一种有效的解决办法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值