Hallo Ich habe einen Motorsteuerung für einen PMSM (BLDC) auf Basis eines AVR UC3C gebaut und verwende einen SVPWM Algorithmus den ich mir aus einer Application Note abgekupfert habe(siehe Anhang). Er funktioniert grundsätzlich und ich bekomme schöne Popokurven heraus. Der Algorithmus ist simpler als alle anderen die ich so im Netz gefunden habe und ich frage mich ob er auch einen Nachteil hat?! Er kommt ohne Sektorbestimmung aus! Vielleicht kann ihn ja jemand auch einfach gut gebrauchen...
1 | static inline void Inverse_Clarke_Transformation(void) //adopted invers clark from microchip AN1078 or TI |
2 | {
|
3 | Vr_a = U_alpha; |
4 | Vr_b = -(U_alpha >> 1) + dsp32_op_mul(_1Q31_SQR3_DIV2, (U_beta)); |
5 | Vr_c = -(U_alpha >> 1) - dsp32_op_mul(_1Q31_SQR3_DIV2, (U_beta)); |
6 | }
|
7 | |
8 | static inline void Calc_SVPWM(void) |
9 | {
|
10 | S32 Voff; |
11 | S32 V_Min; |
12 | S32 V_Max; |
13 | |
14 | V_Min = min3(Vr_a, Vr_b, Vr_c); |
15 | V_Max = max3(Vr_a, Vr_b, Vr_c); |
16 | Voff = (V_Min + V_Max) >> 1; |
17 | //Generate SVPWMs Vectors
|
18 | Vr_a = (Vr_a - Voff); |
19 | Vr_b = (Vr_b - Voff); |
20 | Vr_c = (Vr_c - Voff); |
21 | } //eof Calc_SVPWM |
22 | |
23 | static inline void Generate_PWM_Duties(void) |
24 | {
|
25 | S64 DutyA, DutyB, DutyC; |
26 | ////transform (-2048 .....0.....+2047)* ADC_SCALE to (1600....800....0)
|
27 | //PWM A
|
28 | //PWM = -((i_out - 2048*ADC_SCALE) * 1600/2/2^25))
|
29 | DutyA = -(Vr_a - FULLSCALE_S25); |
30 | DutyA *= default_duty_var; |
31 | Pwm_duty_a = (U32)(DutyA >> 25); |
32 | |
33 | //PWM B
|
34 | //PWM = -((i_out - 2048*ADC_SCALE) * 1600/2/2^25))
|
35 | DutyB = -(Vr_b - FULLSCALE_S25); |
36 | DutyB *= default_duty_var; |
37 | Pwm_duty_b = (U32)(DutyB >> 25); |
38 | |
39 | //PWM C
|
40 | //PWM = -((i_out - 2048*ADC_SCALE) * 1600/2/2^25))
|
41 | DutyC = -(Vr_c - FULLSCALE_S25); |
42 | DutyC *= default_duty_var; |
43 | Pwm_duty_c = (U32)(DutyC >> 25); |
44 | |
45 | //write in registers
|
46 | AVR32_PWM.channel[PWM_A_PWM_CHANNEL].cdtyupd = Pwm_duty_a; |
47 | AVR32_PWM.channel[PWM_B_PWM_CHANNEL].cdtyupd = Pwm_duty_b; |
48 | AVR32_PWM.channel[PWM_C_PWM_CHANNEL].cdtyupd = Pwm_duty_c; |
49 | //unlock to trigger update next periode
|
50 | AVR32_PWM.SCUC.updulock = 1; |
51 | } //eof static inline void Generate_PWM_Duties(void) |