摘 要:本系统以直流电流源为核心,AT89S52单片机为主控制器,通过键盘来设置直流电源的输出电流,设置步进等级可达1mA,并可由数码管显示电流设定 值和实际输出电流值。本系统由单片机程控设定数字信号,经过D/A转换器(AD7543)输出模拟量,再经过运算放大器隔离放大,控制输出功率管的基极,随着功率管基极电压的变化而输出不同的电流。单片机系统还兼顾对恒流源进行实时监控,输出电流经过电流/电压转换后,通过A/D转换芯片,实时把模拟量转 化为数据量,再经单片机分析处理,通过数字量形式的反馈环节,使电流更加稳定,这样构成稳定的压控电流源。实际测试结果表明,本系统能有效应用于需要高稳定度的小功率恒流源的领域。 关键词:压控恒流源 智能化电源 闭环控制
The Digital Controlled Direct Current Source Abstract: In this system the DC source is center and 89S52 version single chip microcomputer (SCM) is main controller, output current of DC power can be set by a keyboard which step level reaches 1mA, while the set value and the real output current can be displayed by LED. In the system, the digitally programmable signal from SCM is converted to analog value by DAC (AD7543), then the analog value which is isolated and amplified by operational amplifiers, is sent to the base electrode of power transistor, so an adjustable output current can be available with the base electrode voltage of power transistor. On the other hand, The constant current source can be monitored by the SCM system real-timely, its work process is that output current is converted voltage, then its analog value is converted to digital value by ADC, finally the digital value as a feedback loop is processed by SCM so that output current is more stable, so a stable voltage-controlled constant current power is designed. The test results have showed that it can be applied in need areas of constant current source with high stability and low power.
Keywords: voltage-controlled constant current source, intelligent power,closed loop control 前言 随着电子技术的发展、数字电路应用领域的扩展,现今社会,产品智能化、数字化已成为人们追求的一种趋势,设备的性能、价格、发展空间等备受人们的关注,尤其对电子设备的精密度和稳定度最为关注。性能好的电子设备,首先离不开稳定的电源,电源稳定度越高,设备和外围条件越优越,那么设备的寿命更长。基于此, 人们对数控恒定电流器件的需求越来越迫切.当今社会,数控恒压技术已经很成熟,但是恒流方面特别是数控恒流的技术才刚刚起步且有待发展,高性能的数控恒流器件的开发和应用存在巨大的发展空间。本文正是应社会发展的需求,研制出一种基于单片机的高性能的数控直流恒流源。本数控直流恒流源系统输出电流稳定,输 出电流可在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 <reg52.h> #include <absacc.h> #include<string.h> #include<intrins.h> #define unit unsigned int #define uchar unsigned char #define DELAY_TIME 60 #define TRUE 1 #define FALSE 0
uchar keyup; uchar keydown; uchar keyupstate; uchar keydownstate;
static unsigned int s=0; static unsigned int b=1; static unsigned int q=0; static unsigned int c=0; static unsigned int a;
code unsigned char table[19]= {11,17,23,28,34,39,45,51,56,62,68,73,79,84,90,96,101,107,113}; code unsigned char Seg7Code[11]= //用十六进数作为数组下标,可直接取得对应的七段编码字节 {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0xBF};
sbit SCL=P1^4; sbit SDA=P1^5;
void DELAY(unsigned int t) /*延时函数*/ { while(t!=0) t--; }
void I2C_Start(void) { /*启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变*/ SDA=1; SCL=1; DELAY(DELAY_TIME); SDA=0; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); }
void I2C_Stop(void) { /*终止I2C总线,当SCL为高电平时使SDA产生一个正跳变*/ SDA=0; SCL=1; DELAY(DELAY_TIME); SDA=1; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); }
void SEND_0(void) /* SEND ACK */ { /*发送0,在SCL为高电平时使SDA信号为低*/ SDA=0; SCL=1; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); }
void SEND_1(void) { /*发送1,在SCL为高电平时使SDA信号为高*/ SDA=1; SCL=1; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); }
bit Check_Acknowledge(void) { /*发送完一个字节后检验设备的应答信号*/ SDA=1; SCL=1; DELAY(DELAY_TIME/2); F0=SDA; DELAY(DELAY_TIME/2); SCL=0; DELAY(DELAY_TIME); if(F0==1) return FALSE; return TRUE; }
void WriteI2CByte(char b)reentrant { /*向I2C总线写一个字节*/ char i; for(i=0;i<8;i++) if((b<<i)&0x80) SEND_1(); else SEND_0(); }
char ReadI2CByte(void)reentrant { /*从I2C总线读一个字节*/ char b=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; } return b; }
/**********以下为读写24c02的函数**********/ void Write_One_Byte(char addr,char thedata) { bit acktemp=1; /*write a byte to mem*/ I2C_Start(); WriteI2CByte(0xa0); acktemp=Check_Acknowledge(); WriteI2CByte(addr);/*address*/ acktemp=Check_Acknowledge(); WriteI2CByte(thedata);/*thedata*/ acktemp=Check_Acknowledge(); I2C_Stop();
}
char Read_One_Byte(char addr) { bit acktemp=1; char mydata; /*read a byte from mem*/ 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();
return mydata; I2C_Stop(); }
void DisplayBrush( void ) //显示输出函数 { unit m; 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++); }
void jisuan (void) { s=a/100; b=(a/10)%10; q=a%10; }
void delays(void) //按键去斗延时函数 { uchar i; for(i=300;i>0;i--); }
void main( 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) goto L1; else a+=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) goto L2; else a-=5; c--; L2: keydownstate=keydown; P2=table[c]; jisuan(); DisplayBrush(); Write_One_Byte(0x10,c); Write_One_Byte(0x20,a); } DisplayBrush();
} }
void intsvr0(void) interrupt 0 using 1 { keyup=!keyup; }
void intsur0(void) interrupt 2 using 1 { keydown=!keydown; }
参考链接:http://www.picavr.com/news/2008-01/3139.htm |