|
摘 要:本系統以直流電流源為核心,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; }
|