带有浮点运算的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 测试视频
实验开发板:开发板