BoooomFOC_STSPIN32G4_EVB/BoooomCTL/Controller/SVPWM/SVPWM.c

171 lines
4.4 KiB
C
Raw Normal View History

2024-05-08 03:04:20 +08:00
//
// Created by ZK on 2023/3/16.
//
#include "SVPWM.h"
2024-05-10 02:39:53 +08:00
#define SVM 1
extern uint16_t cycleNum;
#define SQRT3 1.732050808f
#define LIMIT (float32_t)(0.9f / SQRT3)
#define LIMIT_UDC 16.0f
2024-05-17 00:43:58 +08:00
#define TS 3300
2024-05-10 02:39:53 +08:00
#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;
2024-05-17 00:43:58 +08:00
float channel1, channel2, channel3, udc = 12;
2024-05-10 02:39:53 +08:00
float uAlpha, uBeta;
float32_t iAlpha, iBeta;
float32_t id, iq;
2024-05-17 00:43:58 +08:00
inline void clarke_transform(float Ia, float Ib, float Ic, float *Ialpha, float *Ibeta) {
*Ialpha = Ia;
*Ibeta = (Ib - Ic) * ONE_BY_SQRT3;
}
2024-05-10 02:39:53 +08:00
2024-05-17 00:43:58 +08:00
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;
}
2024-05-10 02:39:53 +08:00
2024-05-17 00:43:58 +08:00
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;
2024-05-10 02:39:53 +08:00
}
2024-05-17 00:43:58 +08:00
2024-05-10 02:39:53 +08:00
inline int SVPWM(float uAlpha, float uBeta, float *tA, float *tB, float *tC) {
2024-05-08 03:04:20 +08:00
int Sextant;
2024-05-10 02:39:53 +08:00
if (uBeta >= 0.0f) {
if (uAlpha >= 0.0f) {
2024-05-08 03:04:20 +08:00
//quadrant I
2024-05-10 02:39:53 +08:00
if (ONE_BY_SQRT3 * uBeta > uAlpha)
2024-05-08 03:04:20 +08:00
Sextant = 2; //sextant v2-v3
else
Sextant = 1; //sextant v1-v2
} else {
//quadrant II
2024-05-10 02:39:53 +08:00
if (-ONE_BY_SQRT3 * uBeta > uAlpha)
2024-05-08 03:04:20 +08:00
Sextant = 3; //sextant v3-v4
else
Sextant = 2; //sextant v2-v3
}
} else {
2024-05-10 02:39:53 +08:00
if (uAlpha >= 0.0f) {
2024-05-08 03:04:20 +08:00
//quadrant IV
2024-05-10 02:39:53 +08:00
if (-ONE_BY_SQRT3 * uBeta > uAlpha)
2024-05-08 03:04:20 +08:00
Sextant = 5; //sextant v5-v6
else
Sextant = 6; //sextant v6-v1
} else {
//quadrant III
2024-05-10 02:39:53 +08:00
if (ONE_BY_SQRT3 * uBeta > uAlpha)
2024-05-08 03:04:20 +08:00
Sextant = 4; //sextant v4-v5
else
Sextant = 5; //sextant v5-v6
}
}
switch (Sextant) {
// sextant v1-v2
case 1: {
// Vector on-times
2024-05-10 02:39:53 +08:00
float t1 = uAlpha - ONE_BY_SQRT3 * uBeta;
float t2 = TWO_BY_SQRT3 * uBeta;
2024-05-08 03:04:20 +08:00
// PWM timings
*tA = (1.0f - t1 - t2) * 0.5f;
*tB = *tA + t1;
*tC = *tB + t2;
}
break;
// sextant v2-v3
case 2: {
// Vector on-times
2024-05-10 02:39:53 +08:00
float t2 = uAlpha + ONE_BY_SQRT3 * uBeta;
float t3 = -uAlpha + ONE_BY_SQRT3 * uBeta;
2024-05-08 03:04:20 +08:00
// PWM timings
*tB = (1.0f - t2 - t3) * 0.5f;
*tA = *tB + t3;
*tC = *tA + t2;
}
break;
// sextant v3-v4
case 3: {
// Vector on-times
2024-05-10 02:39:53 +08:00
float t3 = TWO_BY_SQRT3 * uBeta;
float t4 = -uAlpha - ONE_BY_SQRT3 * uBeta;
2024-05-08 03:04:20 +08:00
// PWM timings
*tB = (1.0f - t3 - t4) * 0.5f;
*tC = *tB + t3;
*tA = *tC + t4;
}
break;
// sextant v4-v5
case 4: {
// Vector on-times
2024-05-10 02:39:53 +08:00
float t4 = -uAlpha + ONE_BY_SQRT3 * uBeta;
float t5 = -TWO_BY_SQRT3 * uBeta;
2024-05-08 03:04:20 +08:00
// PWM timings
*tC = (1.0f - t4 - t5) * 0.5f;
*tB = *tC + t5;
*tA = *tB + t4;
}
break;
// sextant v5-v6
case 5: {
// Vector on-times
2024-05-10 02:39:53 +08:00
float t5 = -uAlpha - ONE_BY_SQRT3 * uBeta;
float t6 = uAlpha - ONE_BY_SQRT3 * uBeta;
2024-05-08 03:04:20 +08:00
// PWM timings
*tC = (1.0f - t5 - t6) * 0.5f;
*tA = *tC + t5;
*tB = *tA + t6;
}
break;
// sextant v6-v1
case 6: {
// Vector on-times
2024-05-10 02:39:53 +08:00
float t6 = -TWO_BY_SQRT3 * uBeta;
float t1 = uAlpha + ONE_BY_SQRT3 * uBeta;
2024-05-08 03:04:20 +08:00
// 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
2024-05-10 02:39:53 +08:00
int result_valid = *tA >= 0.0f && *tA <= 1.0f && *tB >= 0.0f && *tB <= 1.0f && *tC >= 0.0f && *tC <= 1.0f;
2024-05-08 03:04:20 +08:00
return result_valid ? 0 : -1;
2024-05-10 02:39:53 +08:00
// TIM1->CCR1 = channelA;
// TIM1->CCR2 = channelB;
// TIM1->CCR3 = channelC;
}