摘要 為實現電池儲能裝置的雙向DC-DC變換器,本系統以buck-boost拓撲電路為核心,通過DSPICFJ256GP710單片機最小系統控制拓撲的切換,從而進行buck恒流充電和boost恒壓放電。充電時效率≥94%,放電時效率≥95.5%,具有過壓保護及溫度檢測等功能。本系統具有效率高、控制簡單、穩定性強等優點,滿足設計要求。 目錄 一、 方案論證與選取 1.1方案的論證 1.2方案的選取 1.3整體設計 2.1總體設計框圖 二、 理論分析與參數計算 2.1 開關場效應管的選擇 2.2肖特基二極管的選擇 2.3電感參數計算 2.4電容的參數計算 三、 電路與程序設計 3.1硬件部分設計 3.1.1buck-boost主電路模塊 3.1.2 boost驅動電路 3.1.3 buck驅動電路 3.1.4 電流采集模塊 3.2軟件部分設計 3.2.1軟件濾波算法 3.2.2軟件流程圖 四、 測試方案與測試結果 4.1測試儀器(見附件1) 4.2測試步驟及數據 4.2.1充電模式 4.2.2 放電模式 4.3 自由模式 五、 參考文獻 六、 附件 6.1附件一 測試儀器 6.2附件二 作品照片 1.1方案的論證 方案一:正反激組合式雙向DC-DC變換器。它采用正激和反激組合的形式,在變換器的一側繞組串聯,另一側并聯。這種結構的雙向變換拓撲解決了電流型一電壓型組合式拓撲的開關管電壓尖峰問題和啟動問題。 方案二:純硬件buck-boost雙向DC-DC變換器。該方案結構簡單,電源的實時性調整性比較強。但是不能實現升降壓的自動轉換,不能輕易實現人機交互,采集顯示電路需要外加MCU。 方案三:buck-boost雙向DC-DC變換器。用單片機進行控制,以buck恒流給電池充電,boost恒壓對電池進行放電。 1.2方案的選取 方案一的電路過于復雜,且該變換器主要適合大功率電路,對于中小功率的電路來說電路損耗過大,且電路需用到變壓器和大型散熱片,使得整個系統的質量過重,不符合題目要求,所以舍棄。方案二雖然電路簡單,但是不能實現升降壓的自動轉換。方案三利用單片機控制電路的工作模式,使得效率得到提高,符合題目的要求,因此選擇此方案。 1.3整體設計
2.1總體設計框圖 本系統由buck-boost拓撲電路組成,通過單片機的鍵盤控制主電路的工作模式,當選中buck模式時,單片機通過控制輸出PWM的占空比進行電流調節,從而達到恒流充電;當選中boost模式時,單片機通過控制輸出PWM的占空比進行電流調節,從而達到恒壓放電。 2.1 開關場效應管的選擇 選擇導通電阻小的IRF540作為開關管,其導通電阻僅為77mΩ(VGS=10V, ID=17A)。IRF540擊穿電壓VDSS為55V ,漏極電流最大值為28A(VGS =10 V, 25°C),允許最大管耗PCM可達50W,完全滿足電路要求。 2.2肖特基二極管的選擇 選擇STC20100肖特基二極管,其導通壓降小,通過1 A電流時僅為0.35V,并且恢復時間短。實際使用時為降低導通壓降將兩個肖特基二極管并聯。 2.3電感參數計算 BUCK模式:電感選擇應保證在最小電流輸出時,電感電流也保持連續。直流電流等于電感電流斜坡峰-峰值dI一半時對應臨界連續。Iomin=0.2Ion。又dI=VL*Ton/L,VL近似等于(Vdc-Vo),額定電流Ion=10* Iomin,Ton=Vo/Vdc得:Lp1=5(Vdc-Vo)VoT /Vdc*Ion。取開關頻率為30KHz,算得L=400μH。 BOOST模式:根據設計要求可知占空比D=0.4,故Ton=D*T=13.32us,Lp2=Vdc*Ton/Ip=478μH。 綜上,電感取兩種模式平均值L=439μH,實際繞制的電感值為436μH。選用鉑科公司的NPS130060磁環,AL=61nH/N^2,根據L=AL*N^2得出N=85匝。根據1mm^2走3~5A 電流取0.8mm線徑。 2.4電容的參數計算 濾波電容的選擇必須滿足輸出紋波的要求。本系統的電容可等效為電阻Ro和電感Lo與其的串聯(如圖4-2-1)。一般情況下,工作頻率在300kHz以下是可以忽略Lo(等效串聯電感ESL)。 2.2.4電容等效電路 取紋波電壓峰峰值為0.06V,RoCo≈50~80*〖10〗^(-6)ΩF,取平均值65*〖10〗^(-6)ΩF。求得Co=433μF,實際取470μF。 3.1硬件部分設計 3.1.1buck-boost主電路模塊 為了滿足電池儲能裝置的雙向DC-DC變換器,實現電池的充放電功能,主電路采用buck-boost拓撲電路,通過buck恒流對電池充電,boost恒壓對電池放電。當工作在充電狀態下,此時Q2導通,Q3截止,電流流過電感對電池進行充電。當工作在放電狀態下,此時Q3導通,Q2截止,電池進行放電。如圖3.1.1所示。 3.1.1 buck-boost主電路 3.1.2 boost驅動電路 由霍爾采集電流供給單片機,單片機經過處理后輸出PWM,為增加驅動能力,采用推挽結構輸出PWM控制主電路mos管的占空比。如圖3.1.2所示。 3.1.2 boost驅動電路
3.1.3 buck驅動電路 當單片機輸入PWM時,經過大功率光耦T1隔離驅動MOS管。如圖3.1.3所示。 3.1.3 buck驅動電路 3.1.4 電流采集模塊 系統采用霍爾傳感器對電路的電流進行采集,經過電流電壓轉換,由電阻分壓后送入單片機進行A/D轉換。如圖3.1.4所示。
3.1.4 電流采集電路
3.2軟件部分設計 3.2.1軟件濾波算法 連續取N個采樣值進行算術平均運算 N值較大時:信號平滑度較高,但靈敏度較低 N值較小時:信號平滑度較低,但靈敏度較高 N值的選取:一般流量,N=12;壓力:N=4;此算法適用于對一般具有隨機干擾的信號進行濾波 這樣信號的特點是有一個平均值,信號在某一數值范圍附近上下波動。 3.2.2軟件流程圖
3.2.2 軟件流程圖 4.1測試儀器(見附件1) 4.2測試步驟及數據 4.2.1充電模式 - 條件:U2=30V,實現電池恒流充電。要求:I1在1~2A范圍可調,步進值不大于0.1A,電流控制精度不低于5%。
表1 I1步進值精度測量 - 條件:I1=2A,調整直流穩壓電源輸出電壓。要求:U2在24~36V范圍變化時,充電電流I1的變化率不大于1%。
表2 充電電流I1的電壓調整率 - 條件:I1=2A,U2=30V。要求:變換器的效率η≥90%。
表3 變換器效率 - 條件:單片機顯示充電電流I1。要求:I1=1~2A范圍內測量精度不低于2%。
表4 電流I1測量精度 (5)過充保護:I1=2A時,當U1超過閾值電壓后,停止充電。 4.2.2 放電模式 - 條件:斷開S1,接通S2,將裝置設定為放電模式,保持U2=30±0.5V。要求:變換器效率η≥95%。
表5 boost恒壓放電效率 4.3 自由模式 當接通S1、S2,斷開S3,調整直流穩壓電源輸出電壓,使Us在32~38范圍內變化時,雙向buck-boost拓撲電路能夠自動轉換工作模式并保持U2=30±0.5V。 [1] (美)馬尼克塔拉著,王志強等譯,精通開關電源設計,北京:人民郵電 出版社[2] 長谷川彰,開關式穩壓器的設計技術(第一版),北京科學出版社,1989 [3] 顧亦磊,陳世杰,呂征宇,Boost電路的一種實現方法,電源技術應用,2004 [4] 李愛文,張承惠,現代逆變技術及應用,北京科學出版社,2000 [5] 華成英,童詩白,模擬電子技術基礎(第四版),高等教育出版社,2006 6.1附件一 測試儀器 | | | | | | | 直流電壓:200mV/2V/20V/200 V /1000V——±(0.05%+3) 直流電流:200uA/2mA/20mA/ 200mA/20A——±(0.5%+4) 交流電壓:200mV/2V/20V/200 V/750V——±(0.8%+25) 交流電流:200mA/20A—— ±(1.5%+25) | |
| | | | |
| | Lecroy waveRunner 104mxi數字示波器 | | | | | | | | | | | | | | | | | | | | | | |
| | |
| | |
6.2附件二 作品照片    
DSPICFJ256GP710單片機源程序如下:
- #include "p33FJ256GP710.h"
- #include<math.h>
- #include "Delay.h"
- #include "InitCPU.h"
- #include "LCD12864.h"
- #include "ADC.h"
- #include "KEY.h"
- #include "PWM.h"
- #include "DS18B20.h"
- #define uint unsigned int
- #define uchar unsigned char
- #define ulint unsigned long int
- #define KeyPort PORTE
- /*********變量定義***********/
- unsigned char KEY_Receive =0; //按鍵掃描結果存儲
- unsigned int cls=0; //清屏指示
- unsigned char switchover =0; //換屏
- unsigned int Duty_one =0,Duty_two=0; //占空比寄存器
- unsigned int I_Set_One =15000; //1模塊和2模塊設定電流值(調光)
- unsigned int count =0,start=0,start1=0; //
- unsigned char test =0; //按鍵加減寄存器(test =1加;test=2減)
- unsigned char BUCK=0,BOOST=0; //采集100次標志位
- /********************狀態標志位************************/
- unsigned char Menu =1; //主菜單標志位
- unsigned char Menu_A =0; //一級菜單A(狀態A)
- unsigned char Menu_B =0;
- unsigned char Menu_C =0; //一級菜單B(狀態B)
- unsigned char Cursor =1; //光標狀態標志位
- unsigned char stateA =0; //A狀態標志位(區分正常模式還是過流保護)
- unsigned char stateB =0; //B狀態標志位
- unsigned char stateC =0;
- float RE_Ui=0,RE_Uo=0,RE_Ii=0,RE_Io=0;
- float RE_Ui_all=0,RE_Uo_all=0,RE_Ii_all=0,RE_Io_all=0;
- float Ui_ave=0,Uo_ave=0,Ii_ave=0,Io_ave=0;
- float Ui=0,Uo=0,Ii=0,Io=0;
- float GETTEMP;
- float POWER_factor=0;
- unsigned char KeyScan();
- void main()
- {/*****初始化*****/
- InitCPU();
- InitLCD();
- Init_ADC();
- Init_PWM();
- Init_DS18B20();
- _TRISF2=0;//蜂鳴器輸出
- _TRISD1=0;
- _TRISD2=0;
- Clear_lcd();
- DelayMs(10);
- DISPLAY_stri(0 ,0 , "模式選擇: ");
- DISPLAY_stri(0,1,"->1.充電模塊");
- DISPLAY_stri(0,2," 2.放電模塊");
- DISPLAY_stri(0,3," 3.自動模塊");
- writ_com(0x0F);
- writ_com(0x90);
- while(1)
- {
- KEY_Receive=KeyScan();
- switch ( KEY_Receive )
- {
- case 1: //光標向下移動(+)
- {
- test =1; //按鍵寄存器,加
- if(Menu==1)
- { test=0;
- Cursor ++;
- Cursor=Cursor>=4?1:Cursor;
- if( Cursor ==1 )
- {
- DISPLAY_stri(0 ,1 , "->1.充電模塊");
- DISPLAY_stri(0 ,2 , " 2.放電模塊");
- DISPLAY_stri(0 ,3 , " 3.自動模塊");
- writ_com(0x90); //光標顯示在第一行
- }
- if( Cursor ==2 )
- {DISPLAY_stri(0 ,1 , " 1.充電模塊");
- DISPLAY_stri(0 ,2 , "->2.放電模塊");
- DISPLAY_stri(0 ,3 , " 3.自動模塊");
- writ_com(0x88); //光標顯示在第二行
- }
- if( Cursor ==3 )
- {DISPLAY_stri(0 ,1 , " 1.充電模塊");
- DISPLAY_stri(0 ,2 , " 2.放電模塊");
- DISPLAY_stri(0 ,3 , "->3.自動模塊");
- writ_com(0x98);//光標顯示在第二行
- }
- }
- break;
- }
- case 2:
- {
- //菜單光標,顯示2行
- test =2; //按鍵寄存器,減
- if( Menu ==1)
- { test=0;
- Cursor --;
- Cursor=Cursor==0?3:Cursor;
- if( Cursor ==1 )
- {
- DISPLAY_stri(0 ,1 , "->1.充電模塊");
- DISPLAY_stri(0 ,2 , " 2.放電模塊");
- DISPLAY_stri(0 ,3 , " 3.自動模塊");
- writ_com(0x90); //光標顯示在第一行
- }
- if( Cursor ==2 )
- {
- DISPLAY_stri(0 ,1 , " 1.充電模塊");
- DISPLAY_stri(0 ,2 , "->2.放電模塊");
- DISPLAY_stri(0 ,3 , " 3.自動模塊");
- writ_com(0x88); //光標顯示在第二行
- }
- if( Cursor ==3 )
- { DISPLAY_stri(0 ,1 , " 1.充電模塊");
- DISPLAY_stri(0 ,2 , " 2.放電模塊");
- DISPLAY_stri(0 ,3 , "->3.自動模塊");
- writ_com(0x98); //光標顯示在第二行////////////////
- }
- }
- break;
- }
- case 3: //(確定鍵,進入子狀態(執行狀態)
- {
- switchover =~switchover;
- cls=1;
- if( ( Menu * Cursor ) ==1 ) //BUCK模式
- {
- _TRISD1=0;
- _TRISD2=0;
- Menu_A =1;
- Menu_B =0;
- Menu_C =0;
- Menu =0;
- stateA=1;
- stateB=0;
- stateC=0;
- OC3CONbits.OCM=0B110;
- OC2CONbits.OCM=0B110;
- Duty_one=10; //PWM設置one進行BUCK——PWM調整,two關斷
- Duty_two=0;
- T2CONbits.TON=1;
- writ_com(0x0C); //關閉游標和游標位置
- Clear_lcd();
- }
- if( ( Menu * Cursor ) ==2 )//BOOST模式
- {
- _TRISD2=0;
- _TRISD1=0;
- Menu_A =0;
- Menu_B =1;
- Menu_C =0;
- Menu =0;
-
- stateA=0;
- stateB=1;
- stateC=0;
- OC3CONbits.OCM=0B110;
- OC2CONbits.OCM=0B110;
- Duty_one=0; ////PWM設置two進行BUCK——PWM調整,one關斷
- Duty_two=10;
- T2CONbits.TON=1;
- writ_com(0x0C); //關閉游標和游標位置
- Clear_lcd();
- }
- if( ( Menu * Cursor ) ==3 )//自動模式
- {
- _TRISD2=0;
- _TRISD1=0;
- Menu_A =0;
- Menu_B =0;
- Menu_C =1;
- Menu =0;
- stateA=0;
- stateB=0;
- stateC=1;
- OC3CONbits.OCM=0B000;
- OC2CONbits.OCM=0B000;
- BUCK=0;
- BOOST=0;
- Duty_one=0; //PWM設置,剛開始用BUCK
- Duty_two=0;
- T2CONbits.TON=0;
- writ_com(0x0C); //關閉游標和游標位置
- Clear_lcd();
- }
- break;
- }
- case 4:
- {
- if( Menu_A ==1 )
- {
- Menu_A =0;
- Menu_B =0;
- Menu_C =0;
- Menu =1;
- Cursor =1;
- stateA=0;
- stateB=0;
- stateC=0;
- start=0;
- OC3RS=0;
- OC2RS=0;
- OC3CONbits.OCM=0B000;
- OC2CONbits.OCM=0B000;
- _LATD2=0;
- _LATD1=0;
- _LATF2=0;
- T2CONbits.TON=0;
- I_Set_One=15000;
- Clear_lcd();
- DelayMs(10);
- DISPLAY_stri(0 ,0 , "模式選擇: ");
- DISPLAY_stri(0 ,1 , "->1.充電模塊");
- DISPLAY_stri(0 ,2 , " 2.放電模塊");
- DISPLAY_stri(0 ,3 , " 3.自動模塊");
- writ_com(0x90);
- writ_com(0x0F);
- }
- if( Menu_B ==1 )
- {
- Menu_A =0;
- Menu_B =0;
- Menu_C =0;
- Menu =1;
- Cursor =1;
- stateA=0;
- stateB=0;
- stateC=0;
- OC3RS=0;
- OC2RS=0;
- start1=0;
- OC3CONbits.OCM=0B000;
- OC2CONbits.OCM=0B000;
- _LATD2=0;
- _LATD1=0;
- T2CONbits.TON=0;
- Clear_lcd();
- DelayMs(10);
- DISPLAY_stri(0 ,0 , "模式選擇: ");
- DISPLAY_stri(0 ,1 , "->1.充電模塊");
- DISPLAY_stri(0 ,2 , " 2.放電模塊");
- DISPLAY_stri(0 ,3 , " 3.自動模塊");
- writ_com(0x90);
- writ_com(0x0F);
- }
- if( Menu_C ==1 )
- {
- Menu_A =0;
- Menu_B =0;
- Menu_C =0;
- Menu=1;
- Cursor=1;
- stateA=0;
- stateB=0;
- stateC=0;
- OC3RS=0;
- OC2RS=0;
- _LATD2=0;
- _LATD1=0;
- OC3CONbits.OCM=0B000;
- OC2CONbits.OCM=0B000;
- T2CONbits.TON=0;
- Clear_lcd();
- DelayMs(10);
- DISPLAY_stri(0 ,0 , "模式選擇: ");
- DISPLAY_stri(0 ,1 , "->1.充電模塊");
- DISPLAY_stri(0 ,2 , " 2.放電模塊");
- DISPLAY_stri(0 ,3 , " 3.自動模塊");
- writ_com(0x90);
- writ_com(0x0F);
- }
- break;
- }
- default :break;
- }
- switch (stateA)//充電模式
- {
- case 1: //采集電壓電流
- RE_Ui=filter(0);
- RE_Ii=filter(1);
- RE_Uo=filter(2);
- RE_Io=filter(3);
- Ui=(RE_Ui/1.023)*38.74;
- Ii=((RE_Ii/1023)*2980-2082)*10000/418;
- Uo=(RE_Uo/1.023)*25.33;
- Io=((RE_Io/1023)*2980-2063)*10000/417;
-
- // POWER_factor=Ui
- start++;
-
- I_Set_One=test==1?I_Set_One+1000:I_Set_One;
- I_Set_One=test==2?I_Set_One-1000:I_Set_One;
- I_Set_One=I_Set_One>20000?10000:I_Set_One;
- I_Set_One=I_Set_One<10000?20000:I_Set_One;
- test=0;
- if(Io>=I_Set_One)
- {
- Duty_one=Duty_one<=10?700:Duty_one-1;
- }
- else
- {
- Duty_one=Duty_one>=1300?700:Duty_one+1;
- }
-
- if(Uo>=24000) //過壓保護
- {
- DelayMs(2000);
- if(Uo>=24000)
- {
- _LATF2=1;
- T2CONbits.TON=0;
- OC3CONbits.OCM=0B000;
- OC2CONbits.OCM=0B000;
- _LATD2=0;
- _LATD1=0;
- }
- }
- if(switchover) //翻頁顯示
- {
- if(cls==1)
- {
- Clear_lcd();
- DelayMs(10);
- }
- cls=0;
- DISPLAY_stri(0,0,"輸入Ui:");
- DISPLAY_stri(4,0,ADC_deal_U(Ui));
- DISPLAY_stri(0,1,"輸入Ii:");
- DISPLAY_stri(4,1,ADC_deal_I_1(Ii));
- DISPLAY_stri(0,2,"輸出Uo:");
- DISPLAY_stri(4,2,ADC_deal_U(Uo));
- DISPLAY_stri(0,3,"輸出Io:");
- if(start==50)
- {start=0;
- GETTEMP=GETTEMP_DS18B20();
- DISPLAY_stri(4,3,ADC_deal_I_1(Io));
- }
- }
- if(!switchover)
- {
- if(cls==1)
- {
- Clear_lcd();
- DelayMs(10);
- }
- cls=0;
- DISPLAY_stri(0,1,"I_set : ");
- DISPLAY_stri(4,1,ADC_deal_I_1(I_Set_One));
- DISPLAY_stri(0,0,"T: ");
- DISPLAY_stri(4,0,ADC_deal_U(GETTEMP*100));
- DISPLAY_stri(0,2,"I_fact:");
- if(start==50)
- {
- start=0;
- GETTEMP=GETTEMP_DS18B20();
- DISPLAY_stri(4,2,ADC_deal_I_1(Io));
- }
- }
- stateA=1;
- break;
- default :break;
- }
- switch (stateB)//放電模式
- {
- case 1: //采集電壓電流
- RE_Ui=filter(0);
- RE_Ii=filter(1);
- RE_Uo=filter(2);
- RE_Io=filter(3);
- Ui=(RE_Ui/1.023)*38.74;
- Ii=(2082-(RE_Ii/1023)*2980)*10000/418;
- Uo=(RE_Uo/1.023)*25.33;
- Io=(2079-(RE_Io/1023)*2980)*10000/417;
- // GETTEMP=GETTEMP_DS18B20();
- if(Ui>=30000) //恒壓
- {
- Duty_two=Duty_two<10?700:Duty_two-1;
- }
- else
- {
- Duty_two=Duty_two>1300?700:Duty_two+1;
- }
- start1++;
- DISPLAY_stri(0,0,"輸入Ui:");
- if(start1==50)
- {
- start1=0;
- DISPLAY_stri(4,0,ADC_deal_U(Ui));
- }
- DISPLAY_stri(0,1,"輸入Ii:");
- DISPLAY_stri(4,1,ADC_deal_I_1(Ii));
- DISPLAY_stri(0,2,"輸出Uo:");
- DISPLAY_stri(4,2,ADC_deal_U(Uo));
- DISPLAY_stri(0,3,"輸出Io:");
- DISPLAY_stri(4,3,ADC_deal_I_1(Io));
- stateB=1;
- break;
- default :break;
- }
-
- switch (stateC)//自動模式
- {
- case 1:
- RE_Ui=filter(0);
- RE_Uo=filter(2);
- Ui=(RE_Ui/1.023)*38.74;
- Uo=(RE_Uo/1.023)*25.33;
-
- if((Ui>30300)&(BUCK!=1)) //BUCK模式 大于30.3 選定BUCK狀態
- {
- BUCK=1;
- BOOST=0;
- OC3CONbits.OCM=0B110; //BUCK開
- OC2CONbits.OCM=0B000; //BOOST關
- Duty_one=10;
- T2CONbits.TON=1;
- }
- if((Ui<29700)&(BOOST!=1)) //BOOST模式 小于29.7 選定BOOST狀態
- {
- BUCK=0;
- BOOST=1;
- OC3CONbits.OCM=0B000; //BUCK關
- OC2CONbits.OCM=0B110; //BOOST開
- Duty_two=10;
- T2CONbits.TON=1;
- }
- if(BUCK==1)
- {
- if(Ui>=30000) //恒壓
- {
- Duty_one=Duty_one>1300?10:Duty_one+1;
- }
- else
- {
- Duty_one--;
- if(Duty_one==4)
- {
- //Duty_one=0;
- //Duty_two=6;
- T2CONbits.TON=0;
- OC3CONbits.OCM=0B000; //BUCK關
- OC2CONbits.OCM=0B110; //BOOST開
- Duty_one=0;
- Duty_two=6;
- T2CONbits.TON=1;
- BOOST=1;
- BUCK=0;
- }
- }
- }
- if(BOOST==1)
- {
- if(Ui>=30000) //恒壓
- {
- Duty_two--;
- if(Duty_two==4)
- {
- T2CONbits.TON=0;
- Duty_two=0;
- Duty_one=6;
- OC3CONbits.OCM=0B110; //BUCK開
- OC2CONbits.OCM=0B000; //BOOST關
- T2CONbits.TON=1;
- BOOST=0;
- BUCK=1;
- }
-
- }
- else
- {
- Duty_two=Duty_two>1300?10:Duty_two+1;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
所有資料51hei提供下載(含完整的Word格式設計論文):
DCDC電源方案.rar
(7.51 MB, 下載次數: 495)
2018-9-3 20:54 上傳
點擊文件名下載附件
電源資料
|