// // Created by ZK on 2023/3/16. // #include "SVPWM.h" #define SVM 1 extern uint16_t cycleNum; #define SQRT3 1.732050808f #define LIMIT (float32_t)(0.9f / SQRT3) #define LIMIT_UDC 16.0f #define TS 3300 #define SQRT3_MULT_TS (float32_t)((float32_t)TS * SQRT3) uint8_t sectionMap[7] = {0, 2, 6, 1, 4, 3, 5}; float32_t uAlpha, uBeta; float32_t ud, uq; float channel1, channel2, channel3, udc = 12; float uAlpha, uBeta; float32_t iAlpha, iBeta; float32_t id, iq; inline void clarke_transform(float Ia, float Ib, float Ic, float *Ialpha, float *Ibeta) { *Ialpha = Ia; *Ibeta = (Ib - Ic) * ONE_BY_SQRT3; } inline void park_transform(float Ialpha, float Ibeta, float Theta, float *Id, float *Iq) { float s = sinf(Theta / 57.29577951326093f); float c = cosf(Theta / 57.29577951326093f); *Id = Ialpha * c + Ibeta * s; *Iq = -Ialpha * s + Ibeta * c; } inline void inversePark(float ud, float uq, float Theta, float *uAlpha, float *uBeta) { float s = sinf(Theta / 57.29577951326093f); float c = cosf(Theta / 57.29577951326093f); *uAlpha = ud * c - uq * s; *uBeta = ud * s + uq * c; } inline int SVPWM(float uAlpha, float uBeta, float *tA, float *tB, float *tC) { int Sextant; if (uBeta >= 0.0f) { if (uAlpha >= 0.0f) { //quadrant I if (ONE_BY_SQRT3 * uBeta > uAlpha) Sextant = 2; //sextant v2-v3 else Sextant = 1; //sextant v1-v2 } else { //quadrant II if (-ONE_BY_SQRT3 * uBeta > uAlpha) Sextant = 3; //sextant v3-v4 else Sextant = 2; //sextant v2-v3 } } else { if (uAlpha >= 0.0f) { //quadrant IV if (-ONE_BY_SQRT3 * uBeta > uAlpha) Sextant = 5; //sextant v5-v6 else Sextant = 6; //sextant v6-v1 } else { //quadrant III if (ONE_BY_SQRT3 * uBeta > uAlpha) Sextant = 4; //sextant v4-v5 else Sextant = 5; //sextant v5-v6 } } switch (Sextant) { // sextant v1-v2 case 1: { // Vector on-times float t1 = uAlpha - ONE_BY_SQRT3 * uBeta; float t2 = TWO_BY_SQRT3 * uBeta; // PWM timings *tA = (1.0f - t1 - t2) * 0.5f; *tB = *tA + t1; *tC = *tB + t2; } break; // sextant v2-v3 case 2: { // Vector on-times float t2 = uAlpha + ONE_BY_SQRT3 * uBeta; float t3 = -uAlpha + ONE_BY_SQRT3 * uBeta; // PWM timings *tB = (1.0f - t2 - t3) * 0.5f; *tA = *tB + t3; *tC = *tA + t2; } break; // sextant v3-v4 case 3: { // Vector on-times float t3 = TWO_BY_SQRT3 * uBeta; float t4 = -uAlpha - ONE_BY_SQRT3 * uBeta; // PWM timings *tB = (1.0f - t3 - t4) * 0.5f; *tC = *tB + t3; *tA = *tC + t4; } break; // sextant v4-v5 case 4: { // Vector on-times float t4 = -uAlpha + ONE_BY_SQRT3 * uBeta; float t5 = -TWO_BY_SQRT3 * uBeta; // PWM timings *tC = (1.0f - t4 - t5) * 0.5f; *tB = *tC + t5; *tA = *tB + t4; } break; // sextant v5-v6 case 5: { // Vector on-times float t5 = -uAlpha - ONE_BY_SQRT3 * uBeta; float t6 = uAlpha - ONE_BY_SQRT3 * uBeta; // PWM timings *tC = (1.0f - t5 - t6) * 0.5f; *tA = *tC + t5; *tB = *tA + t6; } break; // sextant v6-v1 case 6: { // Vector on-times float t6 = -TWO_BY_SQRT3 * uBeta; float t1 = uAlpha + ONE_BY_SQRT3 * uBeta; // PWM timings *tA = (1.0f - t6 - t1) * 0.5f; *tC = *tA + t1; *tB = *tC + t6; } break; } // if any of the results becomes NaN, result_valid will evaluate to false int result_valid = *tA >= 0.0f && *tA <= 1.0f && *tB >= 0.0f && *tB <= 1.0f && *tC >= 0.0f && *tC <= 1.0f; return result_valid ? 0 : -1; // TIM1->CCR1 = channelA; // TIM1->CCR2 = channelB; // TIM1->CCR3 = channelC; }