摘要 为实现电池储能装置的双向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)
|