做MEC项目,用到了三相DQ,单相DQ,负序等,组内人员参考此坐标系的定义编写代码,以下文章节选自以下各位大神们.感谢各位作者的辛苦推导.
版权声明:本文为CSDN博主「JaySur」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jaysur/article/details/100673823
1.项目之前用的PLL为
D
+
D_+
D+ =
s
i
n
∗
a
l
p
h
a
−
c
o
s
∗
b
e
t
a
sin*alpha - cos*beta
sin∗alpha−cos∗beta
Q
+
Q_+
Q+ =
c
o
s
∗
a
l
p
h
a
+
s
i
n
∗
b
e
t
a
cos*alpha + sin*beta
cos∗alpha+sin∗beta
D
−
D_-
D− =
−
s
i
n
∗
a
l
p
h
a
−
c
o
s
∗
b
e
t
a
-sin*alpha - cos*beta
−sin∗alpha−cos∗beta
Q
−
Q_-
Q− =
c
o
s
∗
a
l
p
h
a
+
s
i
n
∗
b
e
t
a
cos*alpha + sin*beta
cos∗alpha+sin∗beta
得到如下:
C
P
a
r
k
C_{Park}
CPark =
[
s
i
n
θ
−
c
o
s
θ
c
o
s
θ
s
i
n
θ
]
\begin{bmatrix} sin\theta & -cos\theta\\ cos\theta & sin\theta \\ \end{bmatrix}
[sinθcosθ−cosθsinθ]
\qquad\qquad\qquad
(1-1)
C P a r k − 1 C_{Park}^{-1} CPark−1 = [ − s i n θ − c o s θ c o s θ s i n θ ] \begin{bmatrix} -sin\theta & -cos\theta\\ cos\theta & sin\theta \\ \end{bmatrix} [−sinθcosθ−cosθsinθ] \qquad\qquad\qquad (1-2)
之前的代码
#if !SPLL_3PH_DDSRF
int temp0 = 0;
float32 zZ,zB,zC,AGCVal;
//del zero sequence
zZ = (GridVoltAF + GridVoltBF + GridVoltCF)*S1DIV3;
// zA = GridVoltAF-zZ;
zB = GridVoltBF-zZ;
zC = GridVoltCF-zZ;
//id=sqrt(2/3)*[ cos(wt) cos(wt-pi*2/3) cos(wt-pi*4/3)]*[a b c]'
//iq=sqrt(2/3)*[-sin(wt) -sin(wt-pi*2/3) -sin(wt-pi*4/3)]*[a b c]'
//3s/2s transfer
GridVoltAlpha= SQRT_2DIV3 *(GridVoltAF-zZ - 0.5f*zB - 0.5f*zC); //,zA=(GridVoltAF-zZ)
GridVoltBeta= SQRT2_DIV2 *(zB - zC); //=
//2s/2r transfer
GridPLLVoltD= DCL_runDF22(&gridVoltPosiDFilter, GridVoltAlpha*PLLResCos + GridVoltBeta *PLLResSin);
GridPLLVoltQ= DCL_runDF22(&gridVoltPosiQFilter, GridVoltBeta *PLLResCos - GridVoltAlpha*PLLResSin);
AGCVal =1/(DCL_runDF22(&PLLAGCFilter, sqrt(GridPLLVoltD*GridPLLVoltD+GridPLLVoltQ*GridPLLVoltQ)));
if(AGCVal>1/(5.0f*SQRT2*SQRT_3DIV2)) AGCVal=1/(5.0f*SQRT2*SQRT_3DIV2); //5V
if(AGCVal<1/(690*1.2f*SQRT2*SQRT_3DIV2)) AGCVal=1/(690*1.2f*SQRT2*SQRT_3DIV2); //220V
PllPiOutput =DCL_runPI(&PLLPICtrl, GridPLLVoltQ*AGCVal , 0); //PID,AGC
Theta=IntergrateBackEuler(PllPiOutput,Theta); //Integration and get same phase as the voltage 0 degrees
if(Theta > PI2) {Theta -= PI2;} //2*PI limiting
if(Theta < 0) {Theta += PI2;} //2*PI limiting
gridFreq = DCL_runDF22(&bwForFreq, PllPiOutput *(1/PI2));
temp0 = (int16)(Theta*PLL_STEP); //float convert to int
temp0 %= SINE_LOOKTABLE_LEN; //Take a remainder
PLLResSin=-pCoseLookTab(temp0);
PLLResCos= pSineLookTab(temp0);
VoltTheta=Theta-PllCalibrPhase+(PI/2); //Corrected to the lead of the PI/2 phase-locked angle
if(VoltTheta > PI2) VoltTheta -= PI2; //2*PI limiting
if(VoltTheta < 0) VoltTheta += PI2; //2*PI limiting
temp0 = (int16)(VoltTheta*PLL_STEP); //float convert to int
temp0 %= SINE_LOOKTABLE_LEN;
resSin=pSineLookTab(temp0);
resCos=pCoseLookTab(temp0);
2.经过修改的坐标系:
电机控制中Clarke变换的等幅值变换和等功率变换
得到图形如下:
得到的
[
I
d
I
q
]
\begin{bmatrix} I_{d} \\ I_{q}\\\end{bmatrix}
[IdIq] =
[
I
m
∗
c
o
s
θ
−
I
m
∗
s
i
n
θ
]
\begin{bmatrix} I_{m}*cos\theta \\ -I_{m}*sin\theta \\ \end{bmatrix}
[Im∗cosθ−Im∗sinθ]
\qquad\qquad\qquad
(2-3)
得到了SPLL.Theta锁相的角度
θ
\theta
θ即电网电压A相
∗
c
o
s
θ
*cos\theta
∗cosθ
重新生成VoltTheta=SPLL.Theta+
p
i
/
2
pi/2
pi/2,即电网电压A相
∗
s
i
n
θ
*sin\theta
∗sinθ
单相DQ的伪代码如下:
if(++VoltPrvPos >= VOLT_FUNDPOINT) VoltPrvPos=0;
VoltSlid[VoltPrvPos] = 外部PT经过模拟滤波器后经AD采样得到的值经过数字滤波器
VoltPos = VoltPrvPos+VoltLeadPoints; //超前校正指针,超前了360*VoltLeadPoints/VOLT_FUNDPOINT度
#define CAP_VOL_POINT ((PWMFREQUENCY/(50*4))*2*3) //每周波的3/4
CapVoltPos = VoltPos+CAP_VOL_POINT; //电容电压一周波缓冲区指针,滞后270度,即超前90度
CapAlpha = VoltSlid[VoltPos];
pCapBeta = VoltSlid[CapVoltPos];
if(!StateFlag.VoltFilterEn) //用上周波值校正电网电压滞后的相差
pOutSrc= VoltSlid[VoltPos];
else //做电流前馈时,打算用dq校正电网电压滞后的相差,此时未校正
pOutSrc= VoltSlid[VoltPrvPos];
D=(beta *resSin + alpha*resCos)*(SQRT2_DIV2); //D
Q=(beta *resCos - alpha*resSin)*(SQRT2_DIV2); //Q
得到
a
l
p
h
a
alpha
alpha与
b
e
t
a
beta
beta波形
得到
a
l
p
h
a
alpha
alpha与电网电压A相
∗
c
o
s
θ
*cos\theta
∗cosθ同相,即
得到DQ值