本来打算假期把stm32吃透的怎奈家里的床就像吸铁石,手机里的王者就像农药蚕食我的计划(珍爱生命远离王者)。
那么我提一下目前的在搞的PWM输出吧。因为正在搞四轴飞行器,所以需要四路可调占空比的PWM信号来控制四个无刷电机。所以我需要利用stm32中的TIM4定时器来产生四路PWM。首先说下配置的思路及过程:
1) 开启TIM4和GPIO时钟,配置PB8|PB9|PB10|PB11选择复用功能AF输出
2) 初始化TIM4,设置TIM4的ARR(自动重装载值)和PSC(预分频值 )等参数
3) 设置TIM4_CH1/2/3/4的PWM模式, 使能TIM4的CH1/2/3/4输出
4) 使能TIM4。
5) 修改TIM4_CCR1/2/3/4来控制占空比
好的那么咱们先写PWM初始化程序PWM.c
void PWM(u32 arr,u32 psc,u32 crr1,u32 crr2,u32 crr3,u32 crr4)
{ #include "PWM.h"
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能gpioB时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;//初始化引脚PB8/9/10/11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//设置为复用模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//设置为上拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化gpio
GPIO_PinAFConfig(GPIOF, GPIO_PinSource6, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_TIM4);//映射复用的GPIO口PB8/9/10/11至定时器4
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE);//使能TIM4
TIM_TimeBaseStructure.TIM_Prescaler = psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period = arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //重复寄存器,用于自动更新pwm占空比
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; // 设置互补端输出极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //使能互补端输出
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; // 死区后输出为高
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //死区后互补端输出为低
TIM_OCInitStructure.TIM_Pulse =crr1; //
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse =crr2; //
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse =crr3; //
TIM_OC3Init(TIM4, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse =crr4; //设置四个pwm通道占空比
TIM_OC4Init(TIM4, &TIM_OCInitStructure);
TIM_Cmd(TIM4, ENABLE);
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM4, ENABLE);//使能PWM输出
}
然后是我们的头文件PWM.h
#include "sys.h"
#ifndef PWM_
#def PWM_
PWM(500-1,84-1,20,20,20,20)////定时器时钟为 84M,分频系数为 84,所以计数频率
//为 84M/84=1Mhz,重装载值 500,所以 PWM 频率为 1M/500=2Khz其余的crr1/2/3/4均为20
#enif
接下来在主函数中通过TIM_SetComparex(TIMx,crrx);可以调节占空比
也可以通过改变void PWM(u32 arr,u32 psc,u32 crr1,u32 crr2,u32 crr3,u32 crr4) 后四个参数来改变各通道占空比
函数TIM-SetCompare1(TIM4,30)是将TIM4的第一通道crr1设置为30来控制占空比。
占空比计算公式为(TIM4_CCR1/ TIM4_ARR)* 100%