无刷直流电机学习笔记8

一、内容

本期学习的主要内容结合前两期FOC的控制原理和MATLAB建模仿真的内容,对有传感器的正弦波控制程序进行一个梳理,承上启下,从而达到更好的学习效果。

二、知识点

1.电流相电流采样方式

针对于FOC方式控制的PMSM,主要有三种相电流采集方式,其名称及特点分别为:

①三电阻法:最基本的、可靠方式;

②单电阻法:一种低成本方式;

③电流传感器法:比较高成本的方式。

而在所给的有传感器的正弦波控制程序中,所选择的的电流采样方式为三个电阻电流取样,参数为THREE_SHUNT。在头文件STM32F10x_MCconf.h中,也给出了另外俩种电流采样方式的参数——SINGLE_SHUNT、ICS_SENSORS,并且在程序中,也给出了相关程序,具体程序如下所示,其中,子函数SVPWM_3ShuntInit()是设置三电阻法的电流取样和PWM周期,而针对于另两种方式的初始化函数SVPWM_IcsInit()和SVPWM_1ShuntInit(),也是对相关参数的初始化,在之后的学习中,可对这两种方式,进行试验学习。

#ifdef THREE_SHUNT //三个电阻电流取样
  SVPWM_3ShuntInit(); //设置电流取样,PWM周期
#elif defined ICS_SENSORS
  SVPWM_IcsInit();
#elif defined SINGLE_SHUNT
  SVPWM_1ShuntInit();
#endif

2.按键扫描程序

当定时器、PID等初始化结束之后,程序正式启动(即上电完成),需进行按键扫描及显示屏显示程序,程序段分别如下所示。从中,可以看出,按键扫描频率为8ms一次,具有消抖功能,且各个按键都具有各自的作用。

void KeyProc()
{ 
    U8 i;
    if(fgKeyDeal == 0)//8ms 检测一次
    {
        return;
    }
    fgKeyDeal=0;
   if(ucKeyPressTime != 0)//长按的时间定义
   {
       ucKeyPressTime--;
   }       
   fgKeyDeal= 0;
   switch(ucKeyDat)  //判断那个键按下
   {
       case 0:
           i = 0;
       break;
       case SetKey:
           i = SetKey;
       break;
       case FunKey:
           i = FunKey;
       break;
       case LeftKey:
           i = LeftKey;
       break;
       case RightKey:
           i = RightKey;
       break;
       case UpKey:
           i = UpKey;
       break;
       case DownKey:
           i =  DownKey;
       break;
       default:
           i = OtherKey;
       break;
    }
    if(i == ucPreKey)//判断是否跟上个键一样
    {
        if(ucKeyDebouce != 0)//去抖动,时间6*8
        {
            ucKeyDebouce--;
            return;
        }
        if(fgBusy)
        {
            if(i == NoKey)
            {
                fgBusy = 0; // 此处处理释放有效键
                ucKeyNew = 0;
                ucKeyOld = 0;
            }
        }
        else
        {
            if((i != NoKey) && (i != OtherKey))
            {
                fgBusy = 1;
                ucKeyNew = i;
                ucKeyOld = i;
            }
        }
    }
    else
    {       
        ucPreKey = i;
        ucKeyDebouce = KeyDebouce2;  // 72ms
    }
    if(ucKeyNew != 0)
    {
        if(ucKeyOld != 0)
        {
            ucKeyOld = 0;
            switch(ucKeyNew)
            {
                case SetKey:                 
                    ProcSetKey();    //不同的按键不同的处理程序//返回按键
                break;
                case FunKey:      
                    ProcFunKey();
                break;
                case LeftKey:               
                    ProcLeftKey();       //下键处理程序             
                break;
                case RightKey:             
                    ProcRightKey(); //右键处理程序
                break;
                case UpKey:                
                    ProcUpKey();        //确认键处理程序       
                break;
                case DownKey:            
                    ProcDownKey(); //左键处理程序  
                break;
                default:
                break;
            }
        }
        else
        {
        }
    }
}

3. 电流传感器法的空间矢量调制

在主函数中,当电机的启动参数和PID参数配置正确之后,电机正常启动,随后进行电流采样,并对其采样过程进行空间矢量调制,以电流传感器法为例,调制函数为SVPWM_IcsCalcDutyCycles (),具体代码如下所示,其基本思路是利用Park逆变换和Clark逆变换,计算与输入值相对应的占空比值。同理,对于另两种电流采样方式来说,都具备这个作用,而针对于三电阻法的空间矢量控制而言,其还具有为下一个周期配置AD转换器和TIM0的作用。

void SVPWM_IcsCalcDutyCycles (Volt_Components
Stat_Volt_Input)
{
   u8 bSector;
   s32 wX,wY, wZ, wUAlpha, wUBeta;
   u16  hTimePhA=0, hTimePhB=0, hTimePhC=0;   
   wUAlpha =Stat_Volt_Input.qV_Component1 * T_SQRT3 ;//park逆变换,?
   wUBeta =-(Stat_Volt_Input.qV_Component2 * T);
   wX =wUBeta;
   wY =(wUBeta + wUAlpha)/2;//clark逆变换
   wZ =(wUBeta - wUAlpha)/2;
  // Sector  calculation from wX, wY, wZ
  if (wY<0)
  {
      if(wZ<0)
      {
          bSector = SECTOR_5;
      }
      else // wZ >= 0
      if(wX<=0)
      {
         bSector = SECTOR_4;
      }
      else // wX > 0
      {         
          bSector = SECTOR_3;
      }
   }
   else //wY > 0
   {
       if(wZ>=0)
       {
           bSector = SECTOR_2;
       }
       else  //wZ < 0
       if(wX<=0)      
       {  
          bSector = SECTOR_6;
       }
       else // wX > 0
       {        
           bSector = SECTOR_1;
       }
    }
    switch(bSector)
    {  
        case SECTOR_1:  //时间区间是0-4-6-7-7-6-4-0
        case SECTOR_4: //时间区间是0-1-3-7-7-3-1-0               
            hTimePhA = (T/8) + ((((T + wX) - wZ)/2)/131072);
            hTimePhB = hTimePhA + wZ/131072;
            hTimePhC = hTimePhB - wX/131072;                                       
        break;
        case SECTOR_2:
        case SECTOR_5:  
            hTimePhA = (T/8) + ((((T + wY) - wZ)/2)/131072);
            hTimePhB = hTimePhA + wZ/131072;
            hTimePhC = hTimePhA - wY/131072;
        break;
        case SECTOR_3:
        case SECTOR_6:               
            hTimePhA = (T/8) + ((((T - wX) + wY)/2)/131072);
            hTimePhC = hTimePhA - wY/131072;
            hTimePhB = hTimePhC + wX/131072;               
        break;
        default:
        break;
    }
    CR1 = hTimePhA; 
    TIM1->CCR2 = hTimePhB;
    TIM1->CCR3 = hTimePhC;
}

4.FOC控制算法实现

为了实现FOC的矢量控制,需要对PMSM的转矩和电流进行调节,从而实现FOC矢量算法。详细代码如下所示,其基本思路是根据电流采样的Ia、Ib,通过矢量对称计算出Ic,并根据Clark和Park变换,计算出Id和Iq,,然后根据参考值 Iqs 和 Ids 来计算 e,并通过PID控制,最后使得电流环和转矩环达到平衡。

void FOC_Model(void)
{
    #ifdef FEED_FORWARD_CURRENT_REGULATION  
        Volt_Components Stat_Volt_q_d_4;
        s32 wtemp;
    #endif
    #if defined HALL_SENSORS
       //Integrate Speed for rotor angle update
        HALL_IncElectricalAngle();
    #endif    
    Stat_Curr_a_b = GET_PHASE_CURRENTS();//取得当前电流ia,ib
    Stat_Curr_alfa_beta = Clarke(Stat_Curr_a_b);//clarke 变换成i_alfa,i_beta
    Stat_Curr_q_d = Park(Stat_Curr_alfa_beta,GET_ELECTRICAL_ANGLE);  
    #ifdef FEED_FORWARD_CURRENT_REGULATION   
        /*loads the Torque Regulator output reference voltage Vqs*/   
        Stat_Volt_q_d_4.qV_Component1 = PID_Regulator(Stat_Curr_q_d_ref_ref.qI_Component1,Stat_Curr_q_d.qI_Component1,&PID_Torque_InitStructure);                                                  
        /*loads the Flux Regulator output reference voltage Vds*/
        Stat_Volt_q_d_4.qV_Component2 = PID_Regulator(Stat_Curr_q_d_ref_ref.qI_Component2,Stat_Curr_q_d.qI_Component2,&PID_Flux_InitStructure);  
        wtemp = (s32)(Stat_Volt_q_d_4.qV_Component1 + Stat_Volt_q_d_3.qV_Component1);
        SATURATION_TO_S16(wtemp);
        at_Volt_q_d.qV_Component1 = (s16)wtemp;  
        wtemp = (s32)(Stat_Volt_q_d_4.qV_Component2 + Stat_Volt_q_d_3.qV_Component2);
        TURATION_TO_S16(wtemp);
        Stat_Volt_q_d.qV_Component2 = (s16)wtemp;
    #else
        /*loads the Torque Regulator output reference voltage Vqs*/   
        Stat_Volt_q_d.qV_Component1 =
        PID_Regulator(Stat_Curr_q_d_ref_ref.qI_Component1,                     
        Stat_Curr_q_d.qI_Component1, &PID_Torque_InitStructure);
        /*loads the Flux Regulator output reference voltage Vds*/
        Stat_Volt_q_d.qV_Component2 = PID_Regulator(Stat_Curr_q_d_ref_ref.qI_Component2,                         
        Stat_Curr_q_d.qI_Component2, &PID_Flux_InitStructure);  
    #endif
        //circle limitation
        RevPark_Circle_Limitation();//限制Stat_Volt_q_d 的值
        /*Performs the Reverse Park transformation,  i.e transforms stator voltages Vqs and Vds into Valpha and Vbeta on a stationary reference frame*/
        Stat_Volt_alfa_beta = Rev_Park(Stat_Volt_q_d);
        /*Valpha and Vbeta finally drive the power stage*/ 
        CALC_SVPWM(Stat_Volt_alfa_beta);
    #ifdef FEED_FORWARD_CURRENT_REGULATION  
        Stat_Volt_q_d_2.qV_Component1 = (s16)((Stat_Volt_q_d_2.qV_Component1*(VOLTAGE_SAMPLING_BUFFER-1)+Stat_Volt_q_d_4.qV_Component1)/LTAGE_SAMPLING_BUFFER);
        Stat_Volt_q_d_2.qV_Component2 = (s16)((Stat_Volt_q_d_2.qV_Component2*(VOLTAGE_SAMPLING_BUFFER-1)+Stat_Volt_q_d_4.qV_Component2)/VOLTAGE_SAMPLING_BUFFER);
    #endif 
    #ifdef FLUX_WEAKENING
        Stat_Volt_q_d_1.qV_Component1 = (s16)((Stat_Volt_q_d_1.qV_Component1*(VOLTAGE_SAMPLING_BUFFER-1)+Stat_Volt_q_d.qV_Component1)/OLTAGE_SAMPLING_BUFFER);
        Stat_Volt_q_d_1.qV_Component2 = (s16)((Stat_Volt_q_d_1.qV_Component2*VOLTAGE_SAMPLING_BUFFER-1)+tat_Volt_q_d.qV_Component2)/OLTAGE_SAMPLING_BUFFER);
    #endif  
}

三、总结

本期的学习主要是在原理和仿真的学习之后,对有传感器的正弦波控制的程序进行进一步的学习理解,总的来说,对有感正弦波部分有了更深的理解。之后的学习将是从有感向无感的过渡。

你可能感兴趣的:(无刷直流电机学习笔记8)