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