一、介绍


        脉冲宽度调制(PWM),是英文 “Pulse Width Modulation”的缩写,简 称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种 非常有效的技术。简单一点,就是对脉冲宽度的控制。 STM32 的定时器除了 TIM6 和 7 。其他的定时器都可以用来产生 PWM 输出。其 中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时 器也能同时产生多达 4路的 PWM 输出,这样, STM32 最多可以同时产生 30 路48 PWM 输出!


        相关重要理论:


        面积等效原理:冲量相等而形状不同的窄脉冲施加在惯性环节上时,其效果基本相同。


二、框图

1、输入捕获

STM32CUBEMX设置PWM输出_STM32CUBEMX设置PWM输出

 输入捕获可以对输入的信号的上升沿、下降沿或者双边沿进行捕获,常用的有测量输入信号的脉宽和测量PWM输入信号的频率和占空比这两种

PWM输入模式是输入捕获的特例,只能使用通道1和通道2,通道3和通道4使用不了。与上面那种只使用一个捕获寄存器测量脉宽和频率的方法相比,PWM输入模式需要占用两个捕获寄存器,




STM32CUBEMX设置PWM输出_stm32_02


当使用PWM输入模式的时候,因为一个输入通道(TIx)会占用两个捕获通道(ICx),所以一个定时器在使用PWM输入的时候最多只能使用两个输入通道(TIx)。我们以输入通道TI1工作在PWM输入模式为例来讲解具体的工作原理,其他通道以此类推即可。PWM信号由输入通道TI1进入,因为是PWM输入模式的缘故,信号会被分为两路:一路是TI1FP1,另外一路是TI2FP2。其中一路是周期,另一路是占空比,具体一路信号对应周期还是占空比,得从程序上设置哪一路信号作为触发输入,作为触发输入的哪一路信号对应的就是周期,另一路就是对应占空比。作为触发输入的那一路信号还需要设置极性,是上升沿还是下降沿捕获。一旦设置好触发输入的极性,另外一路硬件就会自动配置为相反的极性捕获,无需软件配置。一句话概括就是:选定输入通道,确定触发信号,然后设置触发信号的极性即可。因为是PWM输入的缘故,另一路信号则由硬件配置,无需软件配置。使用PWM输入模式的时候必须将从模式控制器配置为复位模式(配置寄存器SMCR的位SMS[2:0]来实现),即当我们启动触发信号开始进行捕获的时候,同时把计数器CNT复位清零。

STM32CUBEMX设置PWM输出_stm32_03

 

当使用PWM输入模式的时候,因为一个输入通道(TIx)会占用两个捕获通道(ICx),所以一个定时器在使用PWM输入的时候最多只能使用两个输入通道(TIx)。我们以输入通道TI1工作在PWM输入模式为例来讲解具体的工作原理,其他通道以此类推即可。PWM信号由输入通道TI1进入,因为是PWM输入模式的缘故,信号会被分为两路:一路是TI1FP1,另外一路是TI2FP2。其中一路是周期,另一路是占空比,具体一路信号对应周期还是占空比,得从程序上设置哪一路信号作为触发输入,作为触发输入的哪一路信号对应的就是周期,另一路就是对应占空比。作为触发输入的那一路信号还需要设置极性,是上升沿还是下降沿捕获。一旦设置好触发输入的极性,另外一路硬件就会自动配置为相反的极性捕获,无需软件配置。一句话概括就是:选定输入通道,确定触发信号,然后设置触发信号的极性即可。因为是PWM输入的缘故,另一路信号则由硬件配置,无需软件配置。使用PWM输入模式的时候必须将从模式控制器配置为复位模式(配置寄存器SMCR的位SMS[2:0]来实现),即当我们启动触发信号开始进行捕获的时候,同时把计数器CNT复位清零。 

2、输出比较

STM32CUBEMX设置PWM输出_嵌入式硬件_04

输出模式控制器:

STM32CUBEMX设置PWM输出_stm32_05

 除此之外还有六种模式但基本不用。

三、代码分析

初始化

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);	//使能定时器4时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO , ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
	
 
 
   //设置该引脚为复用输出功能,输出TIM4 CH2的PWM脉冲波形	GPIOB.7
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM4_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
	
 
   //初始化TIM4
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	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的时间基数单位
	
	//初始化TIM4 Channel 2 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
	TIM_OC2Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC2

	TIM_CtrlPWMOutputs(TIM4,ENABLE);	

	TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR2上的预装载寄存器
 
	TIM_ARRPreloadConfig(TIM4, ENABLE); 
 
	TIM_Cmd(TIM4, ENABLE);  //使能TIM4
	

}

主函数

delay_ms(10);	 
		if(dir)led0pwmval++;
		else led0pwmval--;

 		if(led0pwmval>900)dir=0;
		if(led0pwmval==0)dir=1;										 
		TIM_SetCompare2(TIM4,led0pwmval);