一、SVPWM原理簡介算法
PWM(Pulse Width Modulation)脈寬調整,這是一種利用面積等效原理實現的控制技術。SVPWM(Space Vector PWM)空間矢量PWM控制,由於控制電動機內部的圓形旋轉磁場,最終須要控制的是電壓空間矢量。通常控制電機的三相電壓相互成120度,以正弦的形式變換。咱們須要控制的就是這三相電壓呈現這種形式來最終控制到電磁轉矩。主電路圖以下所示:函數
將三相電壓矢量以等幅計算方式轉換爲兩相矢量得:優化
因爲逆變器三相橋臂共有6個開關管,爲了研究各相上下橋臂不一樣開關組合時逆變器輸出的空間電壓矢量,特定義開關函數Sx(x=a、b、c) 爲:spa
(Sa、Sb、Sc)的所有可能組合共有八個,包括6個非零矢量 Ul(001)、U2(010)、U3(011)、U4(100)、U5(101)、U6(110)、和兩個零矢量 U0(000)、U7(111),下面以其中一種開關組合爲例分析,假設Sx(x=a、b、c)=(100),此時3d
求解上述方程可得:UaN=2Ud/三、UbN=-Ud/三、UcN=-Ud/3。同理可計算出其它各類組合下的空間電壓矢量,列表以下:code
表 1-1 開關狀態與相電壓和線電壓的對應關係blog
Saci |
Sb資源 |
Sc編譯器 |
矢量符號 |
線電壓 |
相電壓 |
||||
Uab |
Ubc |
Uca |
UaN |
UbN |
UcN |
||||
0 |
0 |
0 |
U0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
U4 |
Udc |
0 |
-Udc |
2/3*Udc | -1/3*Udc | -1/3*Udc |
1 |
1 |
0 |
U6 |
0 |
Udc |
-Udc |
1/3*Udc | 1/3*Udc | -2/3*Udc |
0 |
1 |
0 |
U2 |
-Udc |
Udc |
0 |
-1/3*Udc | 2/3*Udc | -1/3*Udc |
0 |
1 |
1 |
U3 |
-Udc |
0 |
0 |
-2/3*Udc | 1/3*Udc | 1/3*Udc |
0 |
0 |
1 |
U1 |
0 |
-Udc |
Udc |
-1/3*Udc | -1/3*Udc | 2/3*Udc |
1 |
0 |
1 |
U5 |
Udc |
-Udc |
0 |
1/3*Udc | -2/3*Udc | 1/3*Udc |
1 |
1 |
1 |
U7 |
0 |
0 |
0 |
0 |
0 |
0 |
八個基本電壓空間矢量的大小和位置入下圖所示:
若是某一瞬間要求的電壓控制鍵矢量在第一扇區,那麼能夠根據第一扇區的矢量U4以及U6以及零矢量U0或U7合成所要求的矢量U。通過計算,能夠獲得各矢量的狀態保持時間爲:
式中 m 爲 SVPWM 調製係數(調製比):若要求Uref的模保持恆定,則Uref的軌跡爲一圓形;若要求三相電壓波形不失真(即不飽和),則Uref的軌跡應在正六邊形內部;結合此兩點可知Uref的模取最大值時的軌跡爲正六邊形的內切圓,此時m=1,故m<=1。
咱們以減小開關次數爲目標,將基本矢量做用順序的分配原則選定爲:在每次開關狀態轉換時,只改變其中一相的開關狀態。而且對零矢量在時間上進行了平均分配,以使產生的 PWM對稱,從而有效地下降PWM的諧波份量。當 U4(100)切換至 U0(000)時,只需改變 A 相上下一對切換開關,若由 U4(100)切換至 U7(111)則需改變 B、C 相上下兩對切換開關,增長了一倍的切換損失。所以要改變電壓矢量U4(100)、U2(010)、U1(001)的大小,需配合零電壓矢量U0(000),而要改變U6(110)、U3(011)、U5(101),需配合零電壓矢量U7(111)。這樣經過在不一樣區間內安排不一樣的開關切換順序, 就能夠得到對稱的輸出波形,其它各扇區的開關切換順序如表 所示:
Uref 所在的位置 |
開關切換順序 |
三相波形圖 |
Ⅰ區(0°≤θ≤60°) |
…0-4-6-7-7-6-4-0… |
![]() |
Ⅱ區(60°≤θ≤120°) |
…0-2-6-7-7-6-2-0… |
![]() |
Ⅲ區(120°≤θ≤180°) |
…0-2-3-7-7-3-2-0… |
![]() |
Ⅳ區(180°≤θ≤240°) |
…0-1-3-7-7-3-1-0… |
![]() |
Ⅴ區(240°≤θ≤300°) |
…0-1-5-7-7-5-1-0… |
![]() |
Ⅵ區(300°≤θ≤360°) |
…0-4-5-7-7-5-4-0… |
![]() |
以第Ⅰ扇區爲例,其所產生的三相波調製波形在時間 Ts 時段中如圖所示,圖中電壓矢量出現的前後順序爲 U0、U四、U六、U七、U六、U四、U0,各電壓矢量的三相波形則與表 1-2 中的開關表示符號相對應。再下一個 TS 時段,Uref 的角度增長一個γ,利用式(1-8)能夠從新計算新的 T0、T四、T6 及 T7 值,獲得新的合成三相相似表(1-2)所示的三相波形;這樣每個載波週期TS就會合成一個新的矢量,隨着θ的逐漸增大,Uref 將依序進入第Ⅰ、Ⅱ、Ⅲ、Ⅳ、Ⅴ、Ⅵ區。在電壓向量旋轉一週期後,就會產生 R 個合成矢量。
經過以上 SVPWM 的法則推導分析可知要實現SVPWM信號的實時調製,首先須要知道參考電壓矢量 Uref 所在的區間位置,而後利用所在扇區的相鄰兩電壓矢量和適當的零矢量來合成參考電壓矢量。圖1-4是在靜止座標系(α,β)中描述的電壓空間矢量圖,電壓矢量調製的控制指令是矢量控制系統給出的矢量信號 Uref,它以某一角頻率ω在空間逆時針旋轉,當旋轉到矢量圖的某個 60°扇區中時,系統計算該區間所需的基本電壓空間矢量,並以此矢量所對應的狀態去驅動功率開關元件動做。當控制矢量在空間旋轉 360°後,逆變器就能輸出一個週期的正弦波電壓。
空間矢量調製的第一步是判斷由 Uα 和 Uβ所決定的空間電壓矢量所處的扇區。假定合成的電壓矢量落在第 I 扇區,可知其等價條件以下:
以上等價條件再結合矢量圖幾何關係分析,能夠判斷出合成電壓矢量 Uref 落在第 X扇區的充分必要條件,得出下表:
扇區 |
落在此扇區的充要條件 |
I |
Uα>0 ,Uβ>0 且Uβ/ Uα<sqrt(3) |
Ⅱ |
Uα>0 , 且Uβ/ |Uα|>sqrt(3) |
Ⅲ |
Uα<0 ,Uβ>0 且-Uβ/ Uα<sqrt(3) |
Ⅳ |
Uα<0 ,Uβ<0 且Uβ/ Uα<sqrt(3) |
Ⅴ |
Uβ<0 且-Uβ/|Uα|>sqrt(3) |
Ⅵ |
Uα>0 ,Uβ<0 且-Uβ/Uα<sqrt(3) |
若進一步分析以上的條件,有可看出參考電壓矢量Uref 所在的扇區徹底由Uβ, sqrt(3)Uα-Uβ, -sqrt(3)Uα- Uβ 三式決定,所以令:
再定義,若U1>0 ,則 A=1,不然 A=0; 若U 2>0 ,則 B=1,不然 B=0;若U3>0 ,則 C=1,不然 C=0。能夠看出 A,B,C 之間共有八種組合,但由判斷扇區的公式可知 A,B,C 不會同時爲 1 或同時爲 0,因此實際的組合是六種,A,B,C 組合取不一樣的值對 應着不一樣的扇區,而且是一一對應的,所以徹底能夠由 A,B,C 的組合判斷所在的扇區。爲區別六種狀態,令 N=4*C+2*B+A,則能夠經過下表計算參考電壓 矢量 Uref 所在的扇區。
N值與扇區對應關係
N |
3 |
1 |
5 |
4 |
6 |
2 |
扇區號 |
Ⅰ |
Ⅱ |
Ⅲ |
Ⅳ |
Ⅴ |
Ⅵ |
採用上述方法,只需通過簡單的加減及邏輯運算便可肯定所在的扇區,對於提升系統的響應速度和進行仿真都是頗有意義的。
最後由於程序中控制的是沒相電壓的佔空比,佔空比通過計算獲得以下表格
表 1-4 各扇區基本空間矢量的做用時間
扇區 |
時間 |
|
I |
![]() |
![]() |
Ⅱ |
![]() |
![]() |
Ⅲ |
![]() |
![]() |
Ⅳ |
![]() |
![]()
|
Ⅴ |
![]() |
![]()
|
Ⅵ |
![]() |
![]()
|
在扇區1中時間圖以下:
二、stm32f427資源簡介
a、 stm32f427帶有FPU,它有硬件的浮點計算器,因此執行SVPWM算法大體須要15us左右的時間
b、stm32f427的定時器1有7路PWM端口,其中6路是互補的PWM能夠實現對三相橋式電路的控制,另一路PWM端口,用來指示採樣電流的時間。
c、stm32f427有多路ADC轉換,而且分爲注入組與規則組,注入組的優先級高於規則組。SPWM算法就是在採樣相電流完成後處理的。
d、採樣相電流的時間:這裏採用的是雙電阻採樣法,採樣的時間是三相PWM都爲0的時候,這時候的電流狀態如圖所示,這時候採樣電阻上的電流就是相電流。如今的關鍵點是怎麼知道是處於零矢量的狀態,其實設置定時器1的PWM4佔空是4路PWM中最高的就能夠了,固然還須要考慮ADC的轉換時間,這有個壞處就是PWM佔空比將不能達到最大。
三、SVPWM算法程序實現
須要用到的結構體以下
struct CLARK { long Ia; //輸入,A相定子電流 long Ib; //輸入,B相定子電流 long Ic; //輸入,C相定子電流 long IAlpha; //輸出,靜止座標系Alpha軸定子電流 long IBeta; //輸出,靜止座標系Beta軸定子電流 void (*calcClark)(); void (*calcAntiClark)(); }; struct PARK { long Id; //輸出,旋轉座標系下的D座標值電流 long Iq; //輸出,旋轉座標系下的Q座標值電流 long IAlpha; //輸入,靜止座標系Alpha軸定子電流 long IBeta; //輸入,靜止座標系Beta軸定子電流 float Ud; //輸出,旋轉座標系下的D座標值電壓 float Uq; //輸出,旋轉座標系下的Q座標值電壓 float UAlpha; //輸入,靜止座標系Alpha軸定子電壓 float UBeta; //輸入,靜止座標系Beta軸定子電壓 long Theta; //旋轉座標角度 float ActId; //實際D軸電流 float ActIq; //實際Q軸電流 void (*calcPark)(); void (*calcAntiPark)(); }; struct SVPWM { float UAlpha; //輸入,靜止座標系Alpha軸定子電壓 float UBeta; //輸入,靜止座標系Beta軸定子電壓 long Ua; // long Ub; / long Uc; // long Tx; // long Ty; // long Tz; // long taOn; //A相時間 long tbOn; //B相時間 long tcOn; //C相時間 };
一、clark變換模塊程序,clark變換既將三相座標系轉換成二相固定座標系的變換。
static void Clark_calc(struct CLARK *v) { float sqrt_3 = SQRT_3;//添加浮點變量爲了編譯器優化調用硬件浮點指令 v->IAlpha = v->Ia; v->IBeta = (sqrt_3/3)*(v->Ia+(v->Ib*2)); }
二、park變換模快程序,park變換既二相固定座標系轉換成二相旋轉座標系的變換。存在旋轉座標系是爲了將永磁同步電機的勵磁電流與轉矩電流剝離。
#define SinPointNum 3600 extern const int Sin_Table[SinPointNum];//正弦表 static void Park_Calc(struct PARK *v) { long Sinthe,Costhe; UINT16 Point; Point = v->Theta; if(Point<2700) Costhe = Sin_Table[Point+900]; else Costhe = Sin_Table[Point-2700]; // Ualpha = Ucos(the) UpmMax = 2/3Udc Sinthe = Sin_Table[Point]; // Ubeta = Usin(the) v->Id = v->IAlpha*Costhe+v->IBeta*Sinthe; v->Iq = -v->IAlpha*Sinthe+v->IBeta*Costhe; v->Id = v->Id/0x8000; v->Iq = v->Iq/0x8000; v->ActId = (float)(v->Id)*7.15*3.3/4096;//最大采樣實際電流11.8a v->ActIq = (float)(v->Iq)*7.15*3.3/4096;//最大采樣實際電流11.8a }
三、反park變換,反park變換既二相旋轉座標系轉換成二相固定座標系的變換
static void Anti_Park_Calc(struct PARK *v) { int Sinthe,Costhe; UINT16 Point; Point = v->Theta; if(Point<2700) Costhe = Sin_Table[Point+900]; else Costhe = Sin_Table[Point-2700]; // Ualpha = Ucos(the) UpmMax = 2/3Udc Sinthe = Sin_Table[Point]; // Ubeta = Usin(the) v->UAlpha = v->Ud*(float)Costhe - v->Uq*(float)Sinthe;//範圍是-sqrt(2)μ?+sqrt(2) v->UBeta = v->Ud*(float)Sinthe + v->Uq*(float)Costhe;//範圍是-sqrt(2)μ?+sqrt(2) }
四、SVPWM模塊實現
static void Svpwm_Module(struct SVPWM *pstrSvpwm) { UINT8 u8Sector=0; UINT8 a,b,c; int t1,t2; int temp; float sqrt_3 = SQRT_3;//添加浮點變量爲了編譯器優化調用硬件浮點指令 float m = K; UINT8 Udc = MOTOR_POWER; /* 利用如下公式肯定扇區 */ // iClarkBeta_calc(&strSvpwm.v); // pstrSvpwm->v.Va = pstrSvpwm->v.Beta; // beta // pstrSvpwm->v.Vb = (AMP1000_SQRT_3*pstrSvpwm->v.Alpha/2 - pstrSvpwm->v.Beta*AMP1000/2)/AMP1000; // alpha*sqrt(3/4)-0.5*beta // pstrSvpwm->v.Vc = (-AMP1000_SQRT_3*pstrSvpwm->v.Alpha/2 - pstrSvpwm->v.Beta*AMP1000/2)/AMP1000; // -alpha*sqrt(3/4)-beta*0.5 pstrSvpwm->Ua = pstrSvpwm->UBeta; // beta pstrSvpwm->Ub = (sqrt_3*pstrSvpwm->UAlpha/2 - pstrSvpwm->UBeta/2); // alpha*sqrt(3)-beta pstrSvpwm->Uc = (-sqrt_3*pstrSvpwm->UAlpha/2 - pstrSvpwm->UBeta/2); // -alpha*sqrt(3)-beta if(pstrSvpwm->Ua>0) a = 1; else a = 0; if(pstrSvpwm->Ub>0) b = 1; else b = 0; if(pstrSvpwm->Uc>0) c = 1; else c = 0; u8Sector = 4*c + 2*b + a; //*24/MOTOR_POWER /* 利用下面公式計算出X、Y、Z 其中Ts爲Timer1_Period,Udc爲MOTOR_POWER*/ pstrSvpwm->Ua = sqrt_3*pstrSvpwm->Ua/Udc*Ts/(0x8000);//X=sqrt(3)*beta*Ts/Udc pstrSvpwm->Ub = sqrt_3*pstrSvpwm->Ub/Udc*Ts/(0x8000);//Y=(sqrt(3)/2*beta+3/2*alpha)*Ts/Udc pstrSvpwm->Uc = sqrt_3*pstrSvpwm->Uc/Udc*Ts/(0x8000);//Z=(sqrt(3)/2*beta-3/2*alpha)*Ts/Udc // pstrSvpwm->v.Va = SQRT_3*pstrSvpwm->v.Va*Ts/(0x8000)*K;//X=sqrt(3)*beta*Ts/Udc // pstrSvpwm->v.Vb = SQRT_3*pstrSvpwm->v.Vb*Ts/(0x8000)*K;//Y=(sqrt(3)/2*beta+3/2*alpha)*Ts/Udc // pstrSvpwm->v.Vc = SQRT_3*pstrSvpwm->v.Vc*Ts/(0x8000)*K;//Z=(sqrt(3)/2*beta-3/2*alpha)*Ts/Udc /* 計算SVPWM佔空比 */ switch(u8Sector) { case 0: pstrSvpwm->taOn = Time1_Period / 2; pstrSvpwm->tbOn = Time1_Period / 2; pstrSvpwm->tcOn = Time1_Period / 2; break; case 1: // if(Ts>(t1+t2)) { // t1 = -pstrSvpwm->v.Vc; // t2 = -pstrSvpwm->v.Vb; t1 = -pstrSvpwm->Ub;//U2t //這個U2矢量先發生,因此在前 t2 = -pstrSvpwm->Uc;//U6t } if(Ts<(t1+t2)) { t1 = t1*Ts/(t1+t2); t2 = t2*Ts/(t1+t2); } pstrSvpwm->tbOn = ((Ts)- t1 - t2)/4; //Tbon = (1-t1-t2)/4 pstrSvpwm->taOn = pstrSvpwm->tbOn + t1/2; //Taon = Tbon + t1/2 pstrSvpwm->tcOn = pstrSvpwm->taOn + t2/2; //Tcon = Taon + t2/2 break; //2號扇區 case 2: // t1 = -pstrSvpwm->v.Va; // t2 = -pstrSvpwm->v.Vc; t1 = -pstrSvpwm->Uc;//Ut4 t2 = -pstrSvpwm->Ua;//Ut5 if(Ts<(t1+t2)) { t1 = t1*Ts/(t1+t2); t2 = t2*Ts/(t1+t2); } pstrSvpwm->taOn = ((Ts)-t1 - t2)/4;//Taon = (1-t1-t2)/4 pstrSvpwm->tcOn = pstrSvpwm->taOn + t1/2; //Tcon = Taon + t1/2 pstrSvpwm->tbOn = pstrSvpwm->tcOn + t2/2; //Tbon = Tcon + t2/2 break;//6號扇區 case 3: t1 = pstrSvpwm->Ub;//Ut4 t2 = pstrSvpwm->Ua;//Ut6 if(Ts<(t1+t2)) { t1 = t1*Ts/(t1+t2); t2 = t2*Ts/(t1+t2); } pstrSvpwm->taOn = ((Ts)-t1 - t2)/4;//Taon = (1-t1-t2)/4 pstrSvpwm->tbOn = pstrSvpwm->taOn + t1/2; //Tbon = Taon + t1/2 pstrSvpwm->tcOn = pstrSvpwm->tbOn + t2/2; //Tcon = Tbon + t2/2 break;//1號扇區 case 4: // t1 = -pstrSvpwm->v.Vb; // t2 = -pstrSvpwm->v.Va; t1 = -pstrSvpwm->Ua;//Ut1 t2 = -pstrSvpwm->Ub;//Ut3 if(Ts<(t1+t2)) { t1 = t1*Ts/(t1+t2); t2 = t2*Ts/(t1+t2); } pstrSvpwm->tcOn = ((Ts)-t1 - t2)/4; //Tcon = (1-t1-t2)/4 pstrSvpwm->tbOn = pstrSvpwm->tcOn + t1/2; //Tbon = Tcon + t1/2 pstrSvpwm->taOn = pstrSvpwm->tbOn + t2/2; //Taon = Tbon + t2/2 break;//4號扇區 case 5: t1 = pstrSvpwm->Ua;//Ut2 t2 = pstrSvpwm->Uc;//Ut3 if(Ts<(t1+t2))//·防止發生過調整致使圓形電壓矢量失真,因此採起比列縮小 { t1 = t1*Ts/(t1+t2); t2 = t2*Ts/(t1+t2); } pstrSvpwm->tbOn = ((Ts)- t1 - t2)/4;//Tbon = (1-t1-t2)/4 pstrSvpwm->tcOn = pstrSvpwm->tbOn + t1/2; //Tcon = Tbon + t1/2 pstrSvpwm->taOn = pstrSvpwm->tcOn + t2/2; //Taon = Tcon + t2/2 break;//3號扇區 case 6: // t1 = pstrSvpwm->v.Vc; // t2 = pstrSvpwm->v.Vb; t1 = pstrSvpwm->Uc;//Ut1 t2 = pstrSvpwm->Ub;//Ut5 if(Ts<(t1+t2)) { t1 = t1*Ts/(t1+t2); t2 = t2*Ts/(t1+t2); } pstrSvpwm->tcOn = ((Ts) - t1 - t2)/4;//Tcon = (1-t1-t2)/4 pstrSvpwm->taOn = pstrSvpwm->tcOn + t1/2; //Taon = Tcon + t1/2 pstrSvpwm->tbOn = pstrSvpwm->taOn + t2/2; //Tbon = Taon + t2/2 break;//5號扇區 default:break; } /* stm32的中間對齊模式爲倒三角,因此從新計算佔空比 */ u16TimeAon = Time1_Period - (UINT16)pstrSvpwm->taOn; u16TimeBon = Time1_Period - (UINT16)pstrSvpwm->tbOn; u16TimeCon = Time1_Period - (UINT16)pstrSvpwm->tcOn; if(t1==0 && t2==0) { u16TimeAon = Time1_Period; u16TimeBon = Time1_Period; u16TimeCon = Time1_Period; } if(u16TimeAon>=(Limit_Pluse_Max_Value)) u16TimeAon = Limit_Pluse_Max_Value; if(u16TimeBon>=(Limit_Pluse_Max_Value)) u16TimeBon = Limit_Pluse_Max_Value; if(u16TimeCon>=(Limit_Pluse_Max_Value)) u16TimeCon = Limit_Pluse_Max_Value; TIM1->CCR1 = u16TimeAon;//Time1_Period/4;//u16TimeAon;//Time1_Period/4*3;////u16TimeAon;//下一個週期生效 TIM1->CCR2 = u16TimeBon;//0;//u16TimeBon;//Time1_Period/4;////u16TimeBon;//下一個週期生效 TIM1->CCR3 = u16TimeCon;//0;//u16TimeCon;//Time1_Period/4*3;////u16TimeCon;//下一個週期生效 }
開環控制的方式爲設定Ud=0,Uq=20.能夠看到電機轉動起來了。相電流的波形與轉速如圖所示:
紅色爲Ia相電流,綠色爲Ib相電流,在旋轉轉過程當中轉速相差爲8r/min