最近在用stm32写硬件驱动,需要用到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这一对高低电平相反的互补波形