STM32 使用IQmath实现SVPWM 正弦波无刷电机控制

         带有浮点运算的MCU在市场上已经越来越多了,但是便宜好开发的却没有。可不可以使用我们常用的ST的103系列的MCU来做一个svpwm的控制器呢?当然是可以了,但是直接使用不太行,因为M3内核的MCU不具备浮点运算功能,F4系列的具有浮点运算功能,可惜价格不便宜,假货还挺多。在这里介绍一下TI的浮点运算库,IQmath。以及如何应用在SVPWM无刷电机控制,充分降低控制器的成本。

IQmath优势:

        用于定点处理器的数学函数库,加快了计算浮点值的速度。

提供Sin,cos,tan,arcsin,arccos,sqrt,fractional mpy,dv等的计算

在以下应用领域可以提高处理速度:

        电机控制

        伺服控制

        音频/图像编码和解码

        定点Q数学

        图形旋转 :根据应用要求调节分辨率

        指定GLOBAL_Q24:可在定点和浮点器件之间实现代码的无缝兼容性。

我们这里主要是对电机控制的应用,下面我们一起看一下程序。

 case Ready:
         Offset_CurrentReading();     //读取偏移量
         if(AdcValue.OffestFlag ==1 && Keynob == KeyStart)
         {     
           if(Controdmode == Hallloop)
           {
             mcState = Start;
						 IqStartSet = IqStart;
           }
           else 
           {
             mcState = Align;
           }
         }    
      break;

程序中我们在判断控制模式是否为hallloop,紧接着是状态赋值,IqstartSet = Iqstart;

 电机的状态定义了一个enum

typedef enum
{
  Ready,
  Align,
  Start,
  Run,
  Stop,
}McStateTypedef;

IQstart宏定义一个启动电流,调用__IQ().

#define IqStart        _IQ(0.28); //启动电流

在整个控制的过程中主要使用了__IQ(),没有调用其他的函数,下面我们看一下完成的控制部分代码

void MC_Control(void)
{ 
  switch(mcState)
  { 
    case Ready:
         Offset_CurrentReading();     //读取偏移量
         if(AdcValue.OffestFlag ==1 && Keynob == KeyStart)
         {     
           if(Controdmode == Hallloop)
           {
             mcState = Start;
						 IqStartSet = IqStart;
           }
           else 
           {
             mcState = Align;
           }
         }    
      break;
    
    case Align:
         Motor_Align();
         if(TimeStateCount == 0)
         { 
           mcState = Start;   
         }
                  
      break;
    case Start:
         if(Controdmode == Openloop)
         {
              mcState = Run; 
              Angle.Acc_a = _IQ(0.005); //加速度
              Angle.Setp_Max = 50;// 匀速度	          
					    
					 
         }
         else if(Controdmode == Hallloop)
         {  
						if(StateFlag.HallStartSetFlag ==0)
						{
							StateFlag.HallStartSetFlag = 1;
							HallStartAngle();
							Angle.Acc_a = _IQ(0.005); //加速度
							Angle.Setp_Max = 60;// 匀速度	
							Angle.Temp = Hall_Three.ele_angleIQ;
							TimeStateCount = 5000;
						}
						HallStart();
						
            ThreeHallanglecale();//得到角度

						if(TimeStateCount == 0)
						{
						 mcState = Run;     
						}							     
         }
         else if(Controdmode == SMOloop)
         {   
            if(StateFlag.StartSetFlag == 0)
            {
              StateFlag.StartSetFlag =1;
              TimeStateCount = 5000;
						  Angle.Acc_a = _IQ(0.005); //加速度
              Angle.Setp_Max = 55;// 匀速度
							IqStartSet = IqStart;
						}
						  Motor_IFStart();  
            if(TimeStateCount == 0)
            { 
               mcState = Run;
            }            
         }
      break;
    
    case Run:
         if(Controdmode == Openloop)
         {
              Motor_Open(); 
					    ThreeHallanglecale();//得到角度

         }
         else if(Controdmode == Hallloop)
         { 
              Mode_Hall_loop();    
         }
         else if(Controdmode == SMOloop)
         {
              SMO_SpeedLoop();
         }
      break;
    case Stop: 
         StopMotor();
		     if(Keynob == KeyStart)
					{
					  mcState = Ready;
						StateFlag.AlignSetFlag =0;
						StateFlag.StartSetFlag = 0 ;
						TimeStateCount = 0;
						Hall_Three.OldHall_State = 0;
						PWMZD_count = 0;
						Hall_Three.Speed_RPM = 0;
						Hall_Three.old_ele_angleIQ = 0;
						StateFlag.HallStartSetFlag = 0;
					}
      break;
  }

从实验现象来看,电机转动的还是很流畅。

ky_motor Foc 测试视频

实验开发板:开发板

你可能感兴趣的:(Foc驱动从入门到精通,stm32,单片机,嵌入式硬件)