FOC中的Clarke变换_TI和ST电机控制库的源码实现
FOC中的PARK变换_TI和ST电机控制库的源码实现
FOC中的反PARK变换_TI和ST电机控制库的源码实现
Clarke变换
这个变换的目的是将平衡的三相量转换为平衡的两相正交量。
这三相电流理论上是相位相差120度的正弦波:
{ I a = I × cos ( w t ) I b = I × cos ( w t − 2 π / 3 ) I c = I × cos ( w t − 4 π / 3 ) \left\{ \begin{array}{l} Ia=I\times \cos \left( wt \right)\\ Ib=I\times \cos \left( wt-2\pi /3 \right)\\ Ic=I\times \cos \left( wt-4\pi /3 \right)\\ \end{array} \right. ⎩⎨⎧Ia=I×cos(wt)Ib=I×cos(wt−2π/3)Ic=I×cos(wt−4π/3)
空间矢量表示这a,b,c三相电流。
我们更习惯于二维平面图中的直角坐标系。可以把这(Ia,Ib,Ic)三个基向量做一个很简单的正交化。
α
−
β
坐
标
系
\alpha -\beta 坐标系
α−β坐标系
变换公式:
{
I
α
=
I
a
−
cos
(
π
3
)
I
b
−
cos
(
π
3
)
I
c
I
β
=
sin
(
π
3
)
I
b
−
sin
(
π
3
)
I
c
\left\{ \begin{array}{l} I\alpha =Ia-\cos \left( \frac{\pi}{3} \right) Ib-\cos \left( \frac{\pi}{3} \right) Ic\\ I\beta =\sin \left( \frac{\pi}{3} \right) Ib-\sin \left( \frac{\pi}{3} \right) Ic\\ \end{array} \right.
{Iα=Ia−cos(3π)Ib−cos(3π)IcIβ=sin(3π)Ib−sin(3π)Ic
基尔霍夫电流定律(KCL):
I
a
+
I
b
+
I
c
=
0
Ia+Ib+Ic=0
Ia+Ib+Ic=0
所以我们可以得到
{ I α = I a I β = ( 2 I b + I a 3 ) \left\{ \begin{array}{l} I\alpha =Ia\\ I\beta =\left( \frac{2Ib+Ia}{\sqrt{3}} \right)\\ \end{array} \right. {Iα=IaIβ=(32Ib+Ia)
{
I
α
=
I
×
cos
(
w
t
)
I
β
=
I
×
sin
(
w
t
)
\left\{ \begin{array}{l} I\alpha =I\times \cos \left( wt \right)\\ I\beta =I\times \sin \left( wt \right)\\ \end{array} \right.
{Iα=I×cos(wt)Iβ=I×sin(wt)
完成转换成了两相正交量。
TI的Digital Motor Control库中的实现:
使用了IQmath的库:把运算浮点数速度提高。定点DSP实现精确的浮点运算。
typedef struct { _iq As; // Input: phase-a stator variable
_iq Bs; // Input: phase-b stator variable
_iq Cs; // Input: phase-c stator variable
_iq Alpha; // Output: stationary d-axis stator variable
_iq Beta; // Output: stationary q-axis stator variable
} CLARKE;
/*-----------------------------------------------------------------------------
Default initalizer for the CLARKE object.
-----------------------------------------------------------------------------*/
#define CLARKE_DEFAULTS { 0, \
0, \
0, \
0, \
0, \
}
// 1/sqrt(3) = 0.57735026918963
#define ONEbySQRT3 0.57735026918963 /* 1/sqrt(3) */
// Clarke transform macro (with 2 currents)
// 只采用两相电流,另一相Ia+Ib+Ic=0得到
// beta = (2*b+a)/sqrt(3)
//==========================================
#define CLARKE_MACRO(v) \
v.Alpha = v.As; \
v.Beta = _IQmpy((v.As +_IQmpy2(v.Bs)),_IQ(ONEbySQRT3));
// Clarke transform macro (with 3 currents)
// 三相电流时beta = (b-c)/sqrt(3)
//==========================================
#define CLARKE1_MACRO(v) \
v.Alpha = v.As; \
v.Beta = _IQmpy((v.Bs - v.Cs),_IQ(ONEbySQRT3));
ST的电机库的实现函数:
st库只使用了两相电流,一堆限幅检测猛如虎。
typedef struct
{
int16_t a;
int16_t b;
} ab_t;
#define divSQRT_3 (int32_t)0x49E6 /* 1/sqrt(3) in q1.15 format=0.5773315*/
/**
* @brief This function transforms stator values a and b (which are
* directed along axes each displaced by 120 degrees) into values
* alpha and beta in a stationary qd reference frame.
* alpha = a
* beta = -(2*b+a)/sqrt(3)
* @param Input: stator values a and b in ab_t format
* @retval Stator values alpha and beta in alphabeta_t format
*/
__weak alphabeta_t MCM_Clarke( ab_t Input )
{
alphabeta_t Output;
int32_t a_divSQRT3_tmp, b_divSQRT3_tmp ;
int32_t wbeta_tmp;
int16_t hbeta_tmp;
/* qIalpha = qIas*/
Output.alpha = Input.a;
a_divSQRT3_tmp = divSQRT_3 * ( int32_t )Input.a;
b_divSQRT3_tmp = divSQRT_3 * ( int32_t )Input.b;
/*qIbeta = -(2*qIbs+qIas)/sqrt(3)*/
// 这里的右移15位,除以32768。
// divSQRT_3 = 0x49E6 / 32768 = 0.5773315
#ifdef FULL_MISRA_C_COMPLIANCY
wbeta_tmp = ( -( a_divSQRT3_tmp ) - ( b_divSQRT3_tmp ) -
( b_divSQRT3_tmp ) ) / 32768;
#else
/* WARNING: the below instruction is not MISRA compliant, user should verify
that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by
the compiler to perform the shift (instead of LSR logical shift right) */
wbeta_tmp = ( -( a_divSQRT3_tmp ) - ( b_divSQRT3_tmp ) -
( b_divSQRT3_tmp ) ) >> 15;
#endif
/* Check saturation of Ibeta */
if ( wbeta_tmp > INT16_MAX )
{
hbeta_tmp = INT16_MAX;
}
else if ( wbeta_tmp < ( -32768 ) )
{
hbeta_tmp = ( -32768 );
}
else
{
hbeta_tmp = ( int16_t )( wbeta_tmp );
}
Output.beta = hbeta_tmp;
if ( Output.beta == ( int16_t )( -32768 ) )
{
Output.beta = -32767;
}
return ( Output );
}
用__weak
前缀的函数称这个函数为“弱函数”。
若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak属性,则这些全局符号不会引发重定义错误。链接器会忽略弱符号,去使用普通的全局符号来解析所有对这些符号的引用,但当普通的全局符号不可用时,链接器会使用弱符号。
当有函数或变量名可能被用户覆盖时,该函数或变量名可以声明为一个弱符号。
参考:
稚晖大佬:
http://www.pengzhihui.xyz/2020/07/02/foc/#more
STM32 FOC 软件培训库pdf
TI DMC MATH_13.1pdf
被抛弃的写随笔公众号改写技术文章了,感兴趣的可以关注公众号:王崇卫