SVPWM-實戰


接SVPWM原理分析-基於STM32 MC SDK 5.0這篇文章,分析了基本原理和代碼

本章節講實戰操作,通過本文可以了解到程序的完整運行流程。,

1.硬件篇,要調試首先要了解基本的硬件狀態,本文調試使用的是STM32F302的主控。

MOS管驅動部分如圖1所示

   

配置接口如下:

PA7 ------> TIM1_CH1N

PB0 ------> TIM1_CH2N

PB1 ------> TIM1_CH3N

PA8 ------> TIM1_CH1

PA9 ------> TIM1_CH2

PA10 ------> TIM1_CH3

   

配置高級定時器TIM1 產生6路互補的PWM,帶剎車保護,詳細配置代碼如下,

把下面的程序段拷貝到main.c 中直接可以輸出PWM波形(BKIN下拉),方便讀者驗證

先看主程序:

 

 Volt_Components Vtest;

int8_t bSector;

int32_t wX, wY, wZ, wUAlpha, wUBeta;

int16_t hTimePhA=0, hTimePhB=0, hTimePhC=0;

   

int main(void)

{

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_TIM1_Init();

Vtest.qV_Component1=-5000;

Vtest.qV_Component2=-2000;

 

while (1)

{

HAL_Delay(500);

HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);

CALC_SVPWM( Vtest);

}

 

 

 

   

第一部分,定時器的初始化,如何判斷初始化正確:

 

static void MX_TIM1_Init(void)

{

   

/* USER CODE BEGIN TIM1_Init 0 */

   

/* USER CODE END TIM1_Init 0 */

   

TIM_ClockConfigTypeDef sClockSourceConfig = {0};

TIM_MasterConfigTypeDef sMasterConfig = {0};

TIM_OC_InitTypeDef sConfigOC = {0};

TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

   

/* USER CODE BEGIN TIM1_Init 1 */

   

/* USER CODE END TIM1_Init 1 */

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 設置了在下一個更新事件裝入活動的自動重裝載寄存器周期的值。

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

htim1.Init.RepetitionCounter = REP_RATE;/*是否使用重復定時器,

當該值不為0的時候,計數器計數值達到周期數時,該值減1,計數器重新計數,當該值減到0的時候才會產生事件。*/

htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

if (HAL_TIM_Base_Init(&htim1) != HAL_OK)

{

Error_Handler();

}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)

{

Error_Handler();

}

if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

{

Error_Handler();

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC4REF;

sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)

{

Error_Handler();

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 0;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

{

Error_Handler();

}

if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)

{

Error_Handler();

}

if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)

{

Error_Handler();

}

sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;

sBreakDeadTimeConfig.DeadTime = DEADTIME;

sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_LOW;

sBreakDeadTimeConfig.BreakFilter = 0;

sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;

sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_LOW;

sBreakDeadTimeConfig.Break2Filter = 0;

sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;

if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN TIM1_Init 2 */

   

/* USER CODE END TIM1_Init 2 */

HAL_TIM_MspPostInit(&htim1);

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);

HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1);

   

 

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);

HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2);

 

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);

HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_3);

 

// TIM1->CCR1=1000;//

//        TIM1->CCR2=4500/2;

// TIM1->CCR3=75;

   

} 

 

 以下內容是重點,關於確認TIM定制器的配置是否ok

 

 HAL_TIM_MspPostInit(&htim1); //GPIO 初始化

//以下是測試代碼:判斷GPIO的初始化是否OK,可以判斷死區的設置時間是否正確

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);

HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1);

 

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);

HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2);

 

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);

HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_3);

 

TIM1->CCR1=1000;//

  TIM1->CCR2=4500/2;

TIM1->CCR3=75;

 

 

 

 

   
   

PWM輸出占空比的范圍測試:

htim1.Init.Period =4500 ,頻率16K,對應的周期為:62.5uS,設定死區時間1000ns=1us。約占1.6%

占空比范圍測試:

序號

CCRX的值

TIM1_CH1N

占空比大小

TIM1_CH1N

高電平時間

TIM1_CH1

占空比大小

TIM1_CH1

高電平時間

備注

1

100

0.64%

0.4uS

96.15%

60us

  

2

500

9.615%

6us

87.18%

54.4us

  

3

1000

21.05%

13.2us

76.28%

47.6us

  

4

2250

48.72%

30.40

48.41%

30.4us

         

5

4420

96.79%

60.40us

0.32%

0.2us

  

6

4450

97.12%

(62.5-1.8)us

0

0

超限制

7

4490

98.08%

(62.5-1.2)us

0

0

  

8

70

0

0

96.8%

(62.5-2)us

  

9

5

0

0

98.4%

(62.5-1)us

  

   

從以上實驗可知,超出4420之后TIM1_CH1N輸出高電平,TIM1_CH1輸出低電平

實測在4420-4500和 0-100,存在一部分單橋臂占空比變化區間

 

   

   

   

   

   

   

通過以上測試可以得到CCRX的值的變化范圍,極其對應占空比的大小變化范圍。

結論如下:CCRX的變化為為:100-4400,對應的占空比變化范圍為:0.64%~96.79%。

如何判斷死區時間是否合適?

CH1,CH2為單片機的輸出信號,CH3MOS輸出信號,可以看到,時序上有明顯的滯后

滯后的主要原因在於MOS驅動電路的延時,驅動芯片采購:IRS2005驅動芯片

   

有驅動芯片可以得到,延時時間在160ns-220ns(驅動延時)左右。實際的延時誤差值在235ns(包含兩部分,驅動延時和mos開啟延時)

   

通道2PWM輸出,通道3位驅動芯片輸出端,延時位186ns。

   

   

   

   

   

   

CH1,CH2 MCU輸出波形,CH3CH4位驅動芯片輸出波形。

   

CH1 MOS輸出的波形, CH2為TIM1_CH1N,CH3為TIM1_CH1。實測占空比如下,調節TIM1_CH1的占空比其實就是調整

MOS輸出的占空比。上圖是CCRX的值為100是的數據。

   

CCRX=2500時的波形如下所示:

   

   

CCRX=4100時的波形如下所示:

   

   

通過以上可以看到,CCRX的值和MOS輸出的波形的占空比成正比,機CCRX值越大,MOS輸出的占空比越大。

   

死區時間的本質是為了防止上下管同時導通,造成MOS燒毀,或者損耗增大, 軟件設置死區時間為1000ns.

#define DEADTIME_NS        ((uint16_t)1000) //死區時間(ns),范圍:0-3500,死區時間:

   

   

#define DEADTIME_NS        ((uint16_t)1500) //死區時間(ns),范圍:0-3500,死區時間:

   

可以看到死區時間明顯改變,死區時間的大小和MOS的性能相關性比較大,一般來說推薦設置為1000ns,可以可以根據實際情況具體調整,判斷的依據,就是死區時間要大於MOS管的開區和關閉時間,即CH1的波形的上升時間和下降時間。

上升時間:100ns,下降時間100ns,選擇不同 MOS參數會有差異。

   

以上講了這么多,主要是梳理了一下PWMMCU的引腳輸出到控制MOS的輸出,整個流程,同時也回答了,如何判斷MOS死區時間設置是否爭取的問題。整個流程供大家參考。以上提供的豐富的波形,方便大家調試才考使用。

   

3.第三部分,回到正題,驗證第一篇文章中SVPWM函數輸入的Vα和Vβ到3路占空比的計算公式,是否正確。

   

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

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

 

/* Private macro -------------------------------------------------------------*/

/* USER CODE BEGIN PM */

#define SYSCLK_FREQ 72000000uL

#define TIM_CLOCK_DIVIDER 1

#define ADV_TIM_CLK_MHz 144

#define ADC_CLK_MHz 12

#define HALL_TIM_CLK 72000000uL

#define PWM_FREQUENCY 16000

#define SW_DEADTIME_NS 1000 /*!< Dead-time to be inserted

by FW, only if low side

signals are enabled */

#define DEAD_TIME_ADV_TIM_CLK_MHz (ADV_TIM_CLK_MHz * TIM_CLOCK_DIVIDER)

   

#define REP_RATE (1) //該參數可以調整電流環的刷新頻率,刷新周期:(REP_RATE + 1)/(2*PWM_FREQ)

#define PWM_PERIOD_CYCLES (uint16_t)(ADV_TIM_CLK_MHz*\

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

   

#define DEADTIME_NS        ((uint16_t)1000) //死區時間(ns),范圍:0-3500,死區時間:

          

#define DEADTIME (uint16_t)((unsigned long long)SYSCLK_FREQ/ 1*(unsigned long long)DEADTIME_NS/1000000000uL)

/* USER CODE END PM */

//SVPWM波形

#define SQRT_3                1.732051 //根號3

#define T           (PWM_PERIOD_CYCLES * 2) //TIM1 ARR值的4((PWM_PERIOD_CYCLES) / 2)

#define T_SQRT3 (uint16_t)(T * SQRT_3)

#define SECTOR_1        (uint32_t)1

#define SECTOR_2        (uint32_t)2

#define SECTOR_3        (uint32_t)3

#define SECTOR_4        (uint32_t)4

#define SECTOR_5        (uint32_t)5

#define SECTOR_6        (uint32_t)6

   

void CALC_SVPWM(Volt_Components Stat_Volt_Input)

{

// int8_t bSector;

// int32_t wX, wY, wZ, wUAlpha, wUBeta;

// int16_t hTimePhA=0, hTimePhB=0, hTimePhC=0;                

 

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;

 

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

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;

}

}                                                        

 

switch(bSector)                 //根據所在扇區號,計算三相占空比

{

case SECTOR_1:

case SECTOR_4:

hTimePhA = (T/8) + ((((T + wX) - wZ)/2)/131072);

hTimePhB = hTimePhA + wZ/131072;

hTimePhC = hTimePhB - wX/131072;

break;

case SECTOR_2:

case SECTOR_5:

hTimePhA = (T/8) + ((((T + wY) - wZ)/2)/131072);

hTimePhB = hTimePhA + wZ/131072;

hTimePhC = hTimePhA - wY/131072;

break;

 

case SECTOR_3:

case SECTOR_6:

hTimePhA = (T/8) + ((((T - wX) + wY)/2)/131072);

hTimePhC = hTimePhA - wY/131072;

hTimePhB = hTimePhC + wX/131072;

break;

default:

break;

}

 

TIM1->CCR1 = hTimePhA;

TIM1->CCR2 = hTimePhB;

TIM1->CCR3 = hTimePhC;

}

   

 

 

代碼分析可以,Vtest.qV_Component1即為Vα Vtest.qV_Component2即為Vβ,下文直接用Vα ,Vβ表示

Vα ,Vβ值的變化范圍為:-32767~+32767。可以根據上表的數據大小范圍,推算出不用扇區並計算出對應的hTimePhA,hTimePhB和hTimePhC的值。

注意Vα,(未轉換)的值模值不可超過32767,超出范圍的電壓矢量不可以生成。當控制矢量在空間旋轉 360°后,逆變器就能輸出一個周期的正弦波電壓。

   

扇區

hTimePhA

hTimePhB

hTimePhC

V1

V2

V3

A占空比

C占空比

D占空比

備注

I

1000

-1000

2343

2293

2156

12.37

11.95

11.03

51.92%

51.04%

47.92%

占空比1>2>3

I

20000

-5000

3600

1576

890

19.28

8.421

4.755

80.13%

35.14%

19.81%

21

II

2000

-5000

2487

2593

1906

13.16

13.63

9.66

55.13%

57.51%

42.31%

占空比2>1>3

Ii

2000

-20000

2487

3622

876

12.97

19.24

4.093

55.13%

80.51%

19.55%

22

III

-2000

-2000

2063

2473

2163

10.59

12.52

11.32

45.69%

53.99%

48.08%

占空比2>3>1

III

-30000

-2000

398

4102

3828

2.384

21.95

20.73

8.654%

91.05%

85.26%

23

IV

-2000

2000

2063

2163

2437

10.59

10.98

12.86

45.69

48.08

53.99

占空比3>2>1

IV

-20000

5000

890

2925

3611

5.118

15.43

19.18

19.55

65.96

80.19

24

V

-2000

5000

2013

1908

2594

10.36

9.753

13.65

44.55

42.49

57.69

占空比3>1>2

V

-2000

30000

2013

191

4310

10.37

1.062

23.14

44.55

4.167

95.83

25

VI

2000

3000

2471

2029

2440

13.00

10.43

12.79

54.81

45.05

54.17

占空比1>3>2

VI

20000

3000

3542

959

1370

18.94

5.201

7.017

78.59

21.41

30.45

Tu 26

  

  

  

  

  

  

  

  

  

  

  

  

  

   

   

hTimePhx=4500X占空比。

   

 

 

 21

   

   

 

圖22

   

   

   

 

 圖23

 

 

 

 圖24

 

 

 

 

 圖25

 

 

 

 

 圖26

   

  

這樣理論分析就和實際的計算統一了,扇區也對上了。總結如下所示

   

   

   

   

 

4.通過以上3個部分,完成了Vα到Vβ的每個轉換過程的分析,通過實戰了解每個過程的變化。存在問題,歡迎大家指正

   

 

   

 

 

 

   

 


免責聲明!

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



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