在电机控制中矢量输出主要由三部分构成,一是速度控制块;二是角度控制块,三是矢量计算输出。
速度控制结构
typedef struct {
s32 TargetValue; // Input: Target input (pu)
u32 RampDelayMax; // Parameter: Maximum delay rate (Q0) - independently with global Q
s32 RampLowLimit; // Parameter: Minimum limit (pu)
s32 RampHighLimit; // Parameter: Maximum limit (pu)
u32 RampDelayCount; // Variable: Incremental delay (Q0) - independently with global Q
s32 SetpointValue; // Output: Target output (pu)
u32 EqualFlag; // Output: Flag output (Q0) - independently with global Q
s32 Tmp; // Variable: Temp variable
} RMPCNTL;
定义一个速度控制块
RMPCNTL rap_cntl = RMPCNTL_DEFAULTS;
RMPCNTL *p_rap_cntl = &rap_cntl;
调用速度控制函数,设置目标速度:
p_rap_cntl->TargetValue = SpeedRef;//目标速度 此处目标速度采用Q15定标 即#define Q15 32768 最大速度对应32768
RC_Cal(p_rap_cntl);//加减速控制块
线性加减速函数实现,在该函数中可以实现不同的加减速曲线,使得运行曲线更为平滑
void RC_Cal(RMPCNTL *v)
{
v->Tmp = v->TargetValue - v->SetpointValue; //Q15
/* 0.0000305 is resolution of Q15 */
if (abs_1(v->Tmp) >= Q4)//最小速度误差 Q4 即 #define Q4 16
{
v->RampDelayCount++ ;
if (v->RampDelayCount >= v->RampDelayMax)//速度给定延时
{
if (v->TargetValue >= v->SetpointValue)//线性加减速
v->SetpointValue += Q4;
else
v->SetpointValue -= Q4;
v->SetpointValue=SatLimit(v->SetpointValue,v->RampHighLimit,v->RampLowLimit);//速度上线限定
v->RampDelayCount = 0;
}
}
else v->EqualFlag = 0x7FFFFFFF;
}
角度生成模块
角度模块为速度模块的积分,其实现结构如下:
typedef struct {
s32 Freq; // Input: Ramp frequency (pu)
s32 StepAngleMax; // Parameter: Maximum step angle (pu)
s32 Angle; // Variable: Step angle (pu)
s32 Gain; // Input: Ramp gain (pu)
s32 Out; // Output: Ramp signal (pu)
s32 Offset; // Input: Ramp offset (pu)
s32 Angle_L; // Variable: Step angle (pu)
} RAMPGEN;
定义
RAMPGEN rg1 = RAMPGEN_DEFAULTS;
RAMPGEN *p_rg1 = &rg1;
调用
p_rg1->Freq = p_rap_cntl->SetpointValue;
RG_Cal(p_rg1); //angle
实现
void RGInit(RAMPGEN *v)
{
v->StepAngleMax = 2*Q14*F1Max/F2Set;//最大步进角度 F1Max是最大电气频率,F2Set为载波频率,Q14为角度定标 #define Q14 16384 对应180度,比如载波频率1K,最大电频率100Hz,那么最大步进叫度则为360/(1K/100) = 36度 归一化之后则是Q14*(360/(F2Set/F1Max))/180 =>Q14*(2*F1Max/F2Set);
v->Angle_L = 0;
}
void RG_Cal(RAMPGEN *v)
{
/* Compute the angle rate */
/*此处即求余也求商目的是防止积分累计时舍去误差过大,将余数累计避免余数舍去时造成较大误差*/
v->Angle += (v->StepAngleMax*v->Freq)/32768;
v->Angle_L += (v->StepAngleMax*v->Freq)%32768;
if(v->Angle_L > 32768 )
{
v->Angle+=1;
v->Angle_L -= 32768;
} \
/* Saturate the angle rate within (-1,1) 控制角度范围*/
if(v->Angle > Q14)
{
v->Angle = v->Angle - Q14;
}else if(v->Angle < -Q14)
{
v->Angle = Q14- v->Angle;
}
}
加入dq值之后进行坐标变换
p_ipark1->Angle = p_rg1->Angle;
p_ipark1->Sine = SinQ14(p_rg1->Angle); //Q15
p_ipark1->Cosine = CosQ14(p_rg1->Angle);
p_ipark1->Ds = VdTesting = Q15;//Q15
p_ipark1->Qs = VqTesting = Q15;
p_ipark1->Sine= p_ipark1->Sine;
p_ipark1->Cosine= p_ipark1->Cosine;
IPARK_Cal(p_ipark1);
p_svgen1->Ualpha = p_ipark1->Alpha/Q15;
p_svgen1->Ubeta = p_ipark1->Beta/Q15;
SVPWM处理结构
SVPWM处理结构
typedef struct {
s32 Ualpha; // Input: reference alpha-axis phase voltage
s32 Ubeta; // Input: reference beta-axis phase voltage
s32 Ta; // Output: reference phase-a switching function
s32 Tb; // Output: reference phase-b switching function
s32 Tc; // Output: reference phase-c switching function
s32 tmp1; // Variable: temp variable
s32 tmp2; // Variable: temp variable
s32 tmp3; // Variable: temp variable
s32 VecSector; // Space vector sector
} SVGEN;
输入alpha beta轴参数,计算三个矢量的作用时间(Ta,Tb,Tc)
void SvTimeCal(SVGEN *v)
{
v->tmp1= v->Ubeta;
v->tmp2= v->Ubeta/2 + 866*v->Ualpha/1000;
v->tmp3= v->tmp2 - v->tmp1;
v->VecSector=3;
v->VecSector=(v->tmp2> 0)?( v->VecSector-1):v->VecSector;
v->VecSector=(v->tmp3> 0)?( v->VecSector-1):v->VecSector;
v->VecSector=(v->tmp1< 0)?(7-v->VecSector) :v->VecSector;
if(v->VecSector==1 || v->VecSector==4)
{
v->Ta= v->tmp2;
v->Tb= v->tmp1-v->tmp3;
v->Tc=-v->tmp2;
}
else if(v->VecSector==2 || v->VecSector==5)
{
v->Ta= v->tmp3+v->tmp2;
v->Tb= v->tmp1;
v->Tc=-v->tmp1;
}
else
{
v->Ta= v->tmp3;
v->Tb=-v->tmp3;
v->Tc=-(v->tmp1+v->tmp2);
}
}
调用函数产生波形并输出到文件
int main()
{
u32 SpeedRef = Q15;
u32 TIME = 10000;
u32 i=0;
s32 VdTesting = 10;
s32 VqTesting = 10;
file = fopen("01.txt","w");
RcInit(p_rap_cntl);
RGInit(p_rg1);
for (i=0;i<TIME;i++)
{
SvpwmGen(p_svgen1);
fprintf(file ,"%d\n",p_svgen1->Ta );
}
fclose(file);
return 0;
}