FOC中的Clarke变换_TI和ST电机控制库的源码实现
Clarke变换这个变换的目的是将平衡的三相量转换为平衡的两相正交量。这三相电流理论上是相位相差120度的正弦波:{Ia=I×cos(wt)Ib=I×cos(wt−2π/3)Ic=I×cos(wt−4π/3)\left\{ \begin{array}{l}Ia=I\times \cos \left( wt \right)\\Ib=I\times \cos \left( wt-2\pi /3
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
被抛弃的写随笔公众号改写技术文章了,感兴趣的可以关注公众号:王崇卫
更多推荐

所有评论(0)