2_foc开环控制详细流程

       上次是使用DMA与ADC采样相电流,后面经过验证,开环让电机转动可以提给一个固定的相电流。

a5db91442ccf6a76b61bc57f889ffd46.png

       iα和iβ手动给一个固定值,经过Clarke(结合基尔霍夫定律)变换,再经过Park变换、反Park变换,最后将输出的电压给到SVPWM模块。即实际控制中需要获取到电流,再反Park前电流一般会经过PI控制器。

       开环控制配置的几个部分如下:

1、3路PWM波控制

       我的流程是定时器1直接配置的3路PWM,注意要给驱动配置死区,这块的时间配置之后可以搜集一些资料。定时器1的技术模式采用TIM_CounterMode_CenterAligned2;定时器频率为每秒10K个数,MOS的开关频率是16k。

       代码如下:

void  Tim1_PWM_Init(void)    
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef       TIM_OCInitStructure;
  TIM_BDTRInitTypeDef     TIM_BDTRInitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;


  TIM1_Gpio();


 ///


  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned2;            //  Ôö¼ÆÊýģʽ
  //  MOS开关频率168000/ 10500 = 16k   168000/ 16800 = 10k
  TIM_TimeBaseStructure.TIM_Period = 168000 / PWM_FREQ - 1;      
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;                 
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;     
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);     


  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;    
  TIM_OCInitStructure.TIM_Pulse = 5000;               
 


  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High ;  
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; 
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);                        
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);
  TIM_OC3Init(TIM1, &TIM_OCInitStructure);


  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);              
  TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
  TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);


  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;


  TIM_BDTRInitStructure.TIM_DeadTime = 0x6A;                   
  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable
  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;       
  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;    
  TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);      


  TIM_ClearFlag(TIM1, TIM_FLAG_Update); 
  TIM_ClearITPendingBit(TIM1, TIM_IT_Update); 
  TIM_ITConfig(TIM1,TIM_IT_Update ,ENABLE);        
}

2、三相电机芯片DRV8313

       这个了解的不多,直接贴现成的代码吧。

void DRV8313_GPIO(void)
{
       GPIO_InitTypeDef GPIO_InitStructure;
       EXTI_InitTypeDef EXTI_InitStructure;
       RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);


       GPIO_InitStructure.GPIO_Pin = SLEEP_GPIO_PIN;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
       GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;    
       GPIO_Init(SLEEP_GPIO_PORT, &GPIO_InitStructure);
       GPIO_SetBits(SLEEP_GPIO_PORT, SLEEP_GPIO_PIN);


       GPIO_InitStructure.GPIO_Pin = RESET_GPIO_PIN;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
       GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
       GPIO_Init(RESET_GPIO_PORT, &GPIO_InitStructure);
       GPIO_SetBits(RESET_GPIO_PORT, RESET_GPIO_PIN);


       GPIO_InitStructure.GPIO_Pin = FAULT_GPIO_PIN;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
       GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
       GPIO_Init(FAULT_GPIO_PORT, &GPIO_InitStructure);      
}

3、电角度的设置

       作为重要的输入参数,本次开环测试中手动给定累加。

While(1){
  Key_Scanning();    
  Anglee += 8;
  if(Anglee >= 4000){
    Anglee = 0;
  }
  printf("%d \n", Anglee);
  switch (MYSTATE) {
  case RUN: {      
    FOC_Model();
    break;      
  }
  case STOP:                             
  break;
  default:
  break;
  }
  Delay(10);
}

4、Park、Clarke变换以及SVPWM

       ①手动给定采样电流:

         I_AB.I1=12;  //

         I_AB.I2=74;

 ②Clarke变换

  I_alfb.I1 = I_AB.I1; 

  I_alfb.I2= I_AB.I1*0.5773503+I_AB.I2*1.1547005;

  上次笔记后面有给出直接的结论。

③查表进行正余弦计算

  Cosine = Trig_Functions(Anglee);

④Park变换

I_dq.I1 = ((I_alfb.I1 * Cosine.hCos) + (I_alfb.I2 * Cosine.hSin));  //Id
I_dq.I2 = ((I_alfb.I2 * Cosine.hCos) - (I_alfb.I1 * Cosine.hSin));  //Iq

⑤手动给定参考电压后反Park变换

Volt_dq.V2=0.6;
Volt_dq.V1=0;
Volt_alfb.V1 = (Volt_dq.V1 * Cosine.hCos - Volt_dq.V2 * Cosine.hSin);//
Volt_alfb.V2 = (Volt_dq.V1 * Cosine.hSin + Volt_dq.V2 * Cosine.hCos);//

⑥SVPWM模块

SVPWM_algorithm(Volt_alfb);
void SVPWM_algorithm(Volt_Components Volt_alfb)
{    
       u8 bSector=0;
       s32 T1,T2,wX,wY,wZ;
       u32 tempT;
       u16 TA,TB,TC;
       Time_Components TIME_CCR;


       bSector=0;
       if(Volt_alfb.V2>0)bSector=bSector+1;
       if((Volt_alfb.V1*1.7320508-Volt_alfb.V2)>0)bSector=bSector+2;
       if((Volt_alfb.V1*1.7320508+Volt_alfb.V2)<0)bSector=bSector+4;


   wX = TIME_PERIOD*(Volt_alfb.V2*1.7320508)/Volt_DC;   
   wY = TIME_PERIOD*(Volt_alfb.V1*1.5+Volt_alfb.V2*0.8660254)/Volt_DC;
   wZ = TIME_PERIOD*(Volt_alfb.V2*0.8660254-Volt_alfb.V1*1.5)/Volt_DC;
       
       switch(bSector){ 
              case SECTOR_1:
                     T1=       wZ;
                     T2=       wY;    
                     break;


              case SECTOR_2:
                     T1=       wY;
                     T2=       -wX;
                     break;
              case SECTOR_3:
                     T1=       -wZ;
                     T2=       wX;
                     break;


              case SECTOR_4:
                     T1=       -wX;
                     T2=       wZ;
                     break;


              case SECTOR_5:
                     T1=       wX;
                     T2=       -wY;
                     break;


              case SECTOR_6:
                     T1=       -wY;
                     T2=       -wZ;
                     break;


              default:   ///0    
                     break;


       }


       if(T1<0)
          T1=0;
       if(T2<0)
          T2=0;


       tempT=T1+T2;
       if(tempT>TIME_PERIOD)
       {
              T1=T1*TIME_PERIOD/tempT;
              T2=T2*TIME_PERIOD/tempT;             
       }




       TA=(TIME_PERIOD-T1-T2)/4;
       TB=TA+T1/2;//  
       TC=TB+T2/2;//


       switch(bSector)      
       { 
              case SECTOR_1:
                     TIME_CCR.TIME1=TB;
                     TIME_CCR.TIME2=TA;
                     TIME_CCR.TIME3=TC;    
                     break;


              case SECTOR_2:
                     TIME_CCR.TIME1=TA;
                     TIME_CCR.TIME2=TC;
                     TIME_CCR.TIME3=TB;
                     break;


              case SECTOR_3:
                     TIME_CCR.TIME1=TA;
                     TIME_CCR.TIME2=TB;
                     TIME_CCR.TIME3=TC;
                     break;


              case SECTOR_4:
                     TIME_CCR.TIME1=TC;
                     TIME_CCR.TIME2=TB;
                     TIME_CCR.TIME3=TA;
                     break;


              case SECTOR_5:
                     TIME_CCR.TIME1=TC;
                     TIME_CCR.TIME2=TA;
                     TIME_CCR.TIME3=TB;
                     break;


              case SECTOR_6:    
                     TIME_CCR.TIME1=TB;
                     TIME_CCR.TIME2=TC;
                     TIME_CCR.TIME3=TA;
                     break;


              default://0
                     TIME_CCR.TIME1=TIME_PERIOD/4;
                     TIME_CCR.TIME2=TIME_PERIOD/4;
                     TIME_CCR.TIME3=TIME_PERIOD/4;
                     break;


   }
          
       if(TIME_CCR.TIME1<0)       //Ô½½ç´¦Àí
              TIM1->CCR1=0;
       else if(TIME_CCR.TIME1>PWM_PERIOD)//Ô½½ç´¦Àí
              TIM1->CCR1=PWM_PERIOD;
       else
              TIM1->CCR1 = TIME_CCR.TIME1;


       if(TIME_CCR.TIME2<0)
              TIM1->CCR2=0;
       else if(TIME_CCR.TIME2>PWM_PERIOD)
              TIM1->CCR2=PWM_PERIOD;    
       else
              TIM1->CCR2= TIME_CCR.TIME2;


       if(TIME_CCR.TIME3<0)
              TIM1->CCR3=0;
       else if(TIME_CCR.TIME3>PWM_PERIOD)
              TIM1->CCR3=PWM_PERIOD;
       else
              TIM1->CCR3= TIME_CCR.TIME3;
}

这块理解可以直接看《现代永磁同步电机控制原理及MATLAAB仿真》(袁雷),书中直接给出计算流程,一些其他的流程可以看《SVPWM的原理及法则推导和控制算法详解》。

效果如下:

0765a7400cf34ac75400e0a88cefcf5e.gif

             欢迎关注:

d685d1a8b12175d68c6877f7cf2a614e.png

如需完整代码,赞赏1元后公众号留言自动发送。附带书籍和其他资料。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值