stm32f4 生成PWM波

最近在用stm32写硬件驱动,需要用到PWM波,并不复杂,下面分享一下如何快速掌握PWM波

目录

一、PWM基础知识

二、PWM波配置与生成

三、多路PWM生成

四、互补PWM生成


一、PWM基础知识

PWM波的生成依赖定时器,在stm32f4xx中有高级定时器、通用定时器、基本定时器之分,它们的配置是不同的,一般为了方便(好改代码)我们选择通用定时器TIM2~TIM14,这么多一般是足够用的,因为每个定时器还有4个通道

二、PWM波配置与生成

首先是通用定时器的配置代码,仅需要修改IO口,定时器数字,定时器通道数字

pwm模式选择暂且按下不表

void OSA_clk_init(u32 arr,u32 psc)
{

	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//修改TIM
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
	

	
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_TIM3);

	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;        //修改IO口              
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;               
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	       
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;           
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;                   
	GPIO_Init(GPIOB,&GPIO_InitStructure);                      
																																					
	
	
	
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 
	TIM_TimeBaseStructure.TIM_Period=arr;   
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); 
	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 

	TIM_OC3Init(TIM3, &TIM_OCInitStructure); //修改定时器通道

	TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  
 
	
	TIM_Cmd(TIM3, ENABLE);  
	

}

 产生PWM波代码写在main文件里

int main(void)
{ 
	OSA_clk_init(42-1,2-1);//修改arr和psc	
	while(1)
	{	
	    TIM_SetCompare3(TIM3,21);//修改比较值+定时器通道
    }
}
	

这里是生成pwm波的关键,需要修改arr和psc,以及比较值 

 一个pwm周期 =(psc+1)*(arr+1)/主频

psc是预分频系数,决定一次计数的时间

arr是计数值,决定计数的个数

所以用 arr * psc  就是计数个数 * 单次计数时间,这里不用纠结,只要两者乘积是你期望的数字就可以,可以任意拆分

Stm32F407主频(即CPU的时钟频率):168MHZ

PWM比较值=arr * n%

比较值其实就是PWM的占空比,n%就是想要%多少的高电平,比如arr=10, 我要占空比50%(高低电平相同)那我的n%就是50%,比较值为5;我想要高电平20%,低电平80%,那n%就是20%,比较值为2

此外,比较值的修改与PWM的模式也有关

PWM模式有PWM1和PWM2两种
我简单理解就是,想输出波形是同样时间的高电平,PWM1模式下的arr是n%,PWM2模式下的arr是1-n%

三、多路PWM生成

根据上面的代码,复制粘贴,修改函数的名称并进行声明,再把里面的IO等按照需求进行修改

最后在main函数里面重复操作即可

int main(void)
{ 
	OSA_clk_init(42-1,2-1);//修改arr和psc
    OSA_reset_init(100-1,2-1);//修改arr和psc	
	while(1)
	{	
	    TIM_SetCompare3(TIM3,21);//修改比较值+定时器通道
        TIM_SetCompare2(TIM3,5);
    }
}
	

 这里有个小tip,如果想要生成的波上升沿是对齐的,就要把psc设置成同一个数

四、互补PWM生成

PWM模式有PWM1和PWM2两种

PWM1 模式:向上计数,当 TIMx_CNT < TIMx_CCRn 时,定时器 TIMx 的通道 n 为有效电平,否则为无效电平;向下计数,当 TIMx_CNT > TIMx_CCRn 时,定时器 TIMx 的通道 n 为无效电平,否则为有效电平。

PWM2 模式:向上计数,当 TIMx_CNT < TIMx_CCRn 时,定时器 TIMx 的通道 n 为无效电平,否则为有效电平;向下计数,当 TIMx_CNT > TIMx_CCRn 时,定时器 TIMx 的通道 n 为有效电平,否则为无效电平。

想要得到A波形的互补波形,哪里都不要动,只修改PWM模式,原先是1就改成2,原先是2就 改成1,输出B波形

你就可以得到A与B这一对高低电平相反的互补波形


版权声明:本文为weixin_46188211原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。