这里使用STM32F407,其他系列可能略有差异
1.IO配置
2定时器配置,FOC必须使用中心对齐模式
重点说明
1.OC输出模式选择,这里只介绍常用的2种
TIM_OCMode_PWM1 :TIMx->CNT小于CCRx值时输出高电平,否则输出低电平(输出极性为高选项时)
TIM_OCMode_PWM2 :TIMx->CNT小于CCRx值时输出低电平,否则输出高电平(输出极性为高选项时)
2.频率设定计算
见另一篇文章https://blog.csdn.net/yuyan7045/article/details/118388326?spm=1001.2014.3001.5501
3.输出极性
PMSM电机控制时,输出极性是要求高电平有效,才能使MOS导通
4.空闲输出状态
PMSM电机控制时,空闲状态输出为低电平,不能让MOS导通
5.刹车与其极性、
6.死区时间计算
死区时间有TIMx_BDTR决定,我实际控制电机时死区=800ns,计算后选择DTG[7:5]=10x......这一项,计算过程如下:
800 =(64+DTG[5:0])*tdtg,tdtg=2*tDTS,tDTS在我的设计中是168MHz,可见代码;
这样算出DTG[5:0]=3.2,向上取整=4;即DTG[5:0]=00 0100,最后DTG[7:0]=1000 0100
代码分享
/******************************************************************************
* 功能:吸气通道控制任务
*
******************************************************************************/
void TIM_Foc_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStre;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStre.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
GPIO_InitStre.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStre.GPIO_OType=GPIO_OType_PP;
GPIO_InitStre.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStre.GPIO_Speed=GPIO_Fast_Speed;
GPIO_Init(GPIOC,&GPIO_InitStre);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM8);
}
/******************************************************************************
* 功能:吸气通道控制任务
*
******************************************************************************/
void TIM_Foc_PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStre;
TIM_OCInitTypeDef TIM_OCInitStre;
TIM_BDTRInitTypeDef TIM_BDTRInitStre;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);
TIM_TimeBaseInitStre.TIM_Prescaler=0;//168/1/2/4200=20khz
TIM_TimeBaseInitStre.TIM_Period=4200-1;//频率=20kHz
TIM_TimeBaseInitStre.TIM_CounterMode=TIM_CounterMode_CenterAligned1;//中心对齐模式1
TIM_TimeBaseInitStre.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
TIM_TimeBaseInitStre.TIM_RepetitionCounter=0;//不重复计数
TIM_TimeBaseInit(TIM8,&TIM_TimeBaseInitStre);//初始化
TIM_OCInitStre.TIM_Pulse=1000;//实际初始化为0,这里是实验是否正确输出
TIM_OCInitStre.TIM_OCMode=TIM_OCMode_PWM2;//PWM模式2
TIM_OCInitStre.TIM_OCPolarity=TIM_OCPolarity_High;//有效输出极性高
TIM_OCInitStre.TIM_OCIdleState=TIM_OCIdleState_Reset;//空闲输出低
TIM_OCInitStre.TIM_OutputState=TIM_OutputState_Enable;//输出使能
TIM_OCInitStre.TIM_OCNPolarity=TIM_OCNPolarity_High;//互补有效输出极性高
TIM_OCInitStre.TIM_OCNIdleState=TIM_OCNIdleState_Reset;//互补空闲输出低
TIM_OCInitStre.TIM_OutputNState=TIM_OutputNState_Enable;//互补输出使能
TIM_OC1Init(TIM8,&TIM_OCInitStre);//初始化
TIM_OCInitStre.TIM_Pulse=2000;//实际初始化为0,这里是实验是否正确输出
TIM_OC2Init(TIM8,&TIM_OCInitStre);//通道2
TIM_OCInitStre.TIM_Pulse=3000;//实际初始化为0,这里是实验是否正确输出
TIM_OC3Init(TIM8,&TIM_OCInitStre);//通道3
TIM_OCInitStre.TIM_Pulse=0;
TIM_OC4Init(TIM8,&TIM_OCInitStre);//暂定通道4进行ADC触发,在电机中间相后延时1-2us再触发ADC
TIM_BDTRInitStre.TIM_DeadTime=132;//800ns死区时间
TIM_BDTRInitStre.TIM_LOCKLevel=TIM_LOCKLevel_OFF;//电平锁定关闭???
TIM_BDTRInitStre.TIM_AutomaticOutput=TIM_AutomaticOutput_Disable;//自动输出失能
TIM_BDTRInitStre.TIM_Break=TIM_Break_Enable;//使能刹车
TIM_BDTRInitStre.TIM_BreakPolarity=TIM_BreakPolarity_High;//刹车有效极性高???
TIM_BDTRInitStre.TIM_OSSIState=TIM_OSSIState_Disable;//
TIM_BDTRInitStre.TIM_OSSRState=TIM_OSSRState_Disable;//
TIM_BDTRConfig(TIM8, &TIM_BDTRInitStre);//初始化
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable);
TIM_CtrlPWMOutputs(TIM8,ENABLE);//PWM输出使能
TIM_ARRPreloadConfig(TIM8,ENABLE);//自动重装载
TIM_Cmd(TIM8,ENABLE);
}