foc学习笔记2——svpwm
foc學習筆記2——svpwm
寫在前面:如今網上關于foc的文章和教程很多,但初學者往往會被那些專業且復雜的公式搞暈,不知道自己到底在學什么。本文盡量少列公式,多解釋用途,所以不會有公式的推導過程,會更加注重結論以及用法,如果對公式推導有興趣的朋友還請參考其他文章。
最后:本人既不是電機工程師也不是相關專業的學生,純屬個人理解,有什么錯誤還請指出,也希望各位專業人士能嘴下留情。
1.svpwm是干什么的
? 前面說過,理想的foc可以產生任意方向的磁場,而svpwm就是實現這一點的關鍵。但我們電機的相數仍然是三相,可以輸出的磁場方向好像還是6個(1對級),那憑什么用了svpwm就能輸出任意方向的矢量?或許大家忽略了一個問題,矢量既有方向,也有大小,我們輸出的這6個方向的磁場是可以控制它的磁場強度的。再回到拉磨盤,難道我們拉磨盤就一定要一直使全力嗎?當然不是。我們即可以控制力的方向使其作用最大化,又可以控制力的大小來把握磨盤的轉速。換句話說,我們既可以控制矢量的大小,又可以控制矢量的方向。回到電機,雖然這6個磁場方向是固定的,但我們可以控制它們的大小。而我們又知道,矢量是可以合成、分解的,因此我們就可以使用這6個固定方向的磁場(這6個方向與之前六步換相的6個方向是不一樣的,因為一個是三相全導通一個只是兩兩導通),去合成任意方向的磁場。
? 電機內的線圈可以簡化成這個樣子(這是星型接法,還有三角型接法,兩者有什么區別可以自行查閱資料,星型接法更利于分析),三相線圈繞組最終在擰在一點,這個點就叫中性點。電流可以從其中兩相流入第三相流出,也可以從其中一相流入另外兩相流出,甚至也有可能從一相流入一相流出而第三相沒有電流流過,但絕對不可能從三相一起流入或流出。假設我們規定電流流入的繞組產生的磁場方向是正方向,流出的是負方向,那么我們就能得到6個基本矢量的方向,如下圖所示:
? 就像是在平面直角坐標系里面,任意一個矢量都可以分解為一個X方向上的矢量、一個Y方向上的矢量一樣,反過來我們可以使用這6個方向的基本矢量(其實我感覺是三個,某一方向的正負兩個應該算一個才對)去合成一個任意方向的矢量。但是,有兩點是要注意的:第一,我們不可能即使用某一相的正方向矢量又使用它的負方向矢量去合成,因為同一相的繞組它的電流不可能一邊流入一邊流出。第二,當其中兩相的矢量的大小和方向確定了,第三相的矢量也就確定了,因為根據基爾霍夫定律IA+IB+IC = 0,而矢量的大小(磁場強度)又跟電流成正比。所以根據這兩點我大膽猜測一下,合成一個任意矢量并不存在多個解。
? 下面這幅圖就展示了合成一個任意矢量時(但這幅圖的任意矢量只展示了不同方向卻未展示不同大小),對應的ABC三相矢量的大小和方向(正或負)。黑色的是合成矢量,紅色的是A相矢量,藍色的是B相矢量,綠色的是C相矢量。這幅動圖做的非常好(感謝這位大佬)。
? 回到正題,想一想我們的最終目的是什么?svpwm的最終目的是什么?就是為了計算要輸出任意大小和方向的矢量時,ABC三相的電流大小。而我們的三相全橋是不能直接輸出電流的,就連輸出電壓也做不到,只能輸出任意占空比的方波,那怎么辦?很簡單,還記得pwm直流脈寬調制嗎,沒錯就是它,我們可以輸出等效的電壓,而電壓與電流之間差的也只是一個系數。所以我們的最終目的可以略微的改一改,改成:計算要輸出任意大小和方向的矢量時,ABC三相的占空比大小。
2.如何用代碼實現svpwm
本節大量參考引用了SVPWM的原理及法則推導和控制算法詳解第五修改版.pdf中的內容及結論,所以還請結合這篇文檔一同觀看,鏈接放在底部。這篇文檔中的公式沒有任何問題,個人也憑借著其中的公式順利地使電機轉起來了,但內容較為雜亂,初次閱讀可能會抓不住重點。
(1)使用簡易版svpwm生產三相馬鞍波
? 通過上一小節我們已經知道,任意一個矢量都可由ABC方向上的矢量合成。只不過,相比三相的坐標系,我們顯然更加熟悉直角坐標系,所以首先要進行坐標變換,把三相變為兩相。對于幅值不變的坐標變換,三相變兩相需要乘以一個系數三分之二(2/3),為什么要乘以這個系數可以閱讀一下克拉克變換的推導過程,較為復雜這里就不作介紹了。所以下面的6個非零基本矢量的模長為 2/3Udc。
? 意思就是U1到U6這六個矢量的模長都為2/3Udc,注意現在的坐標系是兩相的α-β坐標系。1到6是怎么來的,就是括號內的二進制數轉化來的。而括號內的二進制數的來源請看下表:(其中1代表接Udc,0代表接地。)
| 0 | 0 | 0 | U0 | 
| 1 | 0 | 0 | U4 | 
| 1 | 1 | 0 | U6 | 
| 0 | 1 | 0 | U2 | 
| 0 | 1 | 1 | U3 | 
| 0 | 0 | 1 | U1 | 
| 1 | 0 | 1 | U5 | 
| 1 | 1 | 1 | U7 | 
? 除了圖中的6個矢量以外,還多了兩個零矢量U0和U7,零矢量有什么作用?就是為了在不使出全力的情況下插入用的。因為零矢量對于合成目標矢量是不起任何作用的,相當于在“偷懶”。“偷懶”的比例多了,使出來的力就小了。(這部分個人感覺自己講的不好,希望各位能看懂吧,實在看不懂就跳到后面看結論)
? 有了這8個基本矢量,我們終于能用它們來合成任意矢量了。假設一個任意矢量落在第一扇區,也就是U4和U6之間(不要問為什么要落在這里而不是其他地方,因為它是每隔60°都是一樣的,算明白一個就行)。那么我們就可以使用U4、U6以及兩個零矢量去合成它。
? Uref就是我們想要合成的目標矢量,Ts為mos管一次開關的時間。然后由伏秒平衡原理可以得到Uref乘以它的作用時間就等于U4乘以它的作用時間再加上U6乘以它的作用時間:
 Uref?Ts=U6?T6+U4?T4Uref*Ts = U6*T6 + U4*T4 Uref?Ts=U6?T6+U4?T4
 然后我們就可以列出方程求出T4和T6:(其實就是高中的三角函數并不難,這里就不推導了)
? T4和T6便是我們最終想要的結果,得到它基本就得到了pwm三個通道的占空比大小。后邊還有七段式和五段式的svpwm,其實區別就在怎么分配T4、T6以及零矢量的作用時間,這邊已經講得有點多了,大家自己下去看吧。最后注意幾點,零矢量的作用時間等于Ts減去T4和T6,對于七段式的svpwm,T0和T7均勻分配。如果Ts剛好等于T4加T6,那么意思就是出了全力;如果T4加T6比Ts還要大,那就說明你想要的Uref已經超出了系統能夠輸出的范圍,這是絕對不允許的。如何判斷想要的矢量有沒有超出系統的輸出范圍,只要看m是不是小于等于1就行,換句話說就是Uref要小于等于三分之根號三倍的Udc。
? 理論的東西已經說得夠多了,下面上代碼:
void svpwm(int16_t angle, float m) {uint16_t t4, t6, t0;uint8_t section; //扇區section = angle / 60 + 1; //得到角度對應的扇區angle %= 60; //因為前面的算法只計算了0到60度/*得到矢量的作用時間,除以57.2958是把角度換算成弧度*/t4 = sinf((60 - angle) / 57.2958f)*Ts*m; t6 = sinf(angle / 57.2958f)*Ts*m;t0 = (Ts - t4 - t6) / 2;/*判斷扇區,用7段式svpwm調制,得到三個通道的裝載值*/switch(section){case 1:{ch1 = t4 + t6 + t0;ch2 = t6 + t0;ch3 = t0;}break;case 2:{ch1 = t4 + t0;ch2 = t4 + t6 + t0;ch3 = t0;}break;case 3:{ch1 = t0;ch2 = t4 + t6 + t0;ch3 = t6 + t0;}break;case 4:{ch1 = t0;ch2 = t4 + t0;ch3 = t4 + t6 + t0;}break;case 5:{ch1 = t6 + t0;ch2 = t0;ch3 = t4 + t6 + t0;}break;case 6:{ch1 = t4 + t6 + t0;ch2 = t0;ch3 = t4 + t0;}break;default:break;}/*如果有需要可以讓硬件輸出波形*/ // TIM1->CCR1 = ch1; // TIM1->CCR2 = ch2; // TIM1->CCR3 = ch3;SendWave(ch1, ch2, ch3); //使用串口示波器顯示波形 }? 這里的Ts就是定時器的預裝載值,比如1000,而角度可以從0到360度自己循環給定,然后將這個函數周期性調用即可(這里的m給的是1,也就是出全力)。串口示波器用的是匿名上位機(這里非常感謝匿名團隊)。下面看一下輸出的波形如何:
? 可以看到輸出了非常標準的三相馬鞍波。每一個縱坐標軸對應一個角度,三相波形在此縱坐標下的橫坐標的值即是定時器三個pwm通道的裝載值。當然如果有不信邪的,也可以用單片機硬件輸出pwm波再用示波器測量,但別忘了加個RC低通濾波器,否則你只能看到方波(我這邊之前已經試過了,確實是三相馬鞍波)。而后面的硬件電路三相全橋也只是對pwm波起到一個功率放大的作用,并不會改變實際的波形(當然由于死區時間和傳導延時,會有一丟丟的影響)。
? 但是各位有沒有發現有什么不對勁的?如果你不需要電流閉環,只需要讓電機轉起來的話(記得將編碼器讀到的電角度加或減90°),那么已經成功了,甚至還可以調節m的大小來給電機調速。但還記得第一節講的foc框圖嗎,svpwm的前面是反克拉克變換和反帕克變換,而反Park變換的輸入是ud、uq和θ,θ我們看到了,但ud和uq去哪了?還有uα、uβ、uA、uB、uC我們都沒看到。我們手里能夠控制的只有m一個,這根本就沒辦法實現電流閉環。
(2)帶有反Park變換的svpwm
? 為了對接電流環,我們希望給定ud、uq以及檢測到的轉子電角度來生成三相馬鞍波。那回到第一章的foc框圖,我們需要將ud、uq以及θ經過反Park變換得到uα、uβ,再經過反Clarke變換得到uA、uB、uC,最終送給svpwm生成三相馬鞍波。但實際上我們并不是一定要這樣,經過反Park變換后,我們可以使用uα、uβ直接送給svpwm。
? 下面就簡單地說一下反Park變換。它是將ud、uq兩個直流的量變為uα、uβ兩個交流的量,將D-Q這個旋轉的坐標系變為α-β這個靜止坐標系。為什么會有旋轉的坐標系?因為電機是不斷旋轉的,而我們又希望磁場力方向始終與轉子相差90°,那怎么辦?干脆就以轉子建立坐標系好了,轉子怎么轉,坐標系就怎么轉,轉子不轉,它也不轉。只要保證電流的矢量方向盡可能地和Q軸平行,那磁場力的方向就能盡可能地和轉子保持90°,使力的作用最大化。但我們無法直接控制電流,只能控制電壓,所以暫時退而求其次,讓合成電壓的矢量方向和Q軸平行。對于要求不高的場合,直接控制電壓也能達到不錯的效果。但對于要求高的場合,我們還是希望能控制電流,因為磁場強度和電流相關而不是和電壓相關,而電流反饋的意義就在于此。(這里扯遠了,電流環應該是下一章再講)
那為什么又要有靜止坐標系?因為電機的線圈實實在在的固定在那,又不能和轉子一起轉,所以只好建立在靜止坐標系上了。由旋轉坐標系變化為靜止坐標系其實很簡單,就兩條三角函數的等式,大家不用想得太復雜:
? 可能看到這會有點煩,這好好的為什么總要變換來變換去的,但說出來可能不信,這樣是為了簡化問題。由前面的三相馬鞍波波形得知,我們的電機是交流電機,因為三相的電壓不停地在變化,但因為旋轉坐標系的建立,使得我們的電機變成了直流電機。給定ud為0,調整uq的大小,即可控制電機的轉速以及轉矩,是不是和有刷電機的調壓調速一模一樣。
? 好了,扯了這么多,差點都忘了正題了。ud和uq是我們給定的,θ是讀編碼器讀來的,所以自然而然地我們得到了uα和uβ。然后怎么辦,套公式用結論,大家看那篇文檔的11、12、14、15頁吧,其他就不用看了,我還是把代碼貼出來吧:
uint8_t sectionMap[7] = {0, 2, 6, 1, 4, 3, 5}; uint16_t channel1, channel2, channel3; float32_t uAlpha, uBeta;void InversePark(float32_t sinVal, float32_t cosVal, float32_t ud, float32_t uq) { uAlpha = ud * cosVal - uq * sinVal;uBeta = uq * cosVal + ud * sinVal; }void SVPWM_Generate(float32_t udc) {float32_t U1, U2, U3;uint8_t a, b, c, n = 0;U1 = uBeta;U2 = (SQRT3 * uAlpha - uBeta) / 2;U3 = (-SQRT3 * uAlpha - uBeta) / 2;if(U1 > 0)a = 1;else a = 0;if(U2 > 0)b = 1;else b = 0;if(U3 > 0)c = 1;else c = 0;n = (c << 2) + (b << 1) + a;switch(sectionMap[n]){case 0:{channel1 = TS / 2;channel2 = TS / 2;channel3 = TS / 2;}break;case 1:{int16_t t4 = SQRT3 * TS * U2 / udc;int16_t t6 = SQRT3 * TS * U1 / udc;int16_t t0 = (TS - t4 - t6) / 2;channel1 = t4 + t6 + t0;channel2 = t6 + t0;channel3 = t0;}break;case 2:{int16_t t2 = -SQRT3 * TS * U2 / udc;int16_t t6 = -SQRT3 * TS * U3 / udc;int16_t t0 = (TS - t2 - t6) / 2;channel1 = t6 + t0;channel2 = t2 + t6 + t0;channel3 = t0;}break;case 3:{int16_t t2 = SQRT3 * TS * U1 / udc;int16_t t3 = SQRT3 * TS * U3 / udc;int16_t t0 = (TS - t2 - t3) / 2;channel1 = t0;channel2 = t2 + t3 + t0;channel3 = t3 + t0;}break;case 4:{int16_t t1 = -SQRT3 * TS * U1 / udc;int16_t t3 = -SQRT3 * TS * U2 / udc;int16_t t0 = (TS - t1 - t3) / 2;channel1 = t0;channel2 = t3 + t0;channel3 = t1 + t3 + t0;}break;case 5:{int16_t t1 = SQRT3 * TS * U3 / udc;int16_t t5 = SQRT3 * TS * U2 / udc;int16_t t0 = (TS - t1 - t5) / 2;channel1 = t5 + t0;channel2 = t0;channel3 = t1 + t5 + t0;}break;case 6:{int16_t t4 = -SQRT3 * TS * U3 / udc;int16_t t5 = -SQRT3 * TS * U1 / udc;int16_t t0 = (TS - t4 - t5) / 2;channel1 = t4 + t5 + t0;channel2 = t0;channel3 = t5 + t0;}break;default:break;}TIM1->CCR1 = channel1;TIM1->CCR2 = channel2;TIM1->CCR3 = channel3; }? 到了這里,電機已經可以順利的轉起來了。你可以給定不同的uq來控制電機的轉速以及轉矩,這種控制方式就叫電壓開環控制。
3.名詞解釋
(1)線電壓
? 電機三相中某兩相之間的電壓。
(2)中性點
? 星型接法的電機,三相繞組一頭引出另一頭全部擰在一起,擰在一起的地方就叫做中性點,可以當做電壓為0的地方。
(3)相電壓
? 電機三相中某一相到中性點之間的電壓。
(4)Udc
? 是指三相全橋電路的直流供電電壓(電機驅動器的直流供電電壓),也被叫做直流母線電壓。
(5)Ts
? mos管一次開關所用的時間,可近似為單片機輸出pwm方波的周期。Ts的倒數既是開關頻率,對于電機驅動而言,一般取10kHz~30kHz,太低會降低響應速度,太高則會增加mos管開關損耗。
參考資料:
文檔:SVPWM的原理及法則推導和控制算法詳解第五修改版 提取碼:2617
視頻:硬石相關章節
博客:FOC入門教程
視頻:匿名上位機V7版–0基礎教程4–高速波形顯示
視頻:唐老師講電賽
總結
以上是生活随笔為你收集整理的foc学习笔记2——svpwm的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 全国计算机等级考试题库二级C操作题100
- 下一篇: 第十三章、拷贝控制
