#include "foc/svpwm.h" #include "math/fast_math.h" void svpwm(alpha_beta_t *alpha_beta, float vbus, uint32_t PWM_half_period, phase_time_t *phase_out, u8 *sector_out){ float alpha = alpha_beta->alpha / (3.0f/2.0f * vbus); float beta = alpha_beta->beta / (3.0f/2.0f * vbus); uint32_t sector; if (beta >= 0.0f) { if (alpha >= 0.0f) { //quadrant I if (ONE_BY_SQRT3 * beta > alpha) { sector = SECTOR_2; } else { sector = SECTOR_1; } } else { //quadrant II if (-ONE_BY_SQRT3 * beta > alpha) { sector = SECTOR_3; } else { sector = SECTOR_2; } } } else { if (alpha >= 0.0f) { //quadrant IV5 if (-ONE_BY_SQRT3 * beta > alpha) { sector = SECTOR_5; } else { sector = SECTOR_6; } } else { //quadrant III if (ONE_BY_SQRT3 * beta > alpha) { sector = SECTOR_4; } else { sector = SECTOR_5; } } } // PWM timings u32 tA, tB, tC; u32 low, midle, high; switch (sector) { // sector 1-2 case SECTOR_1: { // Vector on-times uint32_t t1 = (alpha - ONE_BY_SQRT3 * beta) * PWM_half_period; uint32_t t2 = (TWO_BY_SQRT3 * beta) * PWM_half_period; // PWM timings tA = (PWM_half_period - t1 - t2) / 2; tB = tA + t1; tC = tB + t2; low = tA; midle = tB; high = tC; break; } // sector 2-3 case SECTOR_2: { // Vector on-times uint32_t t2 = (alpha + ONE_BY_SQRT3 * beta) * PWM_half_period; uint32_t t3 = (-alpha + ONE_BY_SQRT3 * beta) * PWM_half_period; // PWM timings tB = (PWM_half_period - t2 - t3) / 2; tA = tB + t3; tC = tA + t2; low = tB; midle = tA; high = tC; break; } // sector 3-4 case SECTOR_3: { // Vector on-times uint32_t t3 = (TWO_BY_SQRT3 * beta) * PWM_half_period; uint32_t t4 = (-alpha - ONE_BY_SQRT3 * beta) * PWM_half_period; // PWM timings tB = (PWM_half_period - t3 - t4) / 2; tC = tB + t3; tA = tC + t4; low = tB; midle = tC; high = tA; break; } // sector 4-5 case SECTOR_4: { // Vector on-times uint32_t t4 = (-alpha + ONE_BY_SQRT3 * beta) * PWM_half_period; uint32_t t5 = (-TWO_BY_SQRT3 * beta) * PWM_half_period; // PWM timings tC = (PWM_half_period - t4 - t5) / 2; tB = tC + t5; tA = tB + t4; low = tC; midle = tB; high = tA; break; } // sector 5-6 case SECTOR_5: { // Vector on-times uint32_t t5 = (-alpha - ONE_BY_SQRT3 * beta) * PWM_half_period; uint32_t t6 = (alpha - ONE_BY_SQRT3 * beta) * PWM_half_period; // PWM timings tC = (PWM_half_period - t5 - t6) / 2; tA = tC + t5; tB = tA + t6; low = tC; midle = tA; high = tB; break; } // sector 6-1 case SECTOR_6: { // Vector on-times uint32_t t6 = (-TWO_BY_SQRT3 * beta) * PWM_half_period; uint32_t t1 = (alpha + ONE_BY_SQRT3 * beta) * PWM_half_period; // PWM timings tA = (PWM_half_period - t6 - t1) / 2; tC = tA + t1; tB = tC + t6; low = tA; midle = tC; high = tB; break; } } phase_out->A = tA; phase_out->B = tB; phase_out->C = tC; phase_out->low = low; phase_out->midle = midle; phase_out->high = high; *sector_out = sector; }