STM32(十一)脉冲宽度调制(Pulse Width Modulation)-PWM

一、原理通俗讲解

        简单的说,比如你有5V电源,要控制一台灯的亮度,有一个传统办法,就是串联一个可调电阻,改变电阻,灯的亮度就会改变。还有一个办法,就是PWM调节。不用串联电阻,而是串联一个开关。假设在1秒内,有0.5秒的时间开关是打开的,0.5秒关闭,那么灯就亮0.5秒,灭0.5秒。这样持续下去,灯就会闪烁。如果把频率调高一点,比如是1毫秒,0.5毫秒开,0.5毫秒灭,那么灯的闪烁频率就很高。我们知道,闪烁频率超过一定值,人眼就会感觉不到。所以,这时你看不到灯的闪烁,只看到灯的亮度只有原来的一半。
       同理,如果1毫秒内,0.1毫秒开,0.9毫秒灭,那么,灯的亮度就只有原来的10分之一。这就是PWM的基本原理。

二、实现原理

STM32(十一)脉冲宽度调制(Pulse Width Modulation)-PWM_第1张图片

        ARR——自动重装载值,定时器从0~ARR,CCRx与定时器的值进行比较:如果CCRx大,则输出低电平;反之,则输出高电平。通过改变CCRx的值实现高低电平持续的时间(即:脉冲宽度调制),通过改变ARR的值来改变周期。

STM32(十一)脉冲宽度调制(Pulse Width Modulation)-PWM_第2张图片

STM32(十一)脉冲宽度调制(Pulse Width Modulation)-PWM_第3张图片

STM32(十一)脉冲宽度调制(Pulse Width Modulation)-PWM_第4张图片STM32(十一)脉冲宽度调制(Pulse Width Modulation)-PWM_第5张图片STM32(十一)脉冲宽度调制(Pulse Width Modulation)-PWM_第6张图片

STM32 定时器3输出通道引脚

STM32(十一)脉冲宽度调制(Pulse Width Modulation)-PWM_第7张图片

三、PWM输出配置步骤

  •   ①使能定时器3和相关IO口时钟。

      使能定时器3时钟:RCC_APB1PeriphClockCmd();

      使能GPIOB时钟:RCC_APB2PeriphClockCmd();

  •   ②初始化IO口为复用功能输出。函数:GPIO_Init();

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;      

  •   ③如果需要重映射,需要开启AFIO时钟。同时设置重映射。

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
      GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); 

  •   ④初始化定时器:ARR,PSC等:TIM_TimeBaseInit();
  •   ⑤初始化输出比较参数:TIM_OC2Init();
  •   ⑥使能预装载寄存器: TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); 
  •   ⑦使能定时器。TIM_Cmd();
  •   ⑧不断改变比较值CCRx,达到不同的占空比效果:TIM_SetCompare2();

四、代码驱动

#include "pwm.h"
#include "led.h"
 
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM4_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);// 
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //使能GPIO外设时钟使能
	                                                                     	
    //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ; //TIM_CH1&&TIM_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	TIM_TimeBaseStructure.TIM_Period = arr; 
    //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 80K
	TIM_TimeBaseStructure.TIM_Prescaler =psc; 
    //设置用来作为TIMx时钟频率除数的预分频值  不分频
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); 
    //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC1Init(TIM4, &TIM_OCInitStructure);  //TIM4_CH1
	TIM_OC2Init(TIM4, &TIM_OCInitStructure);  //TIM4_CH2
	
	TIM_CtrlPWMOutputs(TIM4,ENABLE);	//MOE 主输出使能	

	TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);  //CH1预装载使能	 
	TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);  //CH2预装载使能	 
	
	TIM_ARRPreloadConfig(TIM4, ENABLE); //使能TIMx在ARR上的预装载寄存器
	
	TIM_Cmd(TIM4, ENABLE);  //使能TIM4
}

 

你可能感兴趣的:(STM32)