// // 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 3400 #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; uint16_t channel1, channel2, channel3,udc=12; float uAlpha, uBeta; float32_t iAlpha, iBeta; float32_t id, iq; inline void inversePark(float ud, float uq, float Theta, float *uAlpha, float *uBeta) { float s = sinf(Theta / 57.2958f); float c = cosf(Theta / 57.2958f); *uAlpha = ud * c - uq * s; *uBeta = ud * s + uq * c; } #ifdef false inline int SVPWM(float uAlpha, float uBeta, float *tA, float *tB, float *tC) { float U1, U2, U3; uint8_t a, b, c, n = 0; U1 = uBeta; U2 = (SQRT3 * uAlpha - uBeta) / 2; U3 = (-SQRT3 * uAlpha - uBeta) / 2; if (U1 > 0) a = 1; else a = 0; if (U2 > 0) b = 1; else b = 0; if (U3 > 0) c = 1; else c = 0; n = (c << 2) + (b << 1) + a; switch (sectionMap[n]) { case 0: { channel1 = TS / 2; channel2 = TS / 2; channel3 = TS / 2; } break; case 1: { int16_t t4 = SQRT3 * TS * U2 / udc; int16_t t6 = SQRT3 * TS * U1 / udc; int16_t t0 = (TS - t4 - t6) / 2; channel1 = t4 + t6 + t0; channel2 = t6 + t0; channel3 = t0; } break; case 2: { int16_t t2 = -SQRT3 * TS * U2 / udc; int16_t t6 = -SQRT3 * TS * U3 / udc; int16_t t0 = (TS - t2 - t6) / 2; channel1 = t6 + t0; channel2 = t2 + t6 + t0; channel3 = t0; } break; case 3: { int16_t t2 = SQRT3 * TS * U1 / udc; int16_t t3 = SQRT3 * TS * U3 / udc; int16_t t0 = (TS - t2 - t3) / 2; channel1 = t0; channel2 = t2 + t3 + t0; channel3 = t3 + t0; } break; case 4: { int16_t t1 = -SQRT3 * TS * U1 / udc; int16_t t3 = -SQRT3 * TS * U2 / udc; int16_t t0 = (TS - t1 - t3) / 2; channel1 = t0; channel2 = t3 + t0; channel3 = t1 + t3 + t0; } break; case 5: { int16_t t1 = SQRT3 * TS * U3 / udc; int16_t t5 = SQRT3 * TS * U2 / udc; int16_t t0 = (TS - t1 - t5) / 2; channel1 = t5 + t0; channel2 = t0; channel3 = t1 + t5 + t0; } break; case 6: { int16_t t4 = -SQRT3 * TS * U3 / udc; int16_t t5 = -SQRT3 * TS * U1 / udc; int16_t t0 = (TS - t4 - t5) / 2; channel1 = t4 + t5 + t0; channel2 = t0; channel3 = t5 + t0; } break; default: break; } *tA = channel1; *tB = channel2; *tC = channel3; return 0; } #else 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; } #endif