基于PIC16F877A控制boostbuckDCDC变换器.docx
《基于PIC16F877A控制boostbuckDCDC变换器.docx》由会员分享,可在线阅读,更多相关《基于PIC16F877A控制boostbuckDCDC变换器.docx(19页珍藏版)》请在冰豆网上搜索。
![基于PIC16F877A控制boostbuckDCDC变换器.docx](https://file1.bdocx.com/fileroot1/2023-2/2/7614d2d0-5998-4803-a3a4-511b90389869/7614d2d0-5998-4803-a3a4-511b903898691.gif)
基于PIC16F877A控制boostbuckDCDC变换器
输出电压可设置的升降压DC-DC变换器
如下图,设计一个DC-DC变换电路:
要求:
1)当输入电压Ui在14V~16V变化时,输出电压Uo恒压输出,Uo稳态相对误差不超过2%,Uo可通过键盘设置为10~20V间的任意电压,电压步进长度0.1V;
2)要求用液晶屏显示输出电压和输出电流,电压显示精度到0.1V,电流显示精度到50mA;要求带4*4键盘,键盘定义如下:
1
2
3
del
4
5
6
自定义
7
8
9
自定义
小数点
0
自定义
ok
3)输出负载电流I2范围0~1A;
4)试计算电源效率。
<一>电路部分:
设计原理:
主电路boost-buck电路,驱动电路,控制电路(pic单片机控制)。
原理概述:
boost-buck电路利用开关管的开关,输出电压的平均值Uo=ton/(T-ton)×Ui=D/(1-D)*ui。
D为占空比。
用单片机输出PWM方波(经过驱动电路放大后)控制MOS管的开关,来调节输出电压。
将输出电压送回PIC单片机模数转换模块,通过反馈调节PWM占空比调节电压,使输出稳定。
利用差分运放电路,检测出输出电压与输出电流的关系。
键盘输入设置电压。
外接液晶屏显示输出电压和输出电流和输出电流。
主电路:
驱动电路:
控制电路:
液晶外围电路:
键盘电路模块:
用multisim仿真如下结果:
设计小结:
输出电流与输出电压的关系U=RI。
在程序设计中,通过电压的输出在液晶屏上显示电流的输出。
〈二〉程序部分:
输出pwm:
#include
unsignedintDRE;
__CONFIG(0x2001);
voidPWM()
{
PR2=39;//频率25KHz
TRISC|=0x04;//RC2置为输入
CCP1CON=0X0c;//PWM输出
CCPR1L=0X01;//占空比25%
T2CON=0X04;//开定时器TMR2,预分频1:
1
TMR2IF=0;//清除TMR2中断标志位
}
voidmain()
{
while
(1)
{
PWM();
DRE=40;//高电平寄存器的值
CCPR1L=DRE/4;//装入高8位
CCP1CON<5>=(DRE/2)%2;//装入次低位
CCP1CON<4>=DRE%2;//装入最低位
while(TMR2IF==0);
TRISC=0x00;
}
}
AD转换:
#include
__CONFIG(FOSC_XT&WDTE_OFF&LVP_OFF);
voidAD()
{
TRISA0=1;//RA1设置为模拟输入
ADCON1=0x00;//参考电压电源电压VDDAD转换周期Fosc/4
ADCON0=0x40;//
}
voiddelayms(intxms)
{
inti,j;
for(i=0;ifor(j=0;j<150;j++);
}
voidmain()
{
unsignedintx,y,z,A,B,C;
unsignedintResult,Result1,ADRES;
while
(1);
{delayms(5);//采样采样电压充电延时
GO=1;
}
while(GO==1);
{
}
Result=ADRES;
x=(Result*5)/256;//取个位十分位百分位
y=((Result*50)/256)%10;
z=((Result*500)/256)%10;
Result1=Result/1.2-1.5;
A=(Result*5)/256;//取个位十分位百分位
B=((Result*50)/256)%10;
C=((Result*500)/256)%10;
}
液晶屏与键盘:
#include
#defineLCD_ENRC7
#defineLCD_RWRC6
#defineLCD_RSRC5
unsignedintx,y,z,A,B,C;
unsignedchardis0[]="voltage:
";
unsignedchardis1[]={'0','1','2','3','4','5','6','7','8','9','.'};
unsignedchardis2[]="current:
";
unsignedchardis3[]={'0','1','2','3','4','5','6','7','8','9','.'};
unsignedchardis4[3],dis5[3];
__CONFIG(FOSC_XT&WDTE_OFF&LVP_OFF);
voiddelay(intxms)
{
inti,j;
for(i=0;i{
for(j=0;j<150;j++);
}
}
voidwrite_com()
{
unsignedcharcom;//声明写指令
LCD_RS=0;
LCD_RW=0;
LCD_EN=0;
PORTD=com;
delay(5);
LCD_EN=1;
delay(5);
LCD_EN=0;
}
voidwrite_date()
{
unsignedchardate;
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
PORTD=date;
delay(5);
LCD_EN=1;
delay(5);
LCD_EN=0;
}
voidinit()
{TRISD=0x00;
TRISC&=0x1f;
write_com(0x38);
delay(5);
write_com(0x0c);
delay(5);
write_com(0x06);
delay(5);
write_com(0x01);
delay(5);
}
voiddisplay()
{
unsignedcharj;
dis4[0]=dis1[x];
dis4[1]=dis1[10];
dis4[2]=dis1[y];
dis4[3]=dis1[z];
write_com(0xc8);
for(j=0;j<=3;j++)
{
write_date(dis5[j]);
delay
(1);
}
unsignedchark;
dis5[0]=dis3[A];
dis5[1]=dis3[10];
dis5[2]=dis3[B];
dis5[3]=dis3[C];
write_com(0xc8);
for(k=0;k<=3;k++)
{
write_date(dis4[k]);
delay
(1);
}
}
voidmain()
{
unsignedchari;
init();
write_com(0x80);//显示第1行
for(i=0;i<=8;i++)
{
write_date(dis0[i]);
delay
(1);
}
write_com(0x80+0x40);//显示第2行
for(i=0;i<=8;i++)
{
write_date(dis2[i]);
delay
(1);
}
}
#include
#include
#defineLCD_ENRC7
#defineLCD_RWRC6
#defineLCD_RSRC5
unsignedintx,y,z,A,B,C;
unsignedchardis0[]="voltage:
";
unsignedchardis1[]={'0','1','2','3','4','5','6','7','8','9','.'};
unsignedchardis2[]="current:
";
unsignedchardis3[]={'0','1','2','3','4','5','6','7','8','9','.'};
unsignedchardis4[3],dis5[3];
__CONFIG(FOSC_XT&WDTE_OFF&LVP_OFF);
voiddelay(intxms)
{
inti,j;
for(i=0;i{
for(j=0;j<150;j++);
}
}
voidwrite_com()
{
unsignedcharcom;//声明写指令
LCD_RS=0;
LCD_RW=0;
LCD_EN=0;
PORTD=com;
delay(5);
LCD_EN=1;
delay(5);
LCD_EN=0;
}
voidwrite_date()
{
unsignedchardate;
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
PORTD=date;
delay(5);
LCD_EN=1;
delay(5);
LCD_EN=0;
}
voidinit()
{TRISD=0x00;
TRISC&=0x1f;
write_com(0x38);
delay(5);
write_com(0x0c);
delay(5);
write_com(0x06);
delay(5);
write_com(0x01);
delay(5);
}
voiddisplay()
{
unsignedcharj;
dis4[0]=dis1[x];
dis4[1]=dis1[10];
dis4[2]=dis1[y];
dis4[3]=dis1[z];
write_com(0xc8);
for(j=0;j<=3;j++)
{
write_date(dis5[j]);
delay
(1);
}
unsignedchark;
dis5[0]=dis3[A];
dis5[1]=dis3[10];
dis5[2]=dis3[B];
dis5[3]=dis3[C];
write_com(0xc8);
for(k=0;k<=3;k++)
{
write_date(dis4[k]);
delay
(1);
}
}
voidmain()
{
unsignedchari;
init();
write_com(0x80);//显示第1行
for(i=0;i<=8;i++)
{
write_date(dis0[i]);
delay
(1);
}
write_com(0x80+0x40);//显示第2行
for(i=0;i<=8;i++)
{
write_date(dis2[i]);
delay
(1);
}
}#defineKEYBOARD_PORT_DIRTRISB//键盘扫描方向端口
#defineKEYBOARD_PORTPORTB//键盘扫描端口
#defineNO_KEY0xFF//无按键
__CONFIG(0x3FFF);
unsignedcharL,O;
charscankeypad();//获取4×4键盘值
chargetkeyvalue();//获取某按键的值
voiddelay(intxms)
{
inti,j;
for(i=0;ifor(j=0;j<150;j++);
}
constcharccode[16][2]=
{
{0xEE,1},{0xED,2},{0xEB,3},{0xE7,'L'},
{0xDE,4},{0xDD,5},{0xDB,6},{0xD7,'+'},
{0xBE,7},{0xBD,8},{0xBB,9},{0xB7,'-'},
{0x7E,'.'},{0x7D,0},{0x7B,'*'},{0x77,'O'}
};
charscankeypad()//获取4*4键盘扫描码
{
charkey4H=0,key4L=0,scancode=0;
TRISD=0xF0;//低四位输出,高四位输入
PORTD=0x00;//低四位输出0
asm("nop");
asm("nop");//待输出信号稳定
key4H=PORTD;//读取高四位
key4H=key4H&0xF0;//将低四位屏蔽
if(key4H!
=0xF0)//有按键按下
{
delay(20);
key4H=PORTD;//重读
if(key4H!
=0xF0)
{
TRISD=0x0F;
PORTD=0x00;
asm("nop");
asm("nop");
key4L=PORTD;//读取高四位
key4L=key4H&0x0F;//将高四位屏蔽
if(key4L!
=0x0F)//有按键按下
{
scancode=key4H|key4L;//高四位与低四位组成键盘扫描码
while(PORTD!
=0x0F);//按键未松开等待
return(scancode);
}
}
}
returnNO_KEY;
}
charGetkeyvalue()//获取扫描码
{charkeyvalue=0,c=0;
keyvalue=scankeypad();
if(keyvalue!
=NO_KEY)
{
while(keyvalue!
=ccode[c][0])
{//比较描码与当前数组元素是否相等
c++;
}
return(ccode[c][1]);//返回序号对应值
}
return(NO_KEY);
}
voidmain()
{
inti=0,Num[2]={0,0},Numindex=0;
while
(1)
{
i=Getkeyvalue();//获得键值
if(i!
=NO_KEY)//有按键
{
if(i>=0&&i<=9)
{
Num[2]=Numindex*10+i;//新数值
}
else
{
switch(i)
{
case'L':
Num[0]=0;
Num[1]=0;
Numindex=0;
break;
case'.':
break;
case'O':
Num[2]=Numindex*10+i;
break;
default:
break;
};
}
}
}
}
电源输出效率:
(注:
可编辑下载,若有不当之处,请指正,谢谢!
)