无刷直流电机学习笔记5

一、 内容

本期学习的主要内容是对正弦波有传感器的程序部分进行学习,主要体现在对电流环和相关代码的理解。

二、 知识点

上一期的学习初步认识了PID控制下的三个控制环,分别是速度环、电流环和力矩环,下图为三个闭环的关系图,其中逆变器工作之后,黄色部分的电流环开始工作,根据FOC原理,首先读取电机转动过程中的电流信号Ia、Ib和Ic,三相电流Ia、Ib和Ic 经过各种数学变换最终被转换为Id、Iq 电流分量,然后根据参考值Iqs 和Ids来计算e,最后 SVPWM 模块实现最终对三相定子电压的矢量控制。
无刷直流电机学习笔记5_第1张图片
速度环体现在对转子速度或者位置的检测,而力矩环则是转矩的控制器,给出参考值Iqs 和Ids。相关函数如下:

① 电流采样函数
Curr_Components SVPWM_3ShuntGetPhaseCurrentValues(void)
{
  Curr_Components Local_Stator_Currents;
  s32 wAux;
  switch (bSector)
  {
      case 4:       //取得在那个扇区时刻读取AD
      case 5:       // Ia = (hPhaseAOffset)-(ADCChannel 11 value)    
               wAux =(s32)(hPhaseAOffset)- ((ADC1->JDR1)<<1);          
                    //Saturation of Ia 
               if (wAux < S16_MIN)
               {
                   Local_Stator_Currents.qI_Component1=S16_MIN;                               
               }  
               else  if (wAux > S16_MAX)
               { 
                   Local_Stator_Currents.qI_Component1= S16_MAX;
               }
               else
               {
                   Local_Stator_Currents.qI_Component1= wAux;
               }
                    // Ib =(hPhaseBOffset)-(ADC Channel 12 value)
               wAux = (s32)(hPhaseBOffset)-((ADC2->JDR1)<<1);
                    // Saturation of Ib
              if (wAux < S16_MIN)
              {
                  Local_Stator_Currents.qI_Component2= S16_MIN;
              }  
              else  if (wAux > S16_MAX)
              { 
                  Local_Stator_Currents.qI_Component2=S16_MAX;
              }
              else
              {         
                  Local_Stator_Currents.qI_Component2= wAux;
              }
           break;
      case 6:
      case 1:     //Current on Phase A not accessible     
                  // Ib =(hPhaseBOffset)-(ADC Channel 12 value)
              wAux = (s32)(hPhaseBOffset)-((ADC1->JDR1)<<1);
                 //Saturation of Ib  
              if (wAux < S16_MIN)
              {
                  Local_Stator_Currents.qI_Component2= S16_MIN;
              } 
              else  if (wAux > S16_MAX)
              { 
                  Local_Stator_Currents.qI_Component2= S16_MAX;
              }
              else
              {
                  Local_Stator_Currents.qI_Component2=wAux;
              }
                  // Ia = -Ic -Ib 
              wAux =((ADC2->JDR1)<<1)-hPhaseCOffset-Local_Stator_Currents.qI_Component2;
                  //Saturation of Ia
             if (wAux> S16_MAX)
             {
                 Local_Stator_Currents.qI_Component1= S16_MAX;
             }
             else  if (wAux <S16_MIN) 
             {      
                 Local_Stator_Currents.qI_Component1 = S16_MIN;
             }
             else
             {                     
                 Local_Stator_Currents.qI_Component1 = wAux;
             }
         break;
      case 2:
      case 3:     // Ia = (hPhaseAOffset)-(ADC Channel 11 value)     
              wAux =(s32)(hPhaseAOffset)-((ADC1->JDR1)<<1);
                  //Saturation of Ia 
             if (wAux < S16_MIN)
             {
                 Local_Stator_Currents.qI_Component1= S16_MIN;
             }  
             else  if (wAux > S16_MAX)
             { 
                 Local_Stator_Currents.qI_Component1= S16_MAX;
             }
             else
             {
                 Local_Stator_Currents.qI_Component1= wAux;
             }
                   // Ib = -Ic-Ia;
                 wAux =((ADC2->JDR1)<<1)-hPhaseCOffset-Local_Stator_Currents.qI_Component1;
                  // Saturation of Ib
             if (wAux> S16_MAX)
             {
                 Local_Stator_Currents.qI_Component2=S16_MAX;
             }
             else  if (wAux <S16_MIN)
             {     
                 Local_Stator_Currents.qI_Component2 = S16_MIN;
             }
             else  
             {  
                 Local_Stator_Currents.qI_Component2 = wAux;
             }                     
         break;
      default:
      break;
   } 
   return(Local_Stator_Currents); 
}

Curr_Components SVPWM_3ShuntGetPhaseCurrentValues(
)电流采样函数主要是在特定的六个扇区读取状态AD,并且计算出A相和B相的电流值,又由于三相电流矢量之和为0,则可得到C相电流值,为之后的Clark变换做准备工作。

②Clark变换
Curr_Components Clarke(Curr_Components Curr_Input)
{
  Curr_Components Curr_Output;
  s32 qIa_divSQRT3_tmp;
  s32 qIb_divSQRT3_tmp ;
  s16 qIa_divSQRT3;
  s16 qIb_divSQRT3 ;
  // qIalpha = qIas
  Curr_Output.qI_Component1=
  Curr_Input.qI_Component1;
  qIa_divSQRT3_tmp = divSQRT_3 *
  Curr_Input.qI_Component1; //电流平方根3
  qIa_divSQRT3_tmp /=32768;   
  qIb_divSQRT3_tmp = divSQRT_3 *
  Curr_Input.qI_Component2;
  qIb_divSQRT3_tmp /=32768; 
  qIa_divSQRT3=((s16)(qIa_divSQRT3_tmp));       
  qIb_divSQRT3=((s16)(qIb_divSQRT3_tmp));     
  //qIbeta = -(2*qIbs+qIas)/sqrt(3)
  Curr_Output.qI_Component2=(-(qIa_divSQRT3)-(qIb_divSQRT3)-(qIb_divSQRT3));
  return(Curr_Output); 
}

Clark变换是自然坐标系 ABC 变换到静止坐标系α-β的坐标变换,其中,结合原理和程序,我们可知:

           qIalpha = qIas                      式1
           
           qIbeta = -(2*qIbs+qIas)/sqrt(3)            式2

即输出iα和iβ。

③Park变换
Curr_Components Park(Curr_Components Curr_Input,
s16 Theta)
{
  Curr_Components Curr_Output;
  s32 qId_tmp_1, qId_tmp_2;
  s32 qIq_tmp_1, qIq_tmp_2;     
  s16 qId_1, qId_2;  
  s16 qIq_1, qIq_2;   
  Vector_Components = Trig_Functions(Theta);
  //No overflow guaranteed
  qIq_tmp_1 = Curr_Input.qI_Component1 * Vector_Components.hCos;           
  qIq_tmp_1 /= 32768;
  //No
  overflow guaranteed
  qIq_tmp_2 = Curr_Input.qI_Component2 *Vector_Components.hSin; 
  qIq_tmp_2 /= 32768;
  qIq_1 = ((s16)(qIq_tmp_1));
  qIq_2 = ((s16)(qIq_tmp_2));
  //Iq component in Q1.15 Format 
  Curr_Output.qI_Component1 = ((qIq_1)-(qIq_2));
  //No overflow guaranteed
  qId_tmp_1 = Curr_Input.qI_Component1 * Vector_Components.hSin;
  qId_tmp_1 /= 32768;
  //No overflow guaranteed
  qId_tmp_2 = Curr_Input.qI_Component2 * Vector_Components.hCos;
  qId_tmp_2 /= 32768;
  qId_1 = (s16)(qId_tmp_1);             
  qId_2 = (s16)(qId_tmp_2);                                
  //Id component in Q1.15 Format   
  Curr_Output.qI_Component2 = ((qId_1)+(qId_2));  
  return (Curr_Output);
}

Park变换是将静止坐标系α-β变换到同步旋转坐标系d - q的坐标变换,其中,结合原理和程序,我们可知:

  qId=qIalpha_tmp*sin(theta)+qIbeta_tmp*cos(Theta)      式3

  qIq=qIalpha_tmp*cos(Theta)-qIbeta_tmp*sin(Theta)      式4

即输出iq和id。

经过Park变换得到的iq和id,而后经过PID调节、Park的逆变换与SVPWM计算,反馈给逆变器系统,则构成一个完整的电流环。

三、总结

本期主要是对正弦波有感部分程序的学习,总的来说,这段时间由于专业考试较多,相比于之前花的时间和精力少了,所以进展不大。本期学习有收获的地方是进一步学习了程序部分,但是还是不能完全理解。之后的学习重点将从程序学习转向仿真部分,当仿真理解了之后,再来看程序,可能有不一样的收获。

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