数控恒流源程序.docx
《数控恒流源程序.docx》由会员分享,可在线阅读,更多相关《数控恒流源程序.docx(8页珍藏版)》请在冰豆网上搜索。
数控恒流源程序
数控直流恒流源的设计与制作
作者:
佚名 来源:
不详 录入:
Admin 更新时间:
2008-7-2713:
57:
32 点击数:
4
【字体:
】
摘要:
本系统以直流电流源为核心,AT89S52单片机为主控制器,通过键盘来设置直流电源的输出电流,设置步进等级可达1mA,并可由数码管显示电流设定值和实际输出电流值。
本系统由单片机程控设定数字信号,经过D/A转换器(AD7543)输出模拟量,再经过运算放大器隔离放大,控制输出功率管的基极,随着功率管基极电压的变化而输出不同的电流。
单片机系统还兼顾对恒流源进行实时监控,输出电流经过电流/电压转换后,通过A/D转换芯片,实时把模拟量转化为数据量,再经单片机分析处理,通过数字量形式的反馈环节,使电流更加稳定,这样构成稳定的压控电流源。
实际测试结果表明,本系统能有效应用于需要高稳定度的小功率恒流源的领域。
关键词:
压控恒流源 智能化电源闭环控制
TheDigitalControlledDirectCurrentSource
Abstract:
InthissystemtheDCsourceiscenterand89S52versionsinglechipmicrocomputer(SCM)ismaincontroller,outputcurrentofDCpowercanbesetbyakeyboardwhichsteplevelreaches1mA,whilethesetvalueandtherealoutputcurrentcanbedisplayedbyLED.Inthesystem,thedigitallyprogrammablesignalfromSCMisconvertedtoanalogvaluebyDAC(AD7543),thentheanalogvaluewhichisisolatedandamplifiedbyoperationalamplifiers,issenttothebaseelectrodeofpowertransistor,soanadjustableoutputcurrentcanbeavailablewiththebaseelectrodevoltageofpowertransistor.Ontheotherhand,TheconstantcurrentsourcecanbemonitoredbytheSCMsystemreal-timely,itsworkprocessisthatoutputcurrentisconvertedvoltage,thenitsanalogvalueisconvertedtodigitalvaluebyADC,finallythedigitalvalueasafeedbackloopisprocessedbySCMsothatoutputcurrentismorestable,soastablevoltage-controlledconstantcurrentpowerisdesigned.Thetestresultshaveshowedthatitcanbeappliedinneedareasofconstantcurrentsourcewithhighstabilityandlowpower.
Keywords:
voltage-controlledconstantcurrentsource,intelligentpower,closedloopcontrol
前言
随着电子技术的发展、数字电路应用领域的扩展,现今社会,产品智能化、数字化已成为人们追求的一种趋势,设备的性能、价格、发展空间等备受人们的关注,尤其对电子设备的精密度和稳定度最为关注。
性能好的电子设备,首先离不开稳定的电源,电源稳定度越高,设备和外围条件越优越,那么设备的寿命更长。
基于此,人们对数控恒定电流器件的需求越来越迫切.当今社会,数控恒压技术已经很成熟,但是恒流方面特别是数控恒流的技术才刚刚起步且有待发展,高性能的数控恒流器件的开发和应用存在巨大的发展空间。
本文正是应社会发展的需求,研制出一种基于单片机的高性能的数控直流恒流源。
本数控直流恒流源系统输出电流稳定,输出电流可在20mA~2000mA范围内任意设定,不随负载和环境温度变化,并具有很高的精度,输出电流误差范围±4mA,因而可实际应用于需要高稳定度小功率直流恒流源的领域。
1系统原理及理论分析
1.1单片机最小系统组成
单片机系统是整个数控系统的核心部分,它主要用于键盘按键管理、数据处理、实时采样分析系统参数及对各部分反馈环节进行整体调整。
主要包括AT89S52单片机、模数转换芯片ADC0809、12位数模转换芯片AD7543、数码管显示译码芯片74LS47与74LS138等器件。
1.2系统性能
本系统的性能指标主要由两大关系所决定,设定值与A/D采样显示值(系统内部测量值)的关系。
内部测量值与实际测量值的关系,而后者是所有仪表所存在的误差。
在没有采用数字闭环之前,设定值与内部测量值的关系只能通过反复测量来得出它们的关系(要送多大的数才能使D/A输出与设定电流值相对应的电压值),再通过单片机乘除法再实现这个关系,基本实现设定值与内部测量值相一致。
但由于周围环境等因素的影响,使设定值与内部测量值的关系改变,使得设定值与内部测量值不一致,有时会相差上百毫安,只能重新测量设定值与A/D采样显示值的关系改变D/A入口数值的大小才能重新达到设定值与内部测量值相一致,也就是说还不稳定。
在采用数字闭环后。
通过比较设定值与A/D采样显示值,得出它们的差值,再调整D/A的入口数值,从而使A/D采样显示值逐步逼近设定值最终达到一致。
而我们无须关心D/A入口数值的大小,从而省去了原程序中双字节乘除的部分,使程序简单而不受周围环境等因素的影响。
内部测量值与实际测量值的误差是由于取样电阻与负载电阻和晶体管的放大倍数受温度的影响和测量仪表的误差所造成的,为了减少这种误差,一定要选用温度系数低的电阻来作采样电阻,因此本系统选用锰铜电阻丝来做采样电阻。
1.3恒流原理
数模转换芯片AD7543是12位电流输出型,其中OUT1和OUT2是电流的输出端。
电流的输出级别可这样计算
;****************************************************************
更详细请下载下面的文档:
temp_08012710577011.rar
;****************************************************************
数控恒流源程序
#include
#include
#include
#include
#defineunitunsignedint
#defineucharunsignedchar
#defineDELAY_TIME60
#defineTRUE1
#defineFALSE0
ucharkeyup;
ucharkeydown;
ucharkeyupstate;
ucharkeydownstate;
staticunsignedints=0;
staticunsignedintb=1;
staticunsignedintq=0;
staticunsignedintc=0;
staticunsignedinta;
codeunsignedchartable[19]=
{11,17,23,28,34,39,45,51,56,62,68,73,79,84,90,96,101,107,113};
codeunsignedcharSeg7Code[11]= //用十六进数作为数组下标,可直接取得对应的七段编码字节
{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0xBF};
sbitSCL=P1^4;
sbitSDA=P1^5;
voidDELAY(unsignedintt)/*延时函数*/
{
while(t!
=0)
t--;
}
voidI2C_Start(void)
{
/*启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变*/
SDA=1;
SCL=1;
DELAY(DELAY_TIME);
SDA=0;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
voidI2C_Stop(void)
{
/*终止I2C总线,当SCL为高电平时使SDA产生一个正跳变*/
SDA=0;
SCL=1;
DELAY(DELAY_TIME);
SDA=1;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
voidSEND_0(void) /*SENDACK*/
{
/*发送0,在SCL为高电平时使SDA信号为低*/
SDA=0;
SCL=1;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
voidSEND_1(void)
{
/*发送1,在SCL为高电平时使SDA信号为高*/
SDA=1;
SCL=1;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
bitCheck_Acknowledge(void)
{
/*发送完一个字节后检验设备的应答信号*/
SDA=1;
SCL=1;
DELAY(DELAY_TIME/2);
F0=SDA;
DELAY(DELAY_TIME/2);
SCL=0;
DELAY(DELAY_TIME);
if(F0==1)
returnFALSE;
returnTRUE;
}
voidWriteI2CByte(charb)reentrant
{
/*向I2C总线写一个字节*/
chari;
for(i=0;i<8;i++)
if((b<
SEND_1();
else
SEND_0();
}
charReadI2CByte(void)reentrant
{
/*从I2C总线读一个字节*/
charb=0,i;
for(i=0;i<8;i++)
{
SDA=1; /*释放总线*/
SCL=1; /*接受数据*/
DELAY(10);
F0=SDA;
DELAY(10);
SCL=0;
if(F0==1)
{
b=b<<1;
b=b|0x01;
}
else
b=b<<1;
}
returnb;
}
/**********以下为读写24c02的函数**********/
voidWrite_One_Byte(charaddr,charthedata)
{
bitacktemp=1;
/*writeabytetomem*/
I2C_Start();
WriteI2CByte(0xa0);
acktemp=Check_Acknowledge();
WriteI2CByte(addr);/*address*/
acktemp=Check_Acknowledge();
WriteI2CByte(thedata);/*thedata*/
acktemp=Check_Acknowledge();
I2C_Stop();
}
charRead_One_Byte(charaddr)
{ bitacktemp=1;
charmydata;
/*readabytefrommem*/
I2C_Start();
WriteI2CByte(0xa0);
acktemp=Check_Acknowledge();
WriteI2CByte(addr);/*address*/
acktemp=Check_Acknowledge();
I2C_Start();
WriteI2CByte(0xa1);
acktemp=Check_Acknowledge();
mydata=ReadI2CByte();
acktemp=Check_Acknowledge();
returnmydata;
I2C_Stop();
}
voidDisplayBrush(void) //显示输出函数
{
unitm;
P0=0xff;
P0=Seg7Code[10];
P1=0xfe;
for(m=0;m<1000;m++);
P0=Seg7Code[s];
P1=0xfd;
for(m=0;m<1000;m++);
P0=Seg7Code[b];
P1=0xfb;
for(m=0;m<1000;m++);
P0=Seg7Code[q];
P1=0xf7;
for(m=0;m<1000;m++);
}
voidjisuan(void)
{ s=a/100;
b=(a/10)%10;
q=a%10;
}
voiddelays(void) //按键去斗延时函数
{ uchari;
for(i=300;i>0;i--);
}
voidmain(void)
{ c=Read_One_Byte(0x10);
a=Read_One_Byte(0x20);
if(c>18||a>100)
{c=0;a=10;}
P2=table[c];
jisuan();
DisplayBrush();
EA=1;IT0=1;IT1=1;EX0=1;EX1=1;
while
(1)
{
if(keyupstate!
=keyup)
{ delays();
if(c<=18)
{if(a==100)
gotoL1;
elsea+=5;
c++;}
L1:
keyupstate=keyup;
P2=table[c];
jisuan();
DisplayBrush();
Write_One_Byte(0x10,c);
Write_One_Byte(0x20,a);
}
///////////////////////////////////////////////////////
if(keydownstate!
=keydown)
{ delays();
if(a==10)
gotoL2;
elsea-=5;
c--;
L2:
keydownstate=keydown;
P2=table[c];
jisuan();
DisplayBrush();
Write_One_Byte(0x10,c);
Write_One_Byte(0x20,a);
}
DisplayBrush();
}
}
voidintsvr0(void) interrupt0using1
{
keyup=!
keyup;
}
voidintsur0(void) interrupt2using1
{
keydown=!
keydown;
}