/************************************************* ************************************************** ******* park逆變換,輸入Uq、Ud得到Ualpha、Ubeta Uα = Ud · cosθ - Uq · sinθ Uβ = Ud · sinθ + Uq · cosθ ************************************************** ************************************************** ******/ void inverseParkTransform(DQ_Def *dq, AlphaBeta_Def *alphaBeta, float angle) { float cosAngle = cos(angle); float sinAngle = sin(angle); alphaBeta->alpha = dq->d * cosAngle - dq->q * sinAngle; alphaBeta->beta = dq->d * sinAngle + dq->q * cosAngle; }
void set_PWM_value(uint16_t pwm_u,uint16_t pwm_v,uint16_t pwm_w) { __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, pwm_u); __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, pwm_v); __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, pwm_w); }至此SVPWM完成,現將完整的SVPWM程式碼貼進來:
/************************************************* ************************************************** ******* 將座標轉換中的反Park變換得到的Valpha 、Vbeta 轉換六路PWM輸出。 ************************************************** ************************************************** ******/ void SVPWM(AlphaBeta_Def *U_alphaBeta, SVPWM_Def *svpwm) { float sum; float k_svpwm; svpwm->Ts = 1.0f; // SVPWM的取樣週期 svpwm->U_alpha = U_alphaBeta->alpha; svpwm->U_beta = U_alphaBeta->beta; // step1 計算u1、u2和u3 // 計算SVPWM演算法中的三個控制電壓u1、u2和u3 svpwm->u1 = U_alphaBeta->beta; svpwm->u2 = -0.8660254f * U_alphaBeta->alpha - 0.5f * U_alphaBeta->beta; // sqrt(3)/2 ≈ 0.86603 svpwm->u3 = 0.8660254f * U_alphaBeta->alpha - 0.5f * U_alphaBeta->beta; // step2:磁區判斷 // 根據u1、u2和u3的正負情況來決定所處的磁區 svpwm->sector = (svpwm->u1 > 0.0f) + ((svpwm->u2 > 0.0f) << 1) + ((svpwm->u3 > 0.0f) << 2); // N=4 *C+2*B+A // step3:計算基本向量電壓作用時間(佔空比) // 根據磁區的不同,計算對應的t_a、t_b和t_c的值,表示產生的三相電壓的時間 switch (svpwm->sector) { case 5: // 磁區5 svpwm->t4 = svpwm->u3; svpwm->t6 = svpwm->u1; sum = svpwm->t4 + svpwm->t6; if (sum > svpwm->Ts) { k_svpwm = svpwm->Ts / sum; // svpwm->t4 = k_svpwm * svpwm->t4; svpwm->t6 = k_svpwm * svpwm->t6; } svpwm->t7 = (svpwm->Ts - svpwm->t4 - svpwm->t6) / 2; svpwm->ta = svpwm->t4 + svpwm->t6 + svpwm->t7; svpwm->tb = svpwm->t6 + svpwm->t7; svpwm->tc = svpwm->t7; break; case 1: // 磁區1 svpwm->t2 = -svpwm->u3; svpwm->t6 = -svpwm->u2; sum = svpwm->t2 + svpwm->t6; if (sum > svpwm->Ts) { k_svpwm = svpwm->Ts / sum; // 計算縮放係數 svpwm->t2 = k_svpwm * svpwm->t2; svpwm->t6 = k_svpwm * svpwm->t6; } svpwm->t7 = (svpwm->Ts - svpwm->t2 - svpwm->t6) / 2; svpwm->ta = svpwm->t6 + svpwm->t7; svpwm->tb = svpwm->t2 + svpwm->t6 + svpwm->t7; svpwm->tc = svpwm->t7; break; case 3: // 磁區3 svpwm->t2 = svpwm->u1; svpwm->t3 = svpwm->u2; sum = svpwm->t2 + svpwm->t3; if (sum > svpwm->Ts) { k_svpwm = svpwm->Ts / sum; // svpwm->t2 = k_svpwm * svpwm->t2; svpwm->t3 = k_svpwm * svpwm->t3; } svpwm->t7 = (svpwm->Ts - svpwm->t2 - svpwm->t3) / 2; svpwm->ta = svpwm->t7; svpwm->tb = svpwm->t2 + svpwm->t3 + svpwm->t7; svpwm->tc = svpwm->t3 + svpwm->t7; break; case 2: // 磁區2 svpwm->t1 = -svpwm->u1; svpwm->t3 = -svpwm->u3; sum = svpwm->t1 + svpwm->t3; if (sum > svpwm->Ts) { k_svpwm = svpwm->Ts / sum; // svpwm->t1 = k_svpwm * svpwm->t1; svpwm->t3 = k_svpwm * svpwm->t3; } svpwm->t7 = (svpwm->Ts - svpwm->t1 - svpwm->t3) / 2; svpwm->ta = svpwm->t7; svpwm->tb = svpwm->t3 + svpwm->t7; svpwm->tc = svpwm->t1 + svpwm->t3 + svpwm->t7; break; case 6: // 磁區6 svpwm->t1 = svpwm->u2; svpwm->t5 = svpwm->u3; sum = svpwm->t1 + svpwm->t5; if (sum > svpwm->Ts) { k_svpwm = svpwm->Ts / sum; // svpwm->t1 = k_svpwm * svpwm->t1; svpwm->t5 = k_svpwm * svpwm->t5; } svpwm->t7 = (svpwm->Ts - svpwm->t1 - svpwm->t5) / 2; svpwm->ta = svpwm->t5 + svpwm->t7; svpwm->tb = svpwm->t7; svpwm->tc = svpwm->t1 + svpwm->t5 + svpwm->t7; break; case 4: // 磁區4 svpwm->t4 = -svpwm->u2; svpwm->t5 = -svpwm->u1; sum = svpwm->t4 + svpwm->t5; if (sum > svpwm->Ts) { k_svpwm = svpwm->Ts / sum; // svpwm->t4 = k_svpwm * svpwm->t4; svpwm->t5 = k_svpwm * svpwm->t5; } svpwm->t7 = (svpwm->Ts - svpwm->t4 - svpwm->t5) / 2; svpwm->ta = svpwm->t4 + svpwm->t5 + svpwm->t7; svpwm->tb = svpwm->t7; svpwm->tc = svpwm->t5 + svpwm->t7; break; default: break; } // step4:6路PWM輸出 set_PWM_value(PWM_PERIOD*svpwm->ta,PWM_PERIOD*svpwm->tb,PWM_PERIOD*svpwm->tc); }
void svpwm_test(void) { float theta = 0; DQ_Def test_dq; AlphaBeta_Def test_ab; SVPWM_Def svpwm_out; test_dq.d = 0.0f; test_dq.q = 0.2f; for (theta = 0; theta < 6.2831853f; theta += 0.275f) { inverseParkTransform(&test_dq,&test_ab,theta); SVPWM(&test_ab,&svpwm_out); vofa_JustFloat_output(100.0f*svpwm_out.ta,100.0f*svpwm_out.tb,100.0f*svpwm_out.tc,0.0f); // HAL_Delay(1); } }