SVPWM原理分析-基於STM32 MC SDK 5.0


FOC控制的整個過程如下:

   

   

論壇和貼子有很多講理論的,很少實際操作,本文理論聯系實際,為大家一步一步揭開SVPWM神秘的面紗。

本文基於ST-FOC 5.4 SVPWM函數分析,力爭讓讀者可以通過這篇文章了解SVPWM的本質:

SVPWM的目的如下:

SVPWM核心思想通過輸入的計算出三相 PWM占空比。

本文的目錄如下:

1.任意向量如何通過基本空間矢量合成?任意向量都可以通過相鄰的基本空間向量+V0+V7合成。

2.向量扇區的判斷?通過(α,β)坐標系下Vα和Vβ值的大小,判斷需要合成的向量位於哪個扇區。

3 .基本空間矢量作用時間計算?通過計算(α,β)坐標系下Vα和Vβ值的大小,計算出相鄰基本空間矢量作用的時間

4 .占空比計算如何計算?(高電平持續的時間or定時器寄存器的值)根據七段式SVPWM發波原理計算出:hTimePhA ,hTimePhB,hTimePhC的值。

5.總結 SVPWM原理總結。

6.附錄。

   

看一下SVPWM函數原型,輸入變量:

1

2

3

4

5

6

uint16_t PWMC_SetPhaseVoltage( PWMC_Handle_t * pHandle, alphabeta_t Valfa_beta )

typedef struct

{

int16_t alpha;

int16_t beta;

} alphabeta_t;

 

1.任意向量如何通過基本空間矢量合成?

1 典型三相逆變器拓撲

定義[a,b,c]表示逆變橋上半開關管的狀態,當a,b,c1是表示Q1,Q2,Q3導通,當a,b,c0時表示Q1,Q2,Q3關閉,且同一橋臂的上管和下管狀態相反。根據a,b,C的狀態組合,開關管一共有8種狀態。如下圖所示:

   

   

序號

開關管狀態

  

  

相電壓

  

  

線電壓

  

  

  

a

b

c

VAN

VBN

VCN

VAB

VBC

VCA

0

0

0

0

0

0

0

0

0

0

1

0

0

1

-Vdc/3

-Vdc/3

2Vdc/3

0

-Vdc

Vdc

2

0

1

0

-Vdc/3

2Vdc/3

-Vdc/3

-Vdc

Vdc

0

4

1

0

0

2Vdc/3

-Vdc/3

-Vdc/3

Vdc

0

-Vdc

3

0

1

1

-2Vdc/3

Vdc/3

Vdc/3

-Vdc

0

Vdc

5

1

0

1

Vdc/3

-2Vdc/3

Vdc/3

Vdc

-Vdc

0

6

1

1

0

Vdc/3

Vdc/3

-2Vdc/3

0

Vdc

-Vdc

7

1

1

1

0

0

0

0

0

0

1 開關狀態和相電壓,線電壓的關系

以上分析主要給予KCLKVL定律,有疑問的小伙伴可以復習一下電路的相關知識。其中有兩個零矢量和六個非零矢量,整個空間也被划分為以下六個扇區。應用clark變換(三相-兩相變換或者3/2變換,詳見《電力拖動自動控制系統-運動控制系統 》第四版 P164),將VAN,VBN,VCN 旋轉的坐標系轉換到靜止的(α,β)坐標系。

   

   

可以得到Vα和Vβ的計算公式:

Va+Vb+Vc=0Vc=-Va-Vb

 

   

 

   

 

   

得到計算公式如下:

   

   

a

b

c

VAN

VBN

Vsα

Vsβ

Vector

向量

角度

二進制

0

0

0

0

0

0

0

0

  

0

0[000]

1

0

0

2Vdc/3

-Vdc/3

2Vdc/3

0

2Vdc/3

V1

60

4[100]

1

1

0

Vdc/3

Vdc/3

Vdc/3

2Vdc/3

V2

120

6[110]

0

1

0

-Vdc/3

2Vdc/3

-Vdc/3

2Vdc/3

V3

180

2[010]

0

1

1

-2Vdc/3

Vdc/3

-2Vdc/3

0

2Vdc/3

V4

240

3[011]

0

0

1

-Vdc/3

-Vdc/3

-Vdc/3

2Vdc/3

V5

300

1[001]

1

0

1

Vdc/3

-2Vdc/3

Vdc/3

2Vdc/3

V6

360

5[101]

1

1

1

0

0

0

0

0

  

0

7[111]

2 clark變換后基本空間向量的計算【第一象限】

   

同理我們可以計算(α,β)在第四象限對應的轉換關系:

 

注意以上公式的變化點:

   

   

Va+Vb+Vc=0Vc=-Va-Vb

   

 

   

系數K的作用是可以將裝換變為等幅值或者等功率轉換

在這里我們才管用等幅值變換K=2/3,可以得到:

 

   

因此可以得到,如下公式:

   

a

b

c

VAN

VBN

Vsα

Vsβ

Vector

向量

角度

二進制

0

0

0

0

0

0

0

0

  

0

0[000]

1

0

0

2Vdc/3

-Vdc/3

2Vdc/3

0

2Vdc/3

V1

60

4[100]

1

1

0

Vdc/3

Vdc/3

Vdc/3

2Vdc/3

V2

120

6[110]

0

1

0

-Vdc/3

2Vdc/3

-Vdc/3

2Vdc/3

V3

180

2[010]

0

1

1

-2Vdc/3

Vdc/3

-2Vdc/3

0

2Vdc/3

V4

240

3[011]

0

0

1

-Vdc/3

-Vdc/3

-Vdc/3

2Vdc/3

V5

300

1[001]

1

0

1

Vdc/3

-2Vdc/3

Vdc/3

2Vdc/3

V6

360

5[101]

1

1

1

0

0

0

0

0

  

0

7[111]

   

   

2 clark變換后基本空間向量的計算【第四象限】

   

綜上所示,以上兩種情況得到的基本矢量分布如下:

   

   

   

   

以上可以看到,基本向量的相對位置是沒有改變的。

   

如下圖所示:(根據ST-官方教程如下圖所示)

   

2 基本空間矢量圖

   

大家要特別關注Vα和Vβ的方向,本文以STFOC庫為准。

圖中2有幾個問題比較有意思:

1).為什么矢量的排列順序是按照4-6-2-3-1-5 或者是4-5-1-3-2-6順序排列那?這里面值得順序是二進制開關組合代表的組合。

答案:這六個矢量控制的是功率半導體-Mosfet或者IGBT;這些管子在開關和導通過程中會有熱量產生,也就是損耗。為了最大限度的降低損耗,每個扇區(包含扇區內部)的開關切換,都需要保證只改動一個橋臂的動作,這樣發熱量最小,功率密度才能做更高

2).矢量的排列順序是4-6-2-3-1-5 或者是4-5-1-3-2-6順序代表什么意思?

答案:這是電機正反轉的區別,假定4-6-2-3-1-5 逆時針為電機正傳,則4-5-1-3-2-6表示反轉。

備注:不同文檔中矢量的名稱可能會有改變,這里影響不大,只要調整a,b,c的排列順序,大家就可以發現其實都一樣的,大家看文檔的時候不用過於糾結。

SVPWM的目的是為了通過基本的空間的矢量組合得到一個旋轉的向量VOUT ,VOUT 可以用(α,β)軸分Vα和Vβ表示(第四象限)

   

2 .扇區的判斷

   

代碼如下:

//下面是查找定子電流的扇區號

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

if (wY<0)

{

if (wZ<0)

{

bSector = SECTOR_5;

}

else // wZ >= 0

if (wX<=0)

{

bSector = SECTOR_4;

}

else // wX > 0

{

bSector = SECTOR_3;

}

}

else // wY > 0

{

if (wZ>=0)

{

bSector = SECTOR_2;

}

else // wZ < 0

if (wX<=0)

{

bSector = SECTOR_6;

}

else // wX > 0

{

bSector = SECTOR_1;

}

}     

   

VOUT 這個矢量按照我們的設定在圓內依次運行,在每個扇區內VOUT 都是有兩個相鄰的矢量根據不同的時間合成的矢量,因此第一步我們需要知道VOUT 在哪個扇區。

扇區

判斷條件

XwX

Y(wY)

Z(wZ)

SECTOR

I

>0

>0

<0

SECTOR_1

II

>0

>0

>0

SECTOR_2

III

>0

<0

>0

SECTOR_3

IV

<0

<0

>0

SECTOR_4

V

<0

<0

<0

SECTOR_5

VI

<0

>0

<0

SECTOR_6

3 扇區的判斷

                                                     

 

   

設定:X>0wX=1,否則wX=0.

設定:Y>0wY=1,否則wY=0.

設定:Z>0wZ=1,否則wZ=0.

程序中的定義:

1

2

3

4

5

6

wUAlpha = Stat_Volt_Input.qV_Component1 * T_SQRT3;

wUBeta = -(Stat_Volt_Input.qV_Component2 * T);

 

wX = wUBeta;

wY = (wUBeta + wUAlpha)/2;

wZ = (wUBeta - wUAlpha)/2;

   

   


3 基本空間矢量的作用時間計算

   

 

以上是理解下面運算的基礎。特別需要關注的是,(α,β)軸分Vα和Vβ表示(第四象限),在第一象限用Vα'Vβ'表示。

   

3 .基本空間矢量作用時間計算

   

知道扇區的位置,接下來計算矢量的作用時間。先討論一下扇區的發波問題,本文選取7段式SVPWM

關於更多SVPWM的發放方式,詳見:https://blog.csdn.net/michaelf/article/details/94013805

采用7段式SVPWM的優點是減少損耗,同時可以較少高次諧波含量,本文不再這里展開,大家了解一種即可

第一扇區計算:

4 第一扇區基本矢量作用是時間計算

   

   

其中TPWM波形周期,T4是基本矢量V4持續的時間,T6是基本矢量V6持續的時 間。T-T6-T4V0和V7矢量持續的時間。

Vout投影到兩個相鄰的兩個矢量V4,V6上,在坐標系α'和β'坐標系下計算,可以得到如下關系:

為了后續計算,基本向量歸一化處理,步驟如下:

所有的基本空間向量的幅值都是2Vdc/3,當兩個零電壓矢量作用時間為0時,一個PWM周期內非零電壓矢量的作用時間最長,此時的合成空間矢量幅值最大,由下圖可以,其幅值最大不會超過圖中所示的正六邊形邊界,而當合成矢量落在該邊界之外是,將發生過調試,逆變器輸出電壓波形將失真。

以上計算得到最大不失真矢量電壓為幅值為

   

5 基本空間矢量歸一化

因此計算:

得到 :

   

計算結果匯總如下:
 

扇區

N

T1

T2

T0+T7

I

3

-Z

X

T+Z-X

II

1

Z

Y

T-Y-Z

III

5

X

-Y

T-X+Y

IV

4

-X

Z

T+X-Z

V

6

-Y

-Z

T+Y+Z

VI

2

Y

-X

T+X-Y

   

4 基本矢量作用時間計算

詳細的計算可以參考一下鏈接:https://blog.csdn.net/michaelf/article/details/94013805

需要關注兩點,一個是Vβ的方向,一個是基本矢量的歸一化。

   

5基本矢量作用時間計算。

   

4 .占空比計算(高電平持續的時間or定時器寄存器的值)

   

根據3分析,我們可以計算出合成向量在不同的扇區,相鄰矢量作用的時間及 V0V7作用的時間。

向上代碼,后分析:

FOC 5.0代碼分析如下:

1

2

3

4

5

6

7

8

9

uint16_t PWMperiod; /**< PWM period expressed in timer clock cycles unit:

* @f$hPWMPeriod = TimerFreq_{CLK} / F_{PWM}@f$ */

#define PWM_PERIOD_CYCLES (uint16_t)(ADV_TIM_CLK_MHz*\

(unsigned long long)1000000u/((uint16_t)(PWM_FREQUENCY)))

   

#define ADV_TIM_CLK_MHz 72

#define PWM_FREQUENCY 16000

   

PWM_Handle_M1.PWMperiod = PWM_PERIOD_CYCLES,

   

   

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

  

__weak uint16_t PWMC_SetPhaseVoltage( PWMC_Handle_t * pHandle, alphabeta_t Valfa_beta )

{

int32_t wX, wY, wZ, wUAlpha, wUBeta, wTimePhA, wTimePhB, wTimePhC;

   

wUAlpha = Valfa_beta.alpha * ( int32_t )pHandle->hT_Sqrt3;

wUBeta = -( Valfa_beta.beta * ( int32_t )( pHandle->PWMperiod ) ) * 2;

   

wX = wUBeta;

wY = ( wUBeta + wUAlpha ) / 2;

wZ = ( wUBeta - wUAlpha ) / 2;

   

/* Sector calculation from wX, wY, wZ */

if ( wY < 0 )

{

if ( wZ < 0 )

{

pHandle->Sector = SECTOR_5;

wTimePhA = ( int32_t )( pHandle->PWMperiod ) / 4 + ( ( wY - wZ ) / ( int32_t )262144 );

wTimePhB = wTimePhA + wZ / 131072;

wTimePhC = wTimePhA - wY / 131072;

pHandle->lowDuty = wTimePhC;

pHandle->midDuty = wTimePhA;

pHandle->highDuty = wTimePhB;

}

else /* wZ >= 0 */

if ( wX <= 0 )

{

pHandle->Sector = SECTOR_4;

wTimePhA = ( int32_t )( pHandle->PWMperiod ) / 4 + ( ( wX - wZ ) / ( int32_t )262144 );

wTimePhB = wTimePhA + wZ / 131072;

wTimePhC = wTimePhB - wX / 131072;

pHandle->lowDuty = wTimePhC;

pHandle->midDuty = wTimePhB;

pHandle->highDuty = wTimePhA;

}

else /* wX > 0 */

{

pHandle->Sector = SECTOR_3;

wTimePhA = ( int32_t )( pHandle->PWMperiod ) / 4 + ( ( wY - wX ) / ( int32_t )262144 );

wTimePhC = wTimePhA - wY / 131072;

wTimePhB = wTimePhC + wX / 131072;

pHandle->lowDuty = wTimePhB;

pHandle->midDuty = wTimePhC;

pHandle->highDuty = wTimePhA;

}

}

else /* wY > 0 */

{

if ( wZ >= 0 )

{

pHandle->Sector = SECTOR_2;

wTimePhA = ( int32_t )( pHandle->PWMperiod ) / 4 + ( ( wY - wZ ) / ( int32_t )262144 );

wTimePhB = wTimePhA + wZ / 131072;

wTimePhC = wTimePhA - wY / 131072;

pHandle->lowDuty = wTimePhB;

pHandle->midDuty = wTimePhA;

pHandle->highDuty = wTimePhC;

}

else /* wZ < 0 */

if ( wX <= 0 )

{

pHandle->Sector = SECTOR_6;

wTimePhA = ( int32_t )( pHandle->PWMperiod ) / 4 + ( ( wY - wX ) / ( int32_t )262144 );

wTimePhC = wTimePhA - wY / 131072;

wTimePhB = wTimePhC + wX / 131072;

pHandle->lowDuty = wTimePhA;

pHandle->midDuty = wTimePhC;

pHandle->highDuty = wTimePhB;

}

else /* wX > 0 */

{

pHandle->Sector = SECTOR_1;

wTimePhA = ( int32_t )( pHandle->PWMperiod ) / 4 + ( ( wX - wZ ) / ( int32_t )262144 );

wTimePhB = wTimePhA + wZ / 131072;

wTimePhC = wTimePhB - wX / 131072;

pHandle->lowDuty = wTimePhA;

pHandle->midDuty = wTimePhB;

pHandle->highDuty = wTimePhC;

}

}

   

pHandle->CntPhA = ( uint16_t )wTimePhA;

pHandle->CntPhB = ( uint16_t )wTimePhB;

pHandle->CntPhC = ( uint16_t )wTimePhC;

   

return ( pHandle->pFctSetADCSampPointSectX( pHandle ) );

}

 

先看第一扇區七段式SVPWM的順序是:0-4-6-7-6-4-0.重點V0V7的作用時間相等。很重要。

   

扇區切換時間如下:X=1,Y=2

c橋臂: Tc=Tb-T2=Tb-X

同理可以推算出其他各個扇區的切換時間,匯總各個扇區的切換時間,對應關系如下:

扇區

I

II

III

IV

V

VI

備注

N

3

1

5

4

6

2

程序對應的名稱

Ta

hTimePhA

Tb

hTimePhB

Tc

Tb-X

Tb-Y

Tb-Y

Tb-X

Tb-Y

Tb-Y

hTimePhC

6 個橋臂作用時間計算

以上內容是結構STSVPWM教材分析,ST官方教程使用3PPT標識,詳細推到過程如以上所示。

結合代碼,我們會發現幾個問題點,

   

1) 為什么要除以4? pHandle->PWMperiod / 4

前面wUBeta 和wUAlpha 計算式PWMperiod *2,因此在這里需要除去2.實際結果是T/2.

參考PWM定時器配置:

1

2

3

4

5

6

 

htim1.Instance = TIM1;//設置頻率為16k

htim1.Init.Prescaler = ((TIM_CLOCK_DIVIDER) - 1);//分頻系數為0

htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;//TIM中央對齊模式1計數模式

htim1.Init.Period = ((PWM_PERIOD_CYCLES) / 2);/*Period max 4500 設置了在下一個更新事件裝入活動的自動重裝載寄存器周期的值。value0x0000~0xFFFF*/

htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;/*設置定時器時鍾CK_INT頻率與死區發生器以及數字濾波器采樣時鍾頻率分頻化。Value*/

htim1.Init.RepetitionCounter = REP_RATE;/*是否使用重復定時器,當該值不為0的時候,計數器計數值達到周期數時,該值減1,計數器重新計數,當該值減到0的時候才會產生事件。*/

htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

正好配置TIM1為中央對齊模式1(TIM_COUNTERMODE_CENTERALIGNED1),在上面代碼的配置中,載波周期為16KHz,Period(ARR)=4500,CH1的CntPhA (CCR)=800。采用的PWM1模式,

即CNT小於CCR時,輸出有效電平,大於CCR小於ARR時,輸出無效電平,又配置CHx的有效電平為高電平,CHxN的有效電平為高電平,則可以得到下面的PWM波形:

如果CHxN的有效電平是低電平,則輸出的CHx和CHxN的波形是相同的。(可能CHx和CHxN有效電平的叫法相反)

從以上可T=(PWM_PERIOD_CYCLES) / 2.,PWM_PERIOD_CYCLES=2T.

2)為什么要除以131072?((((T + wX) - wZ)/2)/131072)

Q15,電流采用了Q15表示(左對齊),2^15 = 32768

   

3)為什么要除以262144 ?( ( wX - wZ ) / ( int32_t )262144 );

同問題2,262144 =32768X4=Q15*4.

   

5.總結

6.補充內容,PPT截圖如下:

   

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM