无刷电机FOC (一)STM32TIM定时器
本文介绍了基于STM32F407的无刷电机FOC控制中PWM定时器的配置方法。主要内容包括:1)TIM时钟频率的计算方法,说明APB总线分频对定时器时钟的影响;2)定时器初始化流程,对比F4与F103系列在GPIO复用配置上的差异;3)提供完整的PWM初始化代码示例,使用TIM1产生三路PWM输出;4)详细讲解PWM频率和占空比的计算公式,以及不同计数模式、输出模式对PWM波形的影响。文章通过具体
写这篇文章是为了对最近学习无刷电机FOC的一些学习心得进行记录,本文基于STM32F407标准库函数编写。
TIM时钟频率
知道TIM的时钟频率是相当重要的,这关系到定时器计数周期和预分频器的值怎么给。这里使用高级定时器TIM1作为PWM输出,在STM32F407中TIM1是挂在APB2总线上,TIM1的时钟频率与APB2总线分频系数有关,若APB2总线分频系数为1,那么TIM1时钟频率为APB2的时钟频率,若APB2总线分频系数不为1,那么TIM1时钟频率为APB2的时钟频率的2倍。而挂在APB1总线上的TIM2也是同理。
如果使用的是默认设置,那么APB1总线时钟为4分频即42M,APB2总线时钟为2分频即84M,即TIM2时钟频率为84MHZ,TIM1时钟频率为168MHZ。
定时器初始化
STM32F407单片机定时器初始化与F103系列相比变化不大。其主要流程如下:
1.TIM时钟初始化
2.GPIO初始化
与f103系列不同,f4系列GPIO初始化时把GPIO口的复用、输入/出、上/下拉分开了,需要单独设置,且f4系列GPIO速度最大为100MHZ。
3.GPIO复用映射
在f103系列中,TIM1输出PWM的默认IO口为PA8、PA9、PA10、PA11,如果要使用PE9、PE11、PE13、PE14作为PWM的GPIO口输出,需要打开AFIO时钟,设置完全映射或部分映射。
但在f407系列中则取消了默认IO口,无论是使用PA口作为PWM输出,还是使用PE口,都需要使用GPIO_PinAFConfig(GPIOx,GPIO_PinSourcex,功能(比如定时器1GPIO_AF_TIM1,串口GPIO_AF_USART1))函数进行设置。
4.定时器初始化
5.定时器OC初始化
6.定时器PWM使能
代码
#include "stm32f4xx.h" // Device header
#define FOC_PWM_RCC RCC_APB2Periph_TIM1//TIM时钟
#define FOC_PWM_GPIO_RCC RCC_AHB1Periph_GPIOE//GPIOE时钟
#define FOC_PWM_GPIO GPIOE
#define FOC_PWM_GPIO_CH1 GPIO_Pin_9
#define FOC_PWM_GPIO_CH2 GPIO_Pin_11
#define FOC_PWM_GPIO_CH3 GPIO_Pin_13
#define FOC_PWM_GPIO_CH1_PS GPIO_PinSource9
#define FOC_PWM_GPIO_CH2_PS GPIO_PinSource11
#define FOC_PWM_GPIO_CH3_PS GPIO_PinSource13
#define FOC_PWM_TIM TIM1
#define FOC_PWM_GPIO_AF GPIO_AF_TIM1
#define FOC_PWM_TIM_Period 8400-1 //计数周期,即ARR值
#define FOC_PWM_TIM_Prescaler 1 - 1 //预分频器,即PSC的值
#define FOC_PWM_TIM_Mode TIM_OCMode_PWM2
#define FOC_PWM_TIM_CounterMode TIM_CounterMode_CenterAligned1
void PWM_Init(){
RCC_APB2PeriphClockCmd(FOC_PWM_RCC,ENABLE);
RCC_AHB1PeriphClockCmd(FOC_PWM_GPIO_RCC,ENABLE);
//将PE9、PE11、PE13设置为复用推挽输出,下拉模式
//在硬件上一个PWM控制一个桥臂,即一个PWM输出口同时连接到栅极驱动芯片的HO和LO
//PWM为高电平时上管打开下管关闭,PWM为低电平时上管关闭下管打开
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;//复用
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;//推挽输出
GPIO_InitStruct.GPIO_Pin=FOC_PWM_GPIO_CH1|FOC_PWM_GPIO_CH2|FOC_PWM_GPIO_CH3;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;//下拉
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
GPIO_Init(FOC_PWM_GPIO,&GPIO_InitStruct);
TIM_InternalClockConfig(FOC_PWM_TIM);
GPIO_PinAFConfig(FOC_PWM_GPIO, FOC_PWM_GPIO_CH1_PS, FOC_PWM_GPIO_AF);
GPIO_PinAFConfig(FOC_PWM_GPIO, FOC_PWM_GPIO_CH2_PS, FOC_PWM_GPIO_AF);
GPIO_PinAFConfig(FOC_PWM_GPIO, FOC_PWM_GPIO_CH3_PS, FOC_PWM_GPIO_AF);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频
TIM_TimeBaseInitStructure.TIM_CounterMode = FOC_PWM_TIM_CounterMode;
TIM_TimeBaseInitStructure.TIM_Period = FOC_PWM_TIM_Period ; //计数周期,即ARR的值
TIM_TimeBaseInitStructure.TIM_Prescaler = FOC_PWM_TIM_Prescaler; //预分频器,即PSC的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器
TIM_TimeBaseInit(FOC_PWM_TIM, &TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = FOC_PWM_TIM_Mode; //输出比较模式,选择PWM模式1
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC1Init(FOC_PWM_TIM, &TIM_OCInitStructure);
TIM_OC2Init(FOC_PWM_TIM, &TIM_OCInitStructure);
TIM_OC3Init(FOC_PWM_TIM, &TIM_OCInitStructure);
TIM_CtrlPWMOutputs(FOC_PWM_TIM,ENABLE);
TIM_Cmd(FOC_PWM_TIM, ENABLE); //使能定时器
}
void PWM_Channel1(int Compare)
{
TIM_SetCompare1(FOC_PWM_TIM, Compare);
}
void PWM_Channel2(int Compare)
{
TIM_SetCompare2(FOC_PWM_TIM, Compare);
}
void PWM_Channel3(int Compare)
{
TIM_SetCompare3(FOC_PWM_TIM, Compare);
}
PWM频率计算
在上述TIM初始化过程中,需要注意几个参数:TIM_Period (计数周期,即ARR的值)、TIM_Prescaler(预分频器,即PSC的值)、TIM_CounterMode (TIM计数模式)、TIM_OCMode(PWM输出比较模式)、TIM_OCPolarity(输出极性),CCR(通过TIM_SetComparex设置,比较值)
TIM_Period 、TIM_Prescaler和CCR决定了TIM输出PWM的频率,其计算公式如下:
PWM频率=168MHZ(ARR+1)(PSC+1) PWM频率= \frac{168MHZ}{(ARR+1)(PSC+1)} PWM频率=(ARR+1)(PSC+1)168MHZ
PWM占空比=CCR(ARR+1)(与PWM输出模式,计数模式有关) PWM占空比= \frac{CCR}{(ARR+1)} (与PWM输出模式,计数模式有关) PWM占空比=(ARR+1)CCR(与PWM输出模式,计数模式有关)
PWM的工作原理
TIM_CounterMode有三种模式:向上计数模式、向下计数模式、中央对齐模式123
以向上计数模式为例:
定时器从0开始计数,每记一次CNT(计数器当前值)加1,在计数过程中,STM32硬件会不断地将CNT的值与CCR的值进行比较,当CNT的值与CCR的值相等时GPIO口电平翻转,当CNT加到ARR值时CNT置为0重新开始计数。
TIM_OCMode有两种模式:PWM模式1和PWM模式2。
PWM模式1:无论向上计数还是向下计数,一旦CNT<CCR时通道为有效电平,否则为无效电平
PWM模式2:无论向上计数还是向下计数,一旦CNT<CCR时通道为无效电平,否则为有效电平;
TIM_OCPolarity有两种模式:TIM_OCPolarity_High和TIM_OCPolarity_Low,这决定了有效电平是高电平或者低电平。
TIM_OCPolarity_High:有效电平为高电平,无效电平为低电平。
TIM_OCPolarity_Low:有效电平为低电平,无效电平为高电平。
例如,将ARR设为84-1,PSC设为100-1,TIM_OCMode为PWM模式1,TIM_CounterMode为向上计数模式,TIM_OCPolarity为TIM_OCPolarity_High,CCR为60。
这样PWM频率=168MHZ84∗100=20000=20KHZ PWM频率= \frac{168MHZ}{84*100} =20000=20KHZ PWM频率=84∗100168MHZ=20000=20KHZ
由于PSC设为100-1,所以在CNT从0计数到100的过程中,CNT的值会与CCR(60)的值进行比较,当
CNT<CCR时,PWM为模式1,通道为有效电平,为高电平,当CNT>CCR时,通道为无效电平,为低电平。当CNT计数到100时,此时CNT会立刻清0,此时CNT<CCR,GPIO口重新由低电平翻转为高电平。在CNT计数到100的过程中,从0加到60都为高电平,因此PWM占空比为
PWM占空比=60(ARR+1)=60% PWM占空比= \frac{60}{(ARR+1)} =60\% PWM占空比=(ARR+1)60=60%
FOC定时器PWM设置
如果你是使用六部换向调制或者SPWM(正选波调制)来驱动无刷电机的话,那么只需要向上面例子那样将TIM_OCMode为PWM模式1,TIM_CounterMode为向上计数模式,TIM_OCPolarity为TIM_OCPolarity_High即可。但在FOC中,大多使用SVPWM调制方法,这需要产生一个中央对称的PWM波形,如图所示
每两个虚线为一个计数周期,SVPWM为了产生一个这样中心对齐的PWM,需要将TIM_CounterMode设为中央对齐模式1,这个模式下CNT会从0加计数到ARR,然后在减计数到0。(中央对齐模式2会从ARR的值先减到0在加)为了使中央为高电平,需要将PWM模式设为模式2,将TIM_OCPolarity设为TIM_OCPolarity_High,这样在CNT<CCR使为无效电平,为低电平,当CNT>CCR使为有效电平,为高电平。
这样设置会使PWM频率是用上述公式计算出的值的一半。
更多推荐



所有评论(0)