1994年简易数控直流电源.docx
《1994年简易数控直流电源.docx》由会员分享,可在线阅读,更多相关《1994年简易数控直流电源.docx(19页珍藏版)》请在冰豆网上搜索。
1994年简易数控直流电源
简易数控直流电源
摘要:
本系统针对1994年全国电子竞赛A题要求,采用STC89C52单片机作为控制核心,以LCD1602作为数字显示系统,用4*4矩阵键盘作为实际控制步进部分,用DAC0832及OP07组合成输出电压装置。
用变压器和自制稳压电路输出±15V和5V,以ADC0832采集输出电压。
本题以显示方便用1602显示电压,实际应用数码管显示。
关键字:
单片机,LCD1602,矩阵键盘,DAC0832,OP07,ADC0832。
总体方案设计方案
一、总体设计思路:
图一:
原理图
有原理图可采用AT89C52系列单片机作为整机的控制单元,通过改变输入数字量来改变输出电压值(A/D转换后电压值),经集成运放放大输出,间接地改变输出电压的大小。
图二:
总体设计框图
二、各模块设计:
1.自制稳压电源模块
根据题目要求和设计思路,稳压电源需要输出±15V和5V,±15V需要给运放(OP07)供电,5V需要给单片机、LCD1602及给DAC0832、ADC0832充当基准电压。
因为输入是三相220V交流电,所以需要变压器起降压作用。
变压器规格为两入三出形式,其中三出中包括一条地线输出±15V和5V分别需要LM7815、LM7915、LM7805稳压芯片。
具体电路图如图1所示(所用仿真软件是Multisim):
图三:
稳压电路图
电路说明:
V1:
220V50Hz交流电,和平时使用的三相220V交流电完全相同
T1:
12:
1规格的变压器,输出大致为18.3V。
D1、D2、D3、D4:
四个二极管构成整流桥,进行初步滤波。
C1、C2、C7:
2.2mF电容用于进一步滤波。
LM7815CT:
稳压芯片用于输出+15V。
LM7915CT:
稳压芯片用于输出-15V。
LM7805CT:
稳压芯片用于输出+5V。
2.电压源电路的设计
基本设计思路是通过DAC0832与单片机相连输出电流然后经过运放放大输出电压,矩阵键盘与单片机相连,通过控制键盘调节DAC0832的输出大小,通过1602进行显示。
图四:
总控制电路图
(1)电路介绍:
采用STC89C52芯片作为主控制器,P0和1602数据口直接相连,RS,E分别与P3.6、P3.7连接,RW、VSS直接接地。
DAC0832的CS接P3.4口,WR1接P3.5口,WR2,XFER接地。
让DA工作在直通方式下。
DA的8脚接参考电压+5V(UREF),参考电压电路如图四所示。
ADC0832的CS接P3.0,选择CH0端作为数据信号输入端口,DO与DI相连与P3.1口。
第一级运放的负接口与IOUT1连接,IOUT2接地,经第一级运放输出为0~-5V,第二级运放为负相放大,放大倍数为2.5倍,负转正,输出为0~+10V。
两个运放需±15V供电。
因为DAC0832是8位D/A转换器,所以把电压分成了256份因为最终经放大电压输出为12,5V左右,所以控制的时侯每次加二就能实现步进为0.1V。
AT89C52是美国ATMEL公司生产的低电压,高性能CMOS8位单片机,片内含4kB的可反复擦写的只读程序存储器(EPROM)和128B的随机数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS251指令系统,内置通用8位中央处理器(CPU)和FLASH存储单元[1]。
DAC0832是采用CMOS工艺、具有8位分辨能力的D/A转换器。
它有三种工作方式:
不带缓冲工作方式、单缓冲工作方式、双缓冲工作方式,可直接与AT89C51相连。
DAC0832内部采用倒T型电阻网络,芯片中无运算放大器,使用时需外接运放,输出是模拟电流Io1、和Io2。
芯片中已设置反馈电阻Rf,使用时将Rf输出端接运算放大器的输出端即可。
本电路采用不带缓冲工作方式,UREF为D/A转换器的基准电压。
图五:
基准电压电路
(2)按键控制说明
矩阵各按键功能如图六所示:
1
2
3
4
5
6
7
8
9
0
+0.1V
-0.1V
连续增加
空
空
清零
图六:
矩阵键盘功能图
功能介绍:
0~9:
这十个数是用于置数功能,可以显示0.0~9.9所有的数,当按下后输出所输入的数。
例如当按下5后,1602上面随机显示5.V,这时只要再次按下0~9,就能实现电压的输出,例如,再次按下6,显示5.6V。
±0.1V:
每按下一次,电压就±0.1V,实现步进为0.1V。
连续增加:
当按下此键时,电压从0.0V每1秒加0.1V,当再次按下时增加停止,液晶上显示的电压数就是实际输出电压。
清零:
当按下此键时电压清为零。
电压显示部分:
液晶1602第一行显示DAC0832控制电压,第二行显示ADC0832采集的实际输出电压。
,这样设计避免了,只输出步进电压或实际采集电压。
(3)控制实现流程图
图七:
控制流程图
三、数据处理
1.误差测试
下面列出部分电压值及其对应的理论值和实际的数字量,其中对应码值为输入电压对应数模转换所需的码值,实际码值为单片机根据输入电压值处理后送到数模转换器的码值如下表所示。
误差测试表
理论电压值(V)
实际电压值(V)
误差(V)
2.数值处理
数值处理如下:
次数
1
2
3
4
5
6
7
8
单位
给定值
V
测量值
V
偏差值
V
误差百分比
四、参考文献
[1]郭天祥.51单片机C语言教程.电子工业出版社.
[2]康华光.电子技术基础.高等教育出版社.
[3]黄志玮.全国大学生电子设计竞赛训练教程.电子工业出版社
附录:
程序清单
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
sbitsjml=P3^6;//液晶
sbitsneng=P3^7;
sbitcsad=P3^4;//DAC
sbitwrad=P3^5;
sbitclk=P3^2;
sbitcs=P3^0;//ADC
sbitDI=P3^1;
sbitDO=P3^1;
uchara[]="0123456789.V";
uchare[]="ZS:
";
ucharb[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};//4*4矩阵,先行后列
//ucharb[]={0x77,0x7b,0x7d,0x7e,0xb7,0xbb,0xbd,0xbe,0xd7,0xdb,0xdd,0xde,0xe7,0xeb,0xed,0xee};
ucharbb,ge3,shi3;
ucharc[]={0xfe,0xfd,0xfb,0xf7};//四行,先上后下
//ucharc[]={0x7f,0xbf,0xdf,0xef};
longs1,s2,s3,num,nums,ss,tt,kk,jj;
ucharshi,bai,qian,wan;
ucharDATA,DATA1,DATA2;
floatdatas;
longnumm;
voiddelay(uintxms)//延迟
{
uintk,L;
for(k=xms;k>0;k--)
for(L=110;L>0;L--);
}
voidwrite_com(ucharcom)
{
sjml=0;
P0=com;
delay
(1);
sneng=1;
delay
(1);
sneng=0;
}
voidwrite_data(uchardate)
{
sjml=1;
P0=date;
delay
(1);
sneng=1;
delay
(1);
sneng=0;
}
voidinit()
{
sneng=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
voidzhishuo()//显示
{
uchari,j,ge1,shi1,ge2,shi2;
for(j=0;j<4;j++)
{
P2=c[j];
bb=P2;
bb=bb&0xf0;
if(bb!
=0xf0)
{
delay(5);
bb=P2;
bb=bb&0xf0;
if(bb!
=0xf0)
{
//delay(25);
bb=P2;
for(i=0;i<9;i++)
{
if(bb==b[i])//1~9
{
s1=s1*10+i+1;
tt+=1;
kk=1;
nums=s1*2;
}
}
if(bb==b[9])//0
{
s1=s1*10;
tt+=1;
kk=1;
nums=s1*2;
}
if(bb==b[10])//+0.1
{
kk=2;
s2=s2+1;
if(s2==100)
s2=0;
s1=0;
nums=s2*2;
}
if(bb==b[11])//-0.1
{
kk=2;
s2=s2-1;
if(s2<0)
s2=99;
s1=0;
nums=s2*2;
}
if(bb==b[12])//自动+0.1,连续
{
kk=3;
jj+=1;
TR0=~TR0;
if(jj%3==0)
s3=0;
}
if(bb==b[15])//置零
{
s1=s2=s3=0;
nums=s1=s2=s3;
}
while(bb!
=0xf0)
{
bb=P2;
bb=bb&0xf0;
}
}
}
ge1=s1%10;
shi1=s1/10;
ge2=s2%10;
shi2=s2/10;
if(kk==2)
{
write_com(0x80);
write_data(a[shi2]);
write_data(a[10]);
write_data(a[ge2]);
write_data(a[11]);
}
if((tt%2==1)&&(kk==1))
{
write_com(0x80);
write_data(a[ge1]);
write_data(a[10]);
write_com(0x80+3);
write_data(a[11]);
}
if((tt/2>0)&&(kk==1))
{
write_com(0x80);
write_data(a[shi1]);
write_data(a[10]);
write_data(a[ge1]);
write_data(a[11]);
}
if(kk==3)
{
nums=s3*2;
if(num==40)
{
num=0;
s3+=1;
if(s3==100)
s3=0;
ge3=s3%10;
shi3=s3/10;
write_com(0x80);
write_data(a[shi3]);
write_data(a[10]);
write_data(a[ge3]);
write_data(a[11]);
}
}
}
}
voidadc()
{
uchari;
DI=1;
cs=1;
_nop_();
clk=0;
_nop_();
cs=0;
DI=1;
clk=1;
_nop_();
clk=1;
_nop_();
clk=0;
DI=1;
_nop_();
clk=1;
_nop_();
clk=0;
DI=0;
_nop_();
clk=1;
_nop_();
clk=0;
DI=1;
for(i=8;i>0;i--)//得到一个正常排序的8位数据
{
DATA1|=DO;
DATA1<<=1;
clk=1;
_nop_();
clk=0;
_nop_();
}
for(i=8;i>0;i--)//得到一个反序排列的8位数据
{
DATA2>>=1;
if(DO)
DATA2|=0x80;
else
DATA2|=0x00;
_nop_();
clk=1;
_nop_();
clk=0;
}
clk=0;
_nop_();
_nop_();
clk=1;
_nop_();
_nop_();
clk=0;
_nop_();
_nop_();
clk=1;
_nop_();
cs=1;
_nop_();
_nop_();
//DATA=(DATA1==DATA2)?
DATA1:
DATA2;
DATA=DATA1;
datas=DATA*3.96;
numm=datas*100;
shi=numm/10%10;
bai=numm/100%10;
qian=numm/1000%10;
wan=numm/10000;
write_com(0x80+0x40);
write_data(a[wan]);
write_data('.');
write_data(a[qian]);
write_data(a[bai]);
write_data(a[shi]);
write_data('v');
}
/*voidadc_display()
{
ucharshi,bai,qian,wan;
datas=DATA*1.96;
numm=datas*100;
shi=numm/10%10;
bai=numm/100%10;
qian=numm/1000%10;
wan=numm/10000%10;
write_com(0x80+0x40);
write_data(a[wan]);
write_data('.');
write_data(a[qian]);
write_data(a[bai]);
write_data(a[shi]);
write_data('v');
}*/
voiddac()
{
csad=0;
wrad=0;
delay
(1);
P1=nums;
delay(3);
csad=1;
wrad=1;
}
voidmain()
{
init();
TMOD=0x01;
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
EA=1;
ET0=1;
TR0=0;
while
(1)
{adc();
zhishuo();
dac();
//delay(20);
//adc_display();
}
}
voidtime()interrupt1
{
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
num++;
}