程序来源:FOC SDK2.0
说明:在FOC SDK2.0的基础上稍稍修改,并做了一些注释,主要是为了记录总结收获。删掉或者注释了一些暂时用不到的功能。
下面是MC_Clarke_Park.c文件部分程序:
#ifdef MAX_MODULATION_100_PER_CENT //100%占空比
#define START_INDEX 63
const u16 circle_limit_table[65]=
{
32767,32390,32146,31907,31673,31444,31220,31001,30787,30577,30371,
30169,29971,29777,29587,29400,29217,29037,28861,28687,28517,
28350,28185,28024,27865,27709,27555,27404,27256,27110,26966,
26824,26685,26548,26413,26280,26149,26019,25892,25767,25643,
25521,25401,25283,25166,25051,24937,24825,24715,24606,24498,
24392,24287,24183,24081,23980,23880,23782,23684,23588,23493,
23400,23307,23215,23125
};
#endif
#define SIN_MASK 0x0300
#define U0_90 0x0200
#define U90_180 0x0300
#define U180_270 0x0000
#define U270_360 0x0100
static Trig_Components Vector_Components;
const s16 hSin_Cos_Table[256] = SIN_COS_TABLE; //正弦、余弦查表法
/*******************************************************************************
* Function Name : Clarke Transformation
* Description : This function transforms stator currents qIas and
* qIbs (which are directed along axes each displaced by
* 120 degrees) into currents qIalpha and qIbeta in a
* stationary qd reference frame.
* qIalpha = qIas
* qIbeta = -(2*qIbs+qIas)/sqrt(3)
* Input : Stat_Curr_a_b
* Output : Stat_Curr_alfa_beta
* Return : none.
*******************************************************************************/
Curr_Components Clarke(Curr_Components Curr_Input)
{
Curr_Components Curr_Output;
s32 qIa_divSQRT3_tmp;
s32 qIb_divSQRT3_tmp ;
s16 qIa_divSQRT3;
s16 qIb_divSQRT3 ;
// qIalpha = qIas
Curr_Output.qI_Component1= Curr_Input.qI_Component1;
qIa_divSQRT3_tmp = divSQRT_3 * Curr_Input.qI_Component1;
qIa_divSQRT3_tmp /=32768; //相当于10*divsqrt(3)*Curr_Input.qI_Component1
qIb_divSQRT3_tmp = divSQRT_3 * Curr_Input.qI_Component2;
qIb_divSQRT3_tmp /=32768; //相当于10*divsqrt(3)*Curr_Input.qI_Component2
qIa_divSQRT3=((s16)(qIa_divSQRT3_tmp));
qIb_divSQRT3=((s16)(qIb_divSQRT3_tmp));
//qIbeta = -(2*qIbs+qIas)/sqrt(3) beta轴滞后alpha轴,与常规不一样
Curr_Output.qI_Component2=(-(qIa_divSQRT3)-(qIb_divSQRT3)-(qIb_divSQRT3));
return(Curr_Output);
}
/*******************************************************************************
* Function Name : Park Transformation
* Description : This function transforms stator currents qIalpha and qIbeta,
* which belong to a stationary qd reference frame, to a rotor
* flux synchronous reference frame (properly oriented), so as
* to obtain qIq and qIds.每转65535个脉冲
* qId=qIalpha_tmp*sin(theta)+qIbeta_tmp*cos(Theta)
* qIq=qIalpha_tmp*cos(Theta)-qIbeta_tmp*sin(Theta) 与常规不一样
* Input : Stat_Curr_alfa_beta Theta是d与Beta之间的夹角
* Output : Stat_Curr_q_d.
* Return : Curr_Output.
*******************************************************************************/
Curr_Components Park(Curr_Components Curr_Input, s16 Theta)
{
Curr_Components Curr_Output;
s32 qId_tmp_1, qId_tmp_2;
s32 qIq_tmp_1, qIq_tmp_2;
s16 qId_1, qId_2;
s16 qIq_1, qIq_2;
Vector_Components = Trig_Functions(Theta);
//No overflow guaranteed
qIq_tmp_1 = Curr_Input.qI_Component1 * Vector_Components.hCos;
qIq_tmp_1 /= 32768;
//No overflow guaranteed
qIq_tmp_2 = Curr_Input.qI_Component2 *Vector_Components.hSin;
qIq_tmp_2 /= 32768;
qIq_1 = ((s16)(qIq_tmp_1));
qIq_2 = ((s16)(qIq_tmp_2));
//Iq component in Q1.15 Format
Curr_Output.qI_Component1 = ((qIq_1)-(qIq_2));
//No overflow guaranteed
qId_tmp_1 = Curr_Input.qI_Component1 * Vector_Components.hSin;
qId_tmp_1 /= 32768;
//No overflow guaranteed
qId_tmp_2 = Curr_Input.qI_Component2 * Vector_Components.hCos;
qId_tmp_2 /= 32768;
qId_1 = (s16)(qId_tmp_1);
qId_2 = (s16)(qId_tmp_2);
//Id component in Q1.15 Format
Curr_Output.qI_Component2 = ((qId_1)+(qId_2));
return (Curr_Output);
}
/*******************************************************************************
* Function Name : RevPark_Circle_Limitation
* Description : Check if
* Stat_Volt_q_d.qV_Component1^2 + Stat_Volt_q_d.qV_Component2^2 <= 32767^2
* Apply limitation if previous condition is not met,
* by keeping a constant ratio
* Stat_Volt_q_d.qV_Component1/Stat_Volt_q_d.qV_Component2
* 将经过PID调节后的Vd,Vq映射到0-32767,对应的占空比位0-100%
* 这就设计到合成矢量取模运算,即sqrt(Vd^2+Vq^2);
* 运算量比较大,查表法
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void RevPark_Circle_Limitation(void)
{
s32 temp;
temp = Stat_Volt_q_d.qV_Component1 * Stat_Volt_q_d.qV_Component1
+ Stat_Volt_q_d.qV_Component2 * Stat_Volt_q_d.qV_Component2; // min value 0, max value 2*32767*32767
if ( temp > (u32)(( MAX_MODULE * MAX_MODULE) ) ) // (Vd^2+Vq^2) > MAX_MODULE^2 ´大于最大调制比
{
u16 index;
temp /= (u32)(512*32768); // min value START_INDEX, max value 127
temp -= START_INDEX ; // min value 0, max value 127 - START_INDEX
//减去一个索引值,是因为前面的值都是32768,没有意义,存了浪费时间
index = circle_limit_table[(u8)temp]; //index = MMI*S16_Max^2/V_magnitude_index
temp = (s16)Stat_Volt_q_d.qV_Component1 * (u16)(index); //(Vq1)*MMI*S16_Max/V_mag
Stat_Volt_q_d.qV_Component1 = (s16)(temp/32768); //Vq=(Vq1)*MMI*S16_Max/(32768*V_mag)
temp = (s16)Stat_Volt_q_d.qV_Component2 * (u16)(index); //(Vd1)*MMI*S16_Max^2/V_mag
Stat_Volt_q_d.qV_Component2 = (s16)(temp/32768); //Vd=(Vd1)*MMI*S16_Max/(32768*V_mag)
}
}
/*******************************************************************************
* Function Name : Rev_Park Transformation
* Description : This function transforms stator voltage qVq and qVd, that
* belong to a rotor flux synchronous rotating frame, to a
* stationary reference frame, so as to obtain qValpha and qVbeta
* qValfa=qVq*Cos(theta)+qVd*Sin(theta)
* qVbeta=-qVq*Sin(theta)+qVd*Cos(theta)
* Input : Stat_Volt_q_d.
* Output : Stat_Volt_a_b
* Return : none.
*******************************************************************************/
Volt_Components Rev_Park(Volt_Components Volt_Input)
{
s32 qValpha_tmp1,qValpha_tmp2,qVbeta_tmp1,qVbeta_tmp2;
s16 qValpha_1,qValpha_2,qVbeta_1,qVbeta_2;
Volt_Components Volt_Output;
//No overflow guaranteed
qValpha_tmp1 = Volt_Input.qV_Component1 * Vector_Components.hCos;
qValpha_tmp1 /= 32768;
qValpha_tmp2 = Volt_Input.qV_Component2 * Vector_Components.hSin;
qValpha_tmp2 /= 32768;
qValpha_1 = (s16)(qValpha_tmp1);
qValpha_2 = (s16)(qValpha_tmp2);
Volt_Output.qV_Component1 = ((qValpha_1)+(qValpha_2));
qVbeta_tmp1 = Volt_Input.qV_Component1 * Vector_Components.hSin;
qVbeta_tmp1 /= 32768;
qVbeta_tmp2 = Volt_Input.qV_Component2 * Vector_Components.hCos;
qVbeta_tmp2 /= 32768;
qVbeta_1 = (s16)(qVbeta_tmp1);
qVbeta_2 = (s16)(qVbeta_tmp2);
Volt_Output.qV_Component2 = -(qVbeta_1)+(qVbeta_2);
return(Volt_Output);
}
/*******************************************************************************
* Function Name : Trig_Functions
* Description : This function returns Cosine and Sine functions of the input
* angle
* 该函数根据输入角返回三角余弦和正弦函数值
* Input : angle in s16 format
* Output : Cosine and Sine in s16 format
* Return : none.
*******************************************************************************/
Trig_Components Trig_Functions(s16 hAngle)
{
u16 hindex;
Trig_Components Local_Components;
/* 10 bit index computation */
hindex = (u16)(hAngle + 32768);
hindex /= 64;
switch (hindex & SIN_MASK)
{
case U0_90:
Local_Components.hSin = hSin_Cos_Table[(u8)(hindex)];
Local_Components.hCos = hSin_Cos_Table[(u8)(0xFF-(u8)(hindex))];
break;
case U90_180:
Local_Components.hSin = hSin_Cos_Table[(u8)(0xFF-(u8)(hindex))];
Local_Components.hCos = -hSin_Cos_Table[(u8)(hindex)];
break;
case U180_270:
Local_Components.hSin = -hSin_Cos_Table[(u8)(hindex)];
Local_Components.hCos = -hSin_Cos_Table[(u8)(0xFF-(u8)(hindex))];
break;
case U270_360:
Local_Components.hSin = -hSin_Cos_Table[(u8)(0xFF-(u8)(hindex))];
Local_Components.hCos = hSin_Cos_Table[(u8)(hindex)];
break;
default:
break;
}
return (Local_Components);
}
今天就能理解到这儿了,还有很多不理解的地方,改天继续。加油!