//输入形参:AB相电流 __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; /* Iα = Ia*/ Output.alpha = Input.a; /* aTemp = Ia/sqrt(3) */ /* divSQRT_3[1/sqrt(3)]的值是0x49E6, 计算方法32768/sqrt(3)=18918 */ a_divSQRT3_tmp = divSQRT_3 * ( int32_t )Input.a; /* bTemp = Ib/sqrt(3) */ b_divSQRT3_tmp = divSQRT_3 * ( int32_t )Input.b; /* Ib = -Ia/sqrt(3) - Ib/sqrt(3) - Ib/sqrt(3) */ /* 右移15位的原因是divSQRT_3变量是Q15类型,所以要除以32768 */ wbeta_tmp = ( -( a_divSQRT3_tmp ) - ( b_divSQRT3_tmp ) - ( b_divSQRT3_tmp ) ) >> 15; /* 有效性判断 */ ... return ( Output ); }
//输入形参:α和β电流分量;电角度 __weak qd_t MCM_Park( alphabeta_t Input, int16_t Theta ) { qd_t Output; int32_t d_tmp_1, d_tmp_2, q_tmp_1, q_tmp_2; Trig_Components Local_Vector_Components; int32_t wqd_tmp; int16_t hqd_tmp; /* 查表法计算正弦和余弦值,Q15格式 */ Local_Vector_Components = MCM_Trig_Functions( Theta ); /* q_tmp_1=Iα*cos(θ) */ q_tmp_1 = Input.alpha * ( int32_t )Local_Vector_Components.hCos; /* q_tmp_2=Iβ*sin(θ) */ q_tmp_2 = Input.beta * ( int32_t )Local_Vector_Components.hSin; /* Iq=Iα*cos(θ)-Iβ*sin(θ),Q15格式所以要除以32768*/ wqd_tmp = ( q_tmp_1 - q_tmp_2 ) >> 15; /* 有效性判断 */ ... Output.q = hqd_tmp; /* d轴电流计算 */ ... return ( Output ); }
//输入形参:PID控制结构体;误差 __weak int16_t PI_Controller( PID_Handle_t * pHandle, int32_t wProcessVarError ) { int32_t wProportional_Term, wIntegral_Term, wOutput_32, wIntegral_sum_temp; int32_t wDischarge = 0; int16_t hUpperOutputLimit = pHandle->hUpperOutputLimit; int16_t hLowerOutputLimit = pHandle->hLowerOutputLimit; /* P调节:KpG*误差 */ wProportional_Term = pHandle->hKpGain * wProcessVarError; /* I系数是否有效 */ if ( pHandle->hKiGain == 0 ) { pHandle->wIntegralTerm = 0; } else { /* I调节:累计误差+KiG*误差 */ wIntegral_Term = pHandle->hKiGain * wProcessVarError; wIntegral_sum_temp = pHandle->wIntegralTerm + wIntegral_Term; ... } /* Kp=KpG/KpD Ki=KiG/KiD */ /* 为了保证计算过程不涉及浮点数,Kp和Ki用分数表示,这里需要除掉各自的分母 */ wOutput_32 = ( wProportional_Term >> pHandle->hKpDivisorPOW2 ) + ( pHandle->wIntegralTerm >> pHandle->hKiDivisorPOW2 ); ... return ( ( int16_t )( wOutput_32 ) ); }
void PIDCal(void) { //母线电压 采样电阻 电流放大倍数 线电感 线电阻 截止频率rad/s pwm频率 float Vbus = 48.0, Rshunt = 0.002, Aop = 27, Ls = 0.00016, Rs = 0.027, Wc = 4000, freq = 14000.0; float AB = Vbus * Rshunt * Aop / 3.3; float Kip = Ls * Wc / AB; float kii = Rs * Wc / AB / freq; printf("KIP : %f KII : %f\n", Kip, kii); }
//输入形参:q和d电压分量;电角度 __weak alphabeta_t MCM_Rev_Park( qd_t Input, int16_t Theta ) { int32_t alpha_tmp1, alpha_tmp2, beta_tmp1, beta_tmp2; Trig_Components Local_Vector_Components; alphabeta_t Output; Local_Vector_Components = MCM_Trig_Functions( Theta ); /* Vα= Vd*Sin(θ) + Vq*Cos(θ) */ alpha_tmp1 = Input.q * ( int32_t )Local_Vector_Components.hCos; alpha_tmp2 = Input.d * ( int32_t )Local_Vector_Components.hSin; Output.alpha = ( int16_t )( ( ( alpha_tmp1 ) + ( alpha_tmp2 ) ) >> 15 ); /* Vβ= Vd*Cos(θ) - Vq*Sin(θ) */ beta_tmp1 = Input.q * ( int32_t )Local_Vector_Components.hSin; beta_tmp2 = Input.d * ( int32_t )Local_Vector_Components.hCos; Output.beta = ( int16_t )( ( beta_tmp2 - beta_tmp1 ) >> 15 ); return ( Output ); }
//输入形参:q和d电压分量 __weak qd_t Circle_Limitation( CircleLimitation_Handle_t * pHandle, qd_t Vqd ) { uint16_t table_element; uint32_t uw_temp; int32_t sw_temp; qd_t local_vqd = Vqd; //Vqd的平方和 sw_temp = ( int32_t )( Vqd.q ) * Vqd.q + ( int32_t )( Vqd.d ) * Vqd.d; uw_temp = ( uint32_t ) sw_temp; /* Vqd的平方和 大于 设置的最大可调占空比时 */ if ( uw_temp > ( uint32_t )( pHandle->MaxModule ) * pHandle->MaxModule ) { /* 计算 Vqd的平方和 对应的数组下标 */ uw_temp /= ( uint32_t )( 16777216 ); uw_temp -= pHandle->Start_index; /* 获取缩小比例 */ table_element = pHandle->Circle_limit_table[( uint8_t )uw_temp]; /* 等比例缩小Vqd */ sw_temp = Vqd.q * ( int32_t )table_element; local_vqd.q = ( int16_t )( sw_temp / 32768 ); sw_temp = Vqd.d * ( int32_t )( table_element ); local_vqd.d = ( int16_t )( sw_temp / 32768 ); } return ( local_vqd ); }
const int16_t MAX_MODULE = 29490; int MMITable(void) { int32_t START_INDEX = MAX_MODULE * MAX_MODULE / 16777216; printf("START_INDEX: %d\n", START_INDEX); int32_t END_INDEX = 2 * 32767 * 32767 / 16777216; printf("END_INDEX: %d\n", END_INDEX); int32_t ARR_SIZE = END_INDEX - START_INDEX + 1; printf("ARR_SIZE: %d\n", ARR_SIZE); // int32_t ONE_PART = ((2 * 32767 * 32767) - (MAX_MODULE * MAX_MODULE)) / ARR_SIZE; int32_t ONE_PART = 16777216; printf("ONE_PART: %d\n", ONE_PART); double start = MAX_MODULE * MAX_MODULE; double temp = 0.0; int32_t result = 0; for(int32_t i = 1;i <= ARR_SIZE;i++) { temp = start / (start + i * ONE_PART); temp = sqrt(temp); result = temp * 32767; printf("%d,", result); if(i % 10 == 0) printf("\\\n"); } printf("\n"); return 0; }