在無法從電網獲得交流電源的情況下,通常需要逆變器電路。逆變器電路用于將直流電轉換為交流電,可分為純正弦波逆變器和改進方波逆變器兩種類型。這些純正弦波逆變器非常昂貴,而改進的方波逆變器價格低廉。在此處了解有關 不同類型逆變器的更多信息 。在這篇文章中,我將使用Arduino制作一個簡單的純正弦波逆變器,并解釋電路的工作原理。
什么是 SPWM(正弦脈沖寬度調制)?
顧名思義,SPWM代表S正弦脈沖寬度調制。_ 您可能已經知道,PWM 信號是一種信號,我們可以在其中改變脈沖的頻率以及開啟時間和關閉時間,也稱為占空比。如果您想了解有關 PWM的更多信息,可以在此處閱讀。因此,通過改變占空比,我們改變了脈沖的平均電壓。下圖顯示——
如果我們考慮一個在 0-5V 之間切換且占空比為 100%的PWM 信號,我們將獲得 5V 的平均輸出電壓,同樣如果我們考慮占空比為 50% 的相同信號,我們將得到2.5V 的輸出電壓,對于 25% 的占空比,它是那個的一半。總結了PWM信號的基本原理,接下來我們就可以了解SPWM信號的基本原理了。
正弦電壓主要是一種模擬電壓,它會隨著時間的推移改變其幅度,我們可以通過不斷改變 PWM 波的占空比來重現正弦波的這種行為,下圖顯示了這一點。
如果您查看下面的示意圖,它將看到在變壓器的輸出端連接了一個電容器。該電容器負責從載波頻率中平滑交流信號。
利用的輸入信號將根據輸入信號 和負載對電容器進行充電和放電。由于我們使用了一個非常高頻的SPWM信號,它會有一個非常小的占空比,大概是1%,這個1%的占空比會給電容充電一點,下一個占空比是5%,這會再次充電電容器再多一點,接下來的脈沖將有 10% 的占空比,電容器將再充電一點,我們將施加信號,直到我們達到100% 的占空比,然后從那里返回到 1%。這將在輸出端創(chuàng)建一個非常平滑的曲線,如正弦波。 因此,通過在輸入端提供適當的占空比值,我們將在輸出端獲得非常正弦的波形。
SPWM 逆變器的工作原理
上圖顯示了 SPWM 逆變器的主要驅動部分,如您所見,我們使用了兩個半橋配置的N 溝道 MOSFET來驅動該電路的變壓器,以減少不必要的開關噪聲并保護 MOSFET ,我們使用了與 MOSFET 并聯的 1N5819 二極管。為了減少柵極部分產生的任何有害尖峰,我們使用了與 1N4148 二極管并聯的 4.7 歐姆電阻。最后,BD139 和 BD 140 晶體管配置為推挽式配置 驅動 MOSFET 的柵極,因為該 MOSFET 具有非常高的柵極電容,并且基極需要至少 10V 才能正常開啟。在此處了解有關推挽式放大器工作原理的更多信息。
為了更好地理解電路的工作原理,我們將其縮小到 MOSFET 的這一部分為 ON 的程度。當MOSFET導通電流時,先流過變壓器,然后被MOSFET接地,這樣在電流流動的方向上也會感應出磁通量,變壓器的鐵芯會通過磁通量在次級繞組中,我們將在輸出端獲得正弦信號的正半周期。
在下一個循環(huán)中,電路的底部在電路的頂部,這就是我移除頂部的原因,現在電流以相反的方向流動并在該方向產生磁通量,從而反轉磁芯中磁通量的方向。在此處了解有關MOSFET工作原理的更多信息。
現在,我們都知道變壓器是靠磁通量變化來工作的。因此,打開和關閉 MOSFET,一個倒置到另一個并在一秒鐘內執(zhí)行 50 次,將在變壓器鐵芯內產生良好的振蕩磁通量,而變化的磁通量將在次級線圈中感應出電壓,如我們知道法拉第定律。這就是基本逆變器的工作原理。
該項目中使用的完整SPWM 逆變器電路如下所示。
構建 SPWM 逆變器所需的組件
SPWM逆變器電路結構
對于這個演示,電路是在 Veroboard 上構建的,借助原理圖,在變壓器的輸出端,會有大量的電流流過連接,因此連接跳線需要盡可能厚。
SPWM逆變器的Arduino程序
在我們開始理解代碼之前,讓我們先弄清楚基礎知識。通過以上工作原理,您已經了解了PWM 信號在輸出端的樣子,現在的問題是我們如何在 Arduino 的輸出引腳上產生如此變化的波形。
為了產生變化的 PWM 信號,我們將使用16 位定時器 1 ,預分頻器設置為 1,如果我們考慮正弦波的單個半周期,這將為每個計數提供 1600/16000000 = 0.1ms 時間,在波的半個周期內恰好適合 100 次。簡單來說,我們將能夠對正弦波進行 200 次采樣。
接下來,我們必須將我們的正弦波分成 200 段,并根據幅度的相關性計算它們的值。接下來,我們必須將這些值與計數器限制相乘,將其轉換為定時器計數器值。最后,我們必須將這些值放入查找表中以將其提供給計數器,我們將獲得正弦波。
為了讓事情更簡單一點,我使用了一個來自GitHub的非常好的 SPWM 代碼,它是由Kurt Hutten編寫的。
代碼很簡單,我們通過添加所需的頭文件開始我們的程序
?
#include#include
?
接下來,我們有兩個查找表,我們將從中獲取計時器計數器值。
?
int lookUp1[] = {50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,981 ,1020 , 1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264 ,1294 ,1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,1536 ,1550 ,1561 ,1572 ,1580 ,1587 ,1593 , 1597 ,1599 ,1600 ,1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,1264 ,1233 , 1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,446 ,398 ,349 ,300 ,5,250 ,201 , 100 ,50 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0}; int lookUp2[] = {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,981 ,1020 , 1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264 ,1294 ,1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,1536 ,1550 ,1561 ,1572 ,1580 ,1587 ,1593 , 1597 ,1599 ,1600 ,1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,1264 ,1233 , 1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,446 ,398 ,349 ,300 ,5,250 ,201 ,100 ,50 ,0};
?
接下來,在設置部分,我們初始化定時器計數器控制寄存器以清除每個寄存器。如需更多信息,您需要查看 atmega328 IC 的數據表。
?
TCCR1A = 0b10100010; /*10 匹配時清除,為 compA 設置為 BOTTOM。 10 在比賽中清除,在底部設置為 compB。 00 10 WGM1 1:0 用于波形 15。 */ TCCR1B = 0b00011001; /*000 11 WGM1 3:2 用于波形 15。 001 計數器上沒有預分頻器。 */ TIMSK1 = 0b00000001; /*0000000 1 TOV1 標志中斷使能。 */
?
之后,我們使用預定義的值 16000 初始化輸入捕獲寄存器,因為這將幫助我們準確生成 200 個樣本。
?
ICR1 = 1600;// 16MHz 晶體的周期,對于每 50Hz 正弦波周期 200 次細分的 100KHz 開關頻率。
?
接下來,我們通過調用函數來啟用全局中斷,
?
sei();
?
最后,我們將 Arduino 引腳 9 和 10 設置為輸出
?
DDRB = 0b00000110;// 將 PB1 和 PB2 設置為輸出。
?
這標志著 setup 函數的結束。
代碼的循環(huán)部分保持空白,因為它是一個定時器計數器中斷驅動程序。
?
無效循環(huán)(){;/*沒做什么 。. . . 永遠!*/}
?
接下來,我們定義了 timer1 溢出向量,一旦 timer1 溢出并產生中斷,這個中斷函數就會被調用。
?
ISR(TIMER1_OVF_vect){
?
接下來,我們將一些局部變量聲明為靜態(tài)變量,并開始將這些值提供給捕獲和比較電阻器。
?
靜態(tài)整數; 靜態(tài)字符觸發(fā); // 每個周期改變占空比。 OCR1A = 查找1[編號]; OCR1B = 查找2[編號];
?
最后,我們預先增加計數器以將下一個值提供給捕獲和比較電阻器,這標志著這段代碼的結束。
?
if(++num >= 200){ // 預先增加 num 然后檢查它是否低于 200。 數 = 0; // 重置號碼 觸發(fā)=觸發(fā)^0b00000001; 數字寫入(13,觸發(fā)); }
?
測試 TL494 PWM 逆變器電路
為了測試電路,使用以下設置。
12V鉛酸電池。
具有 6-0-6 抽頭和 12-0-12 抽頭的變壓器
100W白熾燈泡作為負載
Meco 108B+TRMS 萬用表
Meco 450B+TRMS 萬用表
來自 Arduino 的輸出信號:
一旦我上傳了代碼。我測量了Arduino兩個引腳的輸出 SPWM 信號,如下圖所示,
如果我們稍微放大一點,我們可以看到 PWM 波不斷變化的占空比。
接下來,下圖顯示了變壓器的輸出信號。
理想狀態(tài)下的 SPWM 逆變器電路:
從上圖中可以看出,該電路在理想運行時消耗約 13W
無負載輸出電壓:
逆變器電路的輸出電壓如上圖所示,這是在沒有任何負載的情況下輸出的電壓。
輸入功耗:
上圖顯示了連接 40W 負載時 ic 消耗的輸入功率。
輸出功耗:
上圖顯示了該電路消耗的輸出功率,(負載為 40W 白熾燈泡)
?
/*
* sPWMv2.c
*
* 創(chuàng)建時間:2014 年 12 月 31 日下午 3:44:43
* 作者:庫爾特·赫頓
arduino Uno 的 atMega328 上的 SPWM,可能與其他 atmel 芯片/arduino 板兼容。
比較輸出 A 和 B 輸出到 PORTB 引腳 1 和 2,它們分別是 Uno 上的引腳 9 和 10。
了解 Uno 上的 LED 也很有用,它是 PORTB 上的引腳 5。
*/
#include
#include
// 查找每個有 200 個條目的表,標準化為最大值 1600,這是加載到寄存器 ICR1 的 PWM 周期。
int lookUp1[] = {50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,981 ,1020 , 1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264 ,1294 ,1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,1536 ,1550 ,1561 ,1572 ,1580 ,1587 ,1593 , 1597 ,1599 ,1600 ,1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,1264 ,1233 , 1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,446 ,398 ,349 ,300 ,5,250 ,201 , 100 ,50 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0};
int lookUp2[] = {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 0 ,0 ,0 ,50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,981 ,1020 , 1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264 ,1294 ,1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,1536 ,1550 ,1561 ,1572 ,1580 ,1587 ,1593 , 1597 ,1599 ,1600 ,1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,1264 ,1233 , 1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,446 ,398 ,349 ,300 ,5,250 ,201 ,100 ,50 ,0};
無效設置(){
// 寄存器初始化,更多細節(jié)參見數據表。
TCCR1A = 0b10100010;
/*10 匹配時清除,為 compA 設置為 BOTTOM。
10 在比賽中清除,在底部設置為 compB。
00
10 WGM1 1:0 用于波形 15。
*/
TCCR1B = 0b00011001;
/*000
11 WGM1 3:2 用于波形 15。
001 計數器上沒有預分頻器。
*/
TIMSK1 = 0b00000001;
/*0000000
1 TOV1 標志中斷使能。
*/
ICR1 = 1600;// 16MHz 晶體的周期,對于每 50Hz 正弦波周期 200 次細分的 100KHz 開關頻率。
sei(); // 啟用全局中斷。
DDRB = 0b00000110;// 將 PB1 和 PB2 設置為輸出。
pinMode(13,輸出);
}
無效循環(huán)(){;/*沒做什么 。. . . 永遠!*/}
ISR(TIMER1_OVF_vect){
靜態(tài)整數;
靜態(tài)字符觸發(fā);
// 每個周期改變占空比。
OCR1A = 查找1[編號];
OCR1B = 查找2[編號];
if(++num >= 200){ // 預先增加 num 然后檢查它是否低于 200。
數 = 0; // 重置號碼
觸發(fā)=觸發(fā)^0b00000001;
數字寫入(13,觸發(fā));
}
}
?
評論