如题,motorware中的示例中的控制算法如下:
static inline void SVGEN_run(SVGEN_Handle handle,const MATH_vec2 *pVab,MATH_vec3 *pT)
{
_iq Vmax,Vmin,Vcom;
_iq Va,Vb,Vc;
_iq Va_tmp = -(pVab->value[0]>>1);
_iq Vb_tmp = _IQmpy(SVGEN_SQRT3_OVER_2,pVab->value[1]);
Va = pVab->value[0]; //alpha
Vb = Va_tmp + Vb_tmp; //-0.5*alpha + sqrt(3)/2 * beta;
Vc = Va_tmp – Vb_tmp; //-0.5*alpha – sqrt(3)/2 * beta;
Vmax=0;
Vmin=0;
// find order Vmin,Vmid,Vmax
if (Va > Vb) {
Vmax = Va;
Vmin = Vb;
}
else
{
Vmax = Vb;
Vmin = Va;
}
if (Vc > Vmax)
{
Vmax = Vc;
}
else if (Vc < Vmin)
{
Vmin = Vc;
}
Vcom = _IQmpy(Vmax+Vmin, _IQ(0.5));
// Subtract common-mode term to achieve SV modulation
pT->value[0] = (Va – Vcom);
pT->value[1] = (Vb – Vcom);
pT->value[2] = (Vc – Vcom);
return;
}
传统svgen_dq算法如下:
#define SVGEN_MACRO(v) \
\
Sector = 0; \
temp_sv1=_IQdiv2(v.Ubeta); /*divide by 2*/ \
temp_sv2=_IQmpy(_IQ(0.8660254),v.Ualpha); /* 0.8660254 = sqrt(3)/2*/ \
\
/* Inverse clarke transformation */ \
Va = v.Ubeta; \
Vb = -temp_sv1 + temp_sv2; \
Vc = -temp_sv1 – temp_sv2; \
/* 60 degree Sector determination */ \
if (Va>_IQ(0)) Sector = 1; \
if (Vb>_IQ(0)) Sector = Sector+2; \
if (Vc>_IQ(0)) Sector = Sector+4; \
/* X,Y,Z (Va,Vb,Vc) calculations X = Va, Y = Vb, Z = Vc */ \
Va = v.Ubeta; \
Vb = temp_sv1 + temp_sv2; \
Vc = temp_sv1 – temp_sv2; \
/* Sector 0: this is special case for (Ualpha,Ubeta) = (0,0)*/ \
\
switch(Sector) \
{ \
case 0: \
v.Ta = _IQ(0.5); \
v.Tb = _IQ(0.5); \
v.Tc = _IQ(0.5); \
break; \
case 1: /*Sector 1: t1=Z and t2=Y (abc —> Tb,Ta,Tc)*/ \
t1 = Vc; \
t2 = Vb; \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tb+t1; /* taon = tbon+t1 */ \
v.Tc = v.Ta+t2; /* tcon = taon+t2 */ \
break; \
case 2: /* Sector 2: t1=Y and t2=-X (abc —> Ta,Tc,Tb)*/ \
t1 = Vb; \
t2 = -Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Ta+t1; /* tcon = taon+t1 */ \
v.Tb = v.Tc+t2; /* tbon = tcon+t2 */ \
break; \
case 3: /* Sector 3: t1=-Z and t2=X (abc —> Ta,Tb,Tc)*/ \
t1 = -Vc; \
t2 = Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Ta+t1; /* tbon = taon+t1 */ \
v.Tc = v.Tb+t2; /* tcon = tbon+t2 */ \
break; \
case 4: /* Sector 4: t1=-X and t2=Z (abc —> Tc,Tb,Ta)*/ \
t1 = -Va; \
t2 = Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Tc+t1; /* tbon = tcon+t1 */ \
v.Ta = v.Tb+t2; /* taon = tbon+t2 */ \
break; \
case 5: /* Sector 5: t1=X and t2=-Y (abc —> Tb,Tc,Ta)*/ \
t1 = Va; \
t2 = -Vb; /* tbon = (1-t1-t2)/2 */ \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Tb+t1; /* taon = tcon+t2 */ \
v.Ta = v.Tc+t2; \
break; \
case 6: /* Sector 6: t1=-Y and t2=-Z (abc —> Tc,Ta,Tb)*/ \
t1 = -Vb; \
t2 = -Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tc+t1; /* taon = tcon+t1 */ \
v.Tb = v.Ta+t2; /* tbon = taon+t2 */ \
break; \
} \
/* Convert the unsigned GLOBAL_Q format (ranged (0,1)) ->.. */ \
/* ..signed GLOBAL_Q format (ranged (-1,1))*/ \
v.Ta = _IQmpy2(v.Ta-_IQ(0.5)); \
v.Tb = _IQmpy2(v.Tb-_IQ(0.5)); \
v.Tc = _IQmpy2(v.Tc-_IQ(0.5)); \
没明白为什么这里要用前者,求解,谢谢!
Eric Ma:
参考下面的回答:
The SVM technique used with InstaSPIN is discussed in the following reference:
Advanced Electric Drives, Analysis, Control and Modeling using Simulink, by Ned Mohan, MNPERE Press, Minneapolis, MN 55414, 2001, ISBN# 0-9715292-0-5
This technique was selected because it seamlessly transitions into the overmodulation region of operation by simply increasing the amplitude of the voltage variables from the Inverse Park Transform. A natural clipping effect occurs which causes the waveforms to change from sinusoidal to trapezoidal.
You can replace the SVM module with a more conventional technique if you desire. But you must then manage the overmodulation yourself.
ERIC
如题,motorware中的示例中的控制算法如下:
static inline void SVGEN_run(SVGEN_Handle handle,const MATH_vec2 *pVab,MATH_vec3 *pT)
{
_iq Vmax,Vmin,Vcom;
_iq Va,Vb,Vc;
_iq Va_tmp = -(pVab->value[0]>>1);
_iq Vb_tmp = _IQmpy(SVGEN_SQRT3_OVER_2,pVab->value[1]);
Va = pVab->value[0]; //alpha
Vb = Va_tmp + Vb_tmp; //-0.5*alpha + sqrt(3)/2 * beta;
Vc = Va_tmp – Vb_tmp; //-0.5*alpha – sqrt(3)/2 * beta;
Vmax=0;
Vmin=0;
// find order Vmin,Vmid,Vmax
if (Va > Vb) {
Vmax = Va;
Vmin = Vb;
}
else
{
Vmax = Vb;
Vmin = Va;
}
if (Vc > Vmax)
{
Vmax = Vc;
}
else if (Vc < Vmin)
{
Vmin = Vc;
}
Vcom = _IQmpy(Vmax+Vmin, _IQ(0.5));
// Subtract common-mode term to achieve SV modulation
pT->value[0] = (Va – Vcom);
pT->value[1] = (Vb – Vcom);
pT->value[2] = (Vc – Vcom);
return;
}
传统svgen_dq算法如下:
#define SVGEN_MACRO(v) \
\
Sector = 0; \
temp_sv1=_IQdiv2(v.Ubeta); /*divide by 2*/ \
temp_sv2=_IQmpy(_IQ(0.8660254),v.Ualpha); /* 0.8660254 = sqrt(3)/2*/ \
\
/* Inverse clarke transformation */ \
Va = v.Ubeta; \
Vb = -temp_sv1 + temp_sv2; \
Vc = -temp_sv1 – temp_sv2; \
/* 60 degree Sector determination */ \
if (Va>_IQ(0)) Sector = 1; \
if (Vb>_IQ(0)) Sector = Sector+2; \
if (Vc>_IQ(0)) Sector = Sector+4; \
/* X,Y,Z (Va,Vb,Vc) calculations X = Va, Y = Vb, Z = Vc */ \
Va = v.Ubeta; \
Vb = temp_sv1 + temp_sv2; \
Vc = temp_sv1 – temp_sv2; \
/* Sector 0: this is special case for (Ualpha,Ubeta) = (0,0)*/ \
\
switch(Sector) \
{ \
case 0: \
v.Ta = _IQ(0.5); \
v.Tb = _IQ(0.5); \
v.Tc = _IQ(0.5); \
break; \
case 1: /*Sector 1: t1=Z and t2=Y (abc —> Tb,Ta,Tc)*/ \
t1 = Vc; \
t2 = Vb; \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tb+t1; /* taon = tbon+t1 */ \
v.Tc = v.Ta+t2; /* tcon = taon+t2 */ \
break; \
case 2: /* Sector 2: t1=Y and t2=-X (abc —> Ta,Tc,Tb)*/ \
t1 = Vb; \
t2 = -Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Ta+t1; /* tcon = taon+t1 */ \
v.Tb = v.Tc+t2; /* tbon = tcon+t2 */ \
break; \
case 3: /* Sector 3: t1=-Z and t2=X (abc —> Ta,Tb,Tc)*/ \
t1 = -Vc; \
t2 = Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Ta+t1; /* tbon = taon+t1 */ \
v.Tc = v.Tb+t2; /* tcon = tbon+t2 */ \
break; \
case 4: /* Sector 4: t1=-X and t2=Z (abc —> Tc,Tb,Ta)*/ \
t1 = -Va; \
t2 = Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Tc+t1; /* tbon = tcon+t1 */ \
v.Ta = v.Tb+t2; /* taon = tbon+t2 */ \
break; \
case 5: /* Sector 5: t1=X and t2=-Y (abc —> Tb,Tc,Ta)*/ \
t1 = Va; \
t2 = -Vb; /* tbon = (1-t1-t2)/2 */ \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Tb+t1; /* taon = tcon+t2 */ \
v.Ta = v.Tc+t2; \
break; \
case 6: /* Sector 6: t1=-Y and t2=-Z (abc —> Tc,Ta,Tb)*/ \
t1 = -Vb; \
t2 = -Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tc+t1; /* taon = tcon+t1 */ \
v.Tb = v.Ta+t2; /* tbon = taon+t2 */ \
break; \
} \
/* Convert the unsigned GLOBAL_Q format (ranged (0,1)) ->.. */ \
/* ..signed GLOBAL_Q format (ranged (-1,1))*/ \
v.Ta = _IQmpy2(v.Ta-_IQ(0.5)); \
v.Tb = _IQmpy2(v.Tb-_IQ(0.5)); \
v.Tc = _IQmpy2(v.Tc-_IQ(0.5)); \
没明白为什么这里要用前者,求解,谢谢!
YunFei Cao:
回复 Eric Ma:
刚好我最近研究了这个问题,写了一篇博客,你可以去看看
http://caoyunfei2012.blog.163.com/blog/static/26640605220169831929763/
版权所有哦
如题,motorware中的示例中的控制算法如下:
static inline void SVGEN_run(SVGEN_Handle handle,const MATH_vec2 *pVab,MATH_vec3 *pT)
{
_iq Vmax,Vmin,Vcom;
_iq Va,Vb,Vc;
_iq Va_tmp = -(pVab->value[0]>>1);
_iq Vb_tmp = _IQmpy(SVGEN_SQRT3_OVER_2,pVab->value[1]);
Va = pVab->value[0]; //alpha
Vb = Va_tmp + Vb_tmp; //-0.5*alpha + sqrt(3)/2 * beta;
Vc = Va_tmp – Vb_tmp; //-0.5*alpha – sqrt(3)/2 * beta;
Vmax=0;
Vmin=0;
// find order Vmin,Vmid,Vmax
if (Va > Vb) {
Vmax = Va;
Vmin = Vb;
}
else
{
Vmax = Vb;
Vmin = Va;
}
if (Vc > Vmax)
{
Vmax = Vc;
}
else if (Vc < Vmin)
{
Vmin = Vc;
}
Vcom = _IQmpy(Vmax+Vmin, _IQ(0.5));
// Subtract common-mode term to achieve SV modulation
pT->value[0] = (Va – Vcom);
pT->value[1] = (Vb – Vcom);
pT->value[2] = (Vc – Vcom);
return;
}
传统svgen_dq算法如下:
#define SVGEN_MACRO(v) \
\
Sector = 0; \
temp_sv1=_IQdiv2(v.Ubeta); /*divide by 2*/ \
temp_sv2=_IQmpy(_IQ(0.8660254),v.Ualpha); /* 0.8660254 = sqrt(3)/2*/ \
\
/* Inverse clarke transformation */ \
Va = v.Ubeta; \
Vb = -temp_sv1 + temp_sv2; \
Vc = -temp_sv1 – temp_sv2; \
/* 60 degree Sector determination */ \
if (Va>_IQ(0)) Sector = 1; \
if (Vb>_IQ(0)) Sector = Sector+2; \
if (Vc>_IQ(0)) Sector = Sector+4; \
/* X,Y,Z (Va,Vb,Vc) calculations X = Va, Y = Vb, Z = Vc */ \
Va = v.Ubeta; \
Vb = temp_sv1 + temp_sv2; \
Vc = temp_sv1 – temp_sv2; \
/* Sector 0: this is special case for (Ualpha,Ubeta) = (0,0)*/ \
\
switch(Sector) \
{ \
case 0: \
v.Ta = _IQ(0.5); \
v.Tb = _IQ(0.5); \
v.Tc = _IQ(0.5); \
break; \
case 1: /*Sector 1: t1=Z and t2=Y (abc —> Tb,Ta,Tc)*/ \
t1 = Vc; \
t2 = Vb; \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tb+t1; /* taon = tbon+t1 */ \
v.Tc = v.Ta+t2; /* tcon = taon+t2 */ \
break; \
case 2: /* Sector 2: t1=Y and t2=-X (abc —> Ta,Tc,Tb)*/ \
t1 = Vb; \
t2 = -Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Ta+t1; /* tcon = taon+t1 */ \
v.Tb = v.Tc+t2; /* tbon = tcon+t2 */ \
break; \
case 3: /* Sector 3: t1=-Z and t2=X (abc —> Ta,Tb,Tc)*/ \
t1 = -Vc; \
t2 = Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Ta+t1; /* tbon = taon+t1 */ \
v.Tc = v.Tb+t2; /* tcon = tbon+t2 */ \
break; \
case 4: /* Sector 4: t1=-X and t2=Z (abc —> Tc,Tb,Ta)*/ \
t1 = -Va; \
t2 = Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Tc+t1; /* tbon = tcon+t1 */ \
v.Ta = v.Tb+t2; /* taon = tbon+t2 */ \
break; \
case 5: /* Sector 5: t1=X and t2=-Y (abc —> Tb,Tc,Ta)*/ \
t1 = Va; \
t2 = -Vb; /* tbon = (1-t1-t2)/2 */ \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Tb+t1; /* taon = tcon+t2 */ \
v.Ta = v.Tc+t2; \
break; \
case 6: /* Sector 6: t1=-Y and t2=-Z (abc —> Tc,Ta,Tb)*/ \
t1 = -Vb; \
t2 = -Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tc+t1; /* taon = tcon+t1 */ \
v.Tb = v.Ta+t2; /* tbon = taon+t2 */ \
break; \
} \
/* Convert the unsigned GLOBAL_Q format (ranged (0,1)) ->.. */ \
/* ..signed GLOBAL_Q format (ranged (-1,1))*/ \
v.Ta = _IQmpy2(v.Ta-_IQ(0.5)); \
v.Tb = _IQmpy2(v.Tb-_IQ(0.5)); \
v.Tc = _IQmpy2(v.Tc-_IQ(0.5)); \
没明白为什么这里要用前者,求解,谢谢!
GUANJIE YU:
回复 YunFei Cao:
YunFei Cao
刚好我最近研究了这个问题,写了一篇博客,你可以去看看
http://caoyunfei2012.blog.163.com/blog/static/26640605220169831929763/
版权所有哦
如题,motorware中的示例中的控制算法如下:
static inline void SVGEN_run(SVGEN_Handle handle,const MATH_vec2 *pVab,MATH_vec3 *pT)
{
_iq Vmax,Vmin,Vcom;
_iq Va,Vb,Vc;
_iq Va_tmp = -(pVab->value[0]>>1);
_iq Vb_tmp = _IQmpy(SVGEN_SQRT3_OVER_2,pVab->value[1]);
Va = pVab->value[0]; //alpha
Vb = Va_tmp + Vb_tmp; //-0.5*alpha + sqrt(3)/2 * beta;
Vc = Va_tmp – Vb_tmp; //-0.5*alpha – sqrt(3)/2 * beta;
Vmax=0;
Vmin=0;
// find order Vmin,Vmid,Vmax
if (Va > Vb) {
Vmax = Va;
Vmin = Vb;
}
else
{
Vmax = Vb;
Vmin = Va;
}
if (Vc > Vmax)
{
Vmax = Vc;
}
else if (Vc < Vmin)
{
Vmin = Vc;
}
Vcom = _IQmpy(Vmax+Vmin, _IQ(0.5));
// Subtract common-mode term to achieve SV modulation
pT->value[0] = (Va – Vcom);
pT->value[1] = (Vb – Vcom);
pT->value[2] = (Vc – Vcom);
return;
}
传统svgen_dq算法如下:
#define SVGEN_MACRO(v) \
\
Sector = 0; \
temp_sv1=_IQdiv2(v.Ubeta); /*divide by 2*/ \
temp_sv2=_IQmpy(_IQ(0.8660254),v.Ualpha); /* 0.8660254 = sqrt(3)/2*/ \
\
/* Inverse clarke transformation */ \
Va = v.Ubeta; \
Vb = -temp_sv1 + temp_sv2; \
Vc = -temp_sv1 – temp_sv2; \
/* 60 degree Sector determination */ \
if (Va>_IQ(0)) Sector = 1; \
if (Vb>_IQ(0)) Sector = Sector+2; \
if (Vc>_IQ(0)) Sector = Sector+4; \
/* X,Y,Z (Va,Vb,Vc) calculations X = Va, Y = Vb, Z = Vc */ \
Va = v.Ubeta; \
Vb = temp_sv1 + temp_sv2; \
Vc = temp_sv1 – temp_sv2; \
/* Sector 0: this is special case for (Ualpha,Ubeta) = (0,0)*/ \
\
switch(Sector) \
{ \
case 0: \
v.Ta = _IQ(0.5); \
v.Tb = _IQ(0.5); \
v.Tc = _IQ(0.5); \
break; \
case 1: /*Sector 1: t1=Z and t2=Y (abc —> Tb,Ta,Tc)*/ \
t1 = Vc; \
t2 = Vb; \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tb+t1; /* taon = tbon+t1 */ \
v.Tc = v.Ta+t2; /* tcon = taon+t2 */ \
break; \
case 2: /* Sector 2: t1=Y and t2=-X (abc —> Ta,Tc,Tb)*/ \
t1 = Vb; \
t2 = -Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Ta+t1; /* tcon = taon+t1 */ \
v.Tb = v.Tc+t2; /* tbon = tcon+t2 */ \
break; \
case 3: /* Sector 3: t1=-Z and t2=X (abc —> Ta,Tb,Tc)*/ \
t1 = -Vc; \
t2 = Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Ta+t1; /* tbon = taon+t1 */ \
v.Tc = v.Tb+t2; /* tcon = tbon+t2 */ \
break; \
case 4: /* Sector 4: t1=-X and t2=Z (abc —> Tc,Tb,Ta)*/ \
t1 = -Va; \
t2 = Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Tc+t1; /* tbon = tcon+t1 */ \
v.Ta = v.Tb+t2; /* taon = tbon+t2 */ \
break; \
case 5: /* Sector 5: t1=X and t2=-Y (abc —> Tb,Tc,Ta)*/ \
t1 = Va; \
t2 = -Vb; /* tbon = (1-t1-t2)/2 */ \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Tb+t1; /* taon = tcon+t2 */ \
v.Ta = v.Tc+t2; \
break; \
case 6: /* Sector 6: t1=-Y and t2=-Z (abc —> Tc,Ta,Tb)*/ \
t1 = -Vb; \
t2 = -Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tc+t1; /* taon = tcon+t1 */ \
v.Tb = v.Ta+t2; /* tbon = taon+t2 */ \
break; \
} \
/* Convert the unsigned GLOBAL_Q format (ranged (0,1)) ->.. */ \
/* ..signed GLOBAL_Q format (ranged (-1,1))*/ \
v.Ta = _IQmpy2(v.Ta-_IQ(0.5)); \
v.Tb = _IQmpy2(v.Tb-_IQ(0.5)); \
v.Tc = _IQmpy2(v.Tc-_IQ(0.5)); \
没明白为什么这里要用前者,求解,谢谢!
ming chen3:
回复 GUANJIE YU:
很明显motorware中的算法简单,计算时间短。可以提高采样频率。
2812和28335都是用的传统的方法,进行扇区判断,计算矢量的作用时间。
2812和28335都是150M主频,motorware中的针对piccolo系列MCU,02x—06x主频在60M到90M,
不知道是否是基于这方面的考虑。。
至于性能我觉得传统方法更好,可以仿真下。
如题,motorware中的示例中的控制算法如下:
static inline void SVGEN_run(SVGEN_Handle handle,const MATH_vec2 *pVab,MATH_vec3 *pT)
{
_iq Vmax,Vmin,Vcom;
_iq Va,Vb,Vc;
_iq Va_tmp = -(pVab->value[0]>>1);
_iq Vb_tmp = _IQmpy(SVGEN_SQRT3_OVER_2,pVab->value[1]);
Va = pVab->value[0]; //alpha
Vb = Va_tmp + Vb_tmp; //-0.5*alpha + sqrt(3)/2 * beta;
Vc = Va_tmp – Vb_tmp; //-0.5*alpha – sqrt(3)/2 * beta;
Vmax=0;
Vmin=0;
// find order Vmin,Vmid,Vmax
if (Va > Vb) {
Vmax = Va;
Vmin = Vb;
}
else
{
Vmax = Vb;
Vmin = Va;
}
if (Vc > Vmax)
{
Vmax = Vc;
}
else if (Vc < Vmin)
{
Vmin = Vc;
}
Vcom = _IQmpy(Vmax+Vmin, _IQ(0.5));
// Subtract common-mode term to achieve SV modulation
pT->value[0] = (Va – Vcom);
pT->value[1] = (Vb – Vcom);
pT->value[2] = (Vc – Vcom);
return;
}
传统svgen_dq算法如下:
#define SVGEN_MACRO(v) \
\
Sector = 0; \
temp_sv1=_IQdiv2(v.Ubeta); /*divide by 2*/ \
temp_sv2=_IQmpy(_IQ(0.8660254),v.Ualpha); /* 0.8660254 = sqrt(3)/2*/ \
\
/* Inverse clarke transformation */ \
Va = v.Ubeta; \
Vb = -temp_sv1 + temp_sv2; \
Vc = -temp_sv1 – temp_sv2; \
/* 60 degree Sector determination */ \
if (Va>_IQ(0)) Sector = 1; \
if (Vb>_IQ(0)) Sector = Sector+2; \
if (Vc>_IQ(0)) Sector = Sector+4; \
/* X,Y,Z (Va,Vb,Vc) calculations X = Va, Y = Vb, Z = Vc */ \
Va = v.Ubeta; \
Vb = temp_sv1 + temp_sv2; \
Vc = temp_sv1 – temp_sv2; \
/* Sector 0: this is special case for (Ualpha,Ubeta) = (0,0)*/ \
\
switch(Sector) \
{ \
case 0: \
v.Ta = _IQ(0.5); \
v.Tb = _IQ(0.5); \
v.Tc = _IQ(0.5); \
break; \
case 1: /*Sector 1: t1=Z and t2=Y (abc —> Tb,Ta,Tc)*/ \
t1 = Vc; \
t2 = Vb; \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tb+t1; /* taon = tbon+t1 */ \
v.Tc = v.Ta+t2; /* tcon = taon+t2 */ \
break; \
case 2: /* Sector 2: t1=Y and t2=-X (abc —> Ta,Tc,Tb)*/ \
t1 = Vb; \
t2 = -Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Ta+t1; /* tcon = taon+t1 */ \
v.Tb = v.Tc+t2; /* tbon = tcon+t2 */ \
break; \
case 3: /* Sector 3: t1=-Z and t2=X (abc —> Ta,Tb,Tc)*/ \
t1 = -Vc; \
t2 = Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Ta+t1; /* tbon = taon+t1 */ \
v.Tc = v.Tb+t2; /* tcon = tbon+t2 */ \
break; \
case 4: /* Sector 4: t1=-X and t2=Z (abc —> Tc,Tb,Ta)*/ \
t1 = -Va; \
t2 = Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Tc+t1; /* tbon = tcon+t1 */ \
v.Ta = v.Tb+t2; /* taon = tbon+t2 */ \
break; \
case 5: /* Sector 5: t1=X and t2=-Y (abc —> Tb,Tc,Ta)*/ \
t1 = Va; \
t2 = -Vb; /* tbon = (1-t1-t2)/2 */ \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Tb+t1; /* taon = tcon+t2 */ \
v.Ta = v.Tc+t2; \
break; \
case 6: /* Sector 6: t1=-Y and t2=-Z (abc —> Tc,Ta,Tb)*/ \
t1 = -Vb; \
t2 = -Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tc+t1; /* taon = tcon+t1 */ \
v.Tb = v.Ta+t2; /* tbon = taon+t2 */ \
break; \
} \
/* Convert the unsigned GLOBAL_Q format (ranged (0,1)) ->.. */ \
/* ..signed GLOBAL_Q format (ranged (-1,1))*/ \
v.Ta = _IQmpy2(v.Ta-_IQ(0.5)); \
v.Tb = _IQmpy2(v.Tb-_IQ(0.5)); \
v.Tc = _IQmpy2(v.Tc-_IQ(0.5)); \
没明白为什么这里要用前者,求解,谢谢!
gang qu:
回复 ming chen3:
分析不错,正在查这个问题。
如题,motorware中的示例中的控制算法如下:
static inline void SVGEN_run(SVGEN_Handle handle,const MATH_vec2 *pVab,MATH_vec3 *pT)
{
_iq Vmax,Vmin,Vcom;
_iq Va,Vb,Vc;
_iq Va_tmp = -(pVab->value[0]>>1);
_iq Vb_tmp = _IQmpy(SVGEN_SQRT3_OVER_2,pVab->value[1]);
Va = pVab->value[0]; //alpha
Vb = Va_tmp + Vb_tmp; //-0.5*alpha + sqrt(3)/2 * beta;
Vc = Va_tmp – Vb_tmp; //-0.5*alpha – sqrt(3)/2 * beta;
Vmax=0;
Vmin=0;
// find order Vmin,Vmid,Vmax
if (Va > Vb) {
Vmax = Va;
Vmin = Vb;
}
else
{
Vmax = Vb;
Vmin = Va;
}
if (Vc > Vmax)
{
Vmax = Vc;
}
else if (Vc < Vmin)
{
Vmin = Vc;
}
Vcom = _IQmpy(Vmax+Vmin, _IQ(0.5));
// Subtract common-mode term to achieve SV modulation
pT->value[0] = (Va – Vcom);
pT->value[1] = (Vb – Vcom);
pT->value[2] = (Vc – Vcom);
return;
}
传统svgen_dq算法如下:
#define SVGEN_MACRO(v) \
\
Sector = 0; \
temp_sv1=_IQdiv2(v.Ubeta); /*divide by 2*/ \
temp_sv2=_IQmpy(_IQ(0.8660254),v.Ualpha); /* 0.8660254 = sqrt(3)/2*/ \
\
/* Inverse clarke transformation */ \
Va = v.Ubeta; \
Vb = -temp_sv1 + temp_sv2; \
Vc = -temp_sv1 – temp_sv2; \
/* 60 degree Sector determination */ \
if (Va>_IQ(0)) Sector = 1; \
if (Vb>_IQ(0)) Sector = Sector+2; \
if (Vc>_IQ(0)) Sector = Sector+4; \
/* X,Y,Z (Va,Vb,Vc) calculations X = Va, Y = Vb, Z = Vc */ \
Va = v.Ubeta; \
Vb = temp_sv1 + temp_sv2; \
Vc = temp_sv1 – temp_sv2; \
/* Sector 0: this is special case for (Ualpha,Ubeta) = (0,0)*/ \
\
switch(Sector) \
{ \
case 0: \
v.Ta = _IQ(0.5); \
v.Tb = _IQ(0.5); \
v.Tc = _IQ(0.5); \
break; \
case 1: /*Sector 1: t1=Z and t2=Y (abc —> Tb,Ta,Tc)*/ \
t1 = Vc; \
t2 = Vb; \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tb+t1; /* taon = tbon+t1 */ \
v.Tc = v.Ta+t2; /* tcon = taon+t2 */ \
break; \
case 2: /* Sector 2: t1=Y and t2=-X (abc —> Ta,Tc,Tb)*/ \
t1 = Vb; \
t2 = -Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Ta+t1; /* tcon = taon+t1 */ \
v.Tb = v.Tc+t2; /* tbon = tcon+t2 */ \
break; \
case 3: /* Sector 3: t1=-Z and t2=X (abc —> Ta,Tb,Tc)*/ \
t1 = -Vc; \
t2 = Va; \
v.Ta=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Ta+t1; /* tbon = taon+t1 */ \
v.Tc = v.Tb+t2; /* tcon = tbon+t2 */ \
break; \
case 4: /* Sector 4: t1=-X and t2=Z (abc —> Tc,Tb,Ta)*/ \
t1 = -Va; \
t2 = Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tb = v.Tc+t1; /* tbon = tcon+t1 */ \
v.Ta = v.Tb+t2; /* taon = tbon+t2 */ \
break; \
case 5: /* Sector 5: t1=X and t2=-Y (abc —> Tb,Tc,Ta)*/ \
t1 = Va; \
t2 = -Vb; /* tbon = (1-t1-t2)/2 */ \
v.Tb=_IQdiv2((_IQ(1)-t1-t2)); \
v.Tc = v.Tb+t1; /* taon = tcon+t2 */ \
v.Ta = v.Tc+t2; \
break; \
case 6: /* Sector 6: t1=-Y and t2=-Z (abc —> Tc,Ta,Tb)*/ \
t1 = -Vb; \
t2 = -Vc; \
v.Tc=_IQdiv2((_IQ(1)-t1-t2)); \
v.Ta = v.Tc+t1; /* taon = tcon+t1 */ \
v.Tb = v.Ta+t2; /* tbon = taon+t2 */ \
break; \
} \
/* Convert the unsigned GLOBAL_Q format (ranged (0,1)) ->.. */ \
/* ..signed GLOBAL_Q format (ranged (-1,1))*/ \
v.Ta = _IQmpy2(v.Ta-_IQ(0.5)); \
v.Tb = _IQmpy2(v.Tb-_IQ(0.5)); \
v.Tc = _IQmpy2(v.Tc-_IQ(0.5)); \
没明白为什么这里要用前者,求解,谢谢!
jia liu8:
回复 Eric Ma:
Hi Eric,
请问这种算法,在过调制时,不需要对duty做处理吗,ta,tb,tc有可能出现大于period的情况吧?
另外这个算法具体是在这本书《Advanced Electric Drives》的哪个章节里有涉及?
谢谢!