一、系統綜述: 該項設計的主要目的是設計一種數控穩壓電源。它利用單片機STC89C51作為主控芯片,控制數字/模擬轉換器(TLC5615)的輸出電壓的大小,經過運算放大器(OPA2107)與IRF9Z24N構成負反饋系統,從而輸出恒定電壓。最后通過電位器分壓將輸出信號反饋到運算放大器(OPA2107)上,使輸出準確度可以調節。此設計通過鍵盤電路與單片機連接,讀入控制數據,利用軟件進行判斷,從而起到控制電源輸出的作用。通過LCD1602(或LED數碼管)顯示數控電源的輸出電壓,實現簡單的人機對話。該項設計具有設計簡單,控制靈活,調節方便,攜帶方便、成本低等優勢,具有較強的實用性。 總體電路圖(數碼管版) 要求有短路保護的才有對應的電路,此圖為完整版及帶短路保護的。 總體電路圖(液晶版) 要求有短路保護的才有對應的電路,此圖為完整版及帶短路保護的。 圖中采用網絡標號的方式,標號相同的代表有電氣連接! 二、原理講解: 供電部分: P2為接線柱,是整個系統的輸入電壓端口,整個數控電源有此輸入能量。D1、D2、D3、D4為四個二極管(in4007),起整流的作用,C6為濾波電容。整流濾波電路是使供電可以為交流,同時也可以用直流供電(交流供電不要超過20V,直流不要超過35V)。受電壓限制的主要是后級運放耐壓、TL431耐壓以及7812的耐壓值。7812主要為保護7805,7805穩出5V電壓共單片機供電使用。但是7805耐壓值是15V,所以前級要加7812保護7805。
晶振部分: C2、C3、Y1(12MHZ)與單片機端口構成震蕩電路,為51單片機提供時鐘。 復位電路: RST連接單片機復位管腳,此電路及有上電復位功能,又有手動復位功能。C1、R2構成上電復位電路,上電瞬間C1導通,則RST為高電平,單片機將復位,電壓穩定后C1儲存的電能通過R2對地釋放掉,單片機將正常運行。同樣K2按下時RST為高電平,單片機復位,彈起來時RST為低電平,單片機正常運行。
單片機部分: 單片機默認選用STC89C51,同時兼容STC89C52、AT89S52、AT89S51、AT89C51等51單片機。 按鍵部分: 按鍵選用獨立按鍵,掃描時間短,使程序更簡單且掃描時間更短,從而提高穩定性。按鍵彈起時P20、P21、P22、P23為弱上拉狀態,所以為高電平。按鍵按下時對應的I/O口為低電平,可以被程序中的掃描函數檢測到。(寫文檔時沒什么寫的,可以在此講解自彈按鍵與自鎖按鍵區別和原理,在此朱老師省略。)
數碼管顯示部分: (寫文檔時,可以在此講解共陽數碼管與共陰數碼管的區別和原理,在此朱老師省略。) 數碼管顯示采用四位一體共陽數碼管,這樣使電路更為簡單,只需四個8550三極管就可以將其驅動。P24、P25、P26、P27分別作為數碼管的位選端,控制是否選通哪一位數碼管。采用PNP型三極管,低電平導通,高電平截止(寫文檔時可以在此處講解8550三極管的參數等信息,朱老師在此省略)。R20、R30、R40、R50為三極管基極限流電阻,此電阻及能保護三極管又能保證三極管導通時處于完全導通狀態。R51為限流電阻,此電阻的大小直接決定數碼管的亮暗成都,在此選擇220歐姆、1/4色環電阻。數碼管的陰極端直接接單片機的P0口,而不需上拉電阻。STC89C51的單片機P0口為漏極開路,所以作為輸出時必須接上拉電路,而作為輸入時相當于數碼管作為上拉,所以不再需要上拉電阻,及簡化了電路又節省了成本。 數模轉換部分:(此為數控電壓數控調壓關鍵所在) (寫文檔時沒什么寫的,可以在此講解TLC5615技術參數和原理,特別是轉換公式和數據協議,在此朱老師簡單介紹。) 數模轉換采用德州儀器的TLC5615,此為一片10位串行單5V電源DAC,直接電壓輸出。單片機P33、P32、P34分別連接TLC5615的時鐘端、片選端、數據端即可控制它輸出想要的電壓。此時TLC5615的6腳及參考電壓輸入端需接入2.5V的參考電壓。根據公式可知,當參考電壓為2.5V時,TLC5615將最大輸出5V電壓。 TL5615(DAC)電壓計算公式
Vout為7腳輸出電壓,Vrefin為6腳參考電壓輸入端,N為單片機通過1、2、3管腳向TLC5615寫入的數據,1024是根據這是一片10位數模轉換而計算出來的(210=1024),最后乘以二是因為TLC5615內部有2倍的增益放大器。 TLC5615內部原理圖: TLC5615邏輯時序圖:
在給TLC輸入2.5V參考電壓的時候,我們用了TL431芯片。TL431是可控精密穩壓源。它的輸出電壓用兩個電阻就可以任意的設置到從Verf(2.5V)到36V范圍內的任何值。該器件的典型動態阻抗為0.2Ω,在很多應用中用它代替穩壓二極管。 同時用OPA2107作為跟隨器,減小2.5V基準電源的阻抗,再送入TLC5615 參考電壓端。 (寫文檔時,可以在此講解TL41技術參數OPA2107技術參數和原理和跟隨器電路原理)
MOS放大部分: 將上述TLC5615輸出的可調電壓送到誤差放大器(OPA2107)的反相端,通過PMOS管(F9Z24N)放大。同時在F9Z24N的輸出端用RW1(10K)電位器分壓,取一定比例的輸出電壓反饋到比較器正相端,構成一個負反饋系統(PMOS是反相放大,所以是負反饋)以保證輸出電壓的穩定。C5作為輸出濾波電容,濾掉輸出電壓紋波。根據反饋系統的穩定原理計算出輸出電壓的公式,如下: 設:Vo為輸出電壓,Vin為OPA2107的2腳輸入電壓,RWH為電位器上部分電阻,RWL為電位器下部分電阻,RW為電位器阻值。 Vo=Vin×(RW/RWL); (寫文檔時,可以在此講解F9Z24N技術參數) 過流檢測及短路保護: P1為電源輸出端,R11為電流檢測電阻,此電阻將電流變換成電壓。再通過U4A(OPA2107)反相放大一定的倍數。最后通過U4B與2.5V標準電平比較,若電壓大于2.5V則輸出低電平,送給單片機。單片機則認為過流就會控制TLC5615將輸出將為0V。這樣就起到了限流與短路保護的作用。 (寫文檔時,可以在此講解反相比例運算電路的原理) 報警電路:  此電路可以由單片機控制三極管(8550)的通斷來控制蜂鳴器的報警。當P36為高時,三極管不高通,為低時三極管導通蜂鳴器響。當過流或短路時,單片機切斷輸出,同時蜂鳴器報名。
單片機源程序如下:
- <font color="rgb(0, 0, 0)">#include<reg52.h>
- #define uint unsigned int
- #define uchar unsigned char
- uchar a,miao,shi,fen,ri,yue,nian,week,key1n,key4n,key3n;alarmflag,temp;
- char amiao,afen,ashi;
- bit flag=0;
- #define yh 0x80
- #define er 0x80+0x40
- sbit rw=P3^6;
- sbit rs=P3^5;
- sbit en=P3^4;
- sbit IO=P1^1;
- sbit RST=P1^2;
- sbit SCLK=P1^0;
- sbit ACC0=ACC^0;
- sbit ACC7=ACC^7;
- //sbit key5=P1^3;
- sbit key1=P3^0;
- sbit key2=P3^1;
- sbit key3=P3^2;
- sbit key4=P3^3;
- sbit beep=P2^4;
- uchar code tab1[]={"20 - - "};
- uchar code tab2[]={" : : "};
- uchar code tab3[]={" alarm setting: "};
- uchar code tab4[]={"Now is the time!"};
- uchar code tab5[]={"Get up quickly! "};
- uchar code tab6[]={"HAPPY EVERY DAY!"};
- uchar cnt;
- void delay(uint xms)
- {
- uint x,y;
- for(x=xms;x>0;x--)
- for(y=110;y>0;y--);
- }
- void write_1602com(uchar com)
- {
- rs=0;
- rw=0;
- P0=com;
- delay(1);
- en=1;
- delay(1);
- en=0;
- }
- void write_1602dat(uchar dat)
- {
- rs=1;
- rw=0;
- P0=dat;
- delay(1);
- en=1;
- delay(1);
- en=0;
- }
- void lcd_init()
- {
- write_1602com(0x38);
- write_1602com(0x08);
- write_1602com(0x0c);
- write_1602com(0x06);
- write_1602com(0x01);
- write_1602com(yh+1);
- for(a=0;a<14;a++)
- {
- delay(5);
- write_1602dat(tab1[a]);
- }
- write_1602com(er+2);
- for(a=0;a<8;a++)
- {
- delay(5);
- write_1602dat(tab2[a]);
- }
- }
- void write_byte(uchar dat)
- {
- ACC=dat;
- RST=1;
- for(a=8;a>0;a--)
- {
- IO=ACC0;
- SCLK=0;
- SCLK=1;
- ACC=ACC>>1;
- }
- }
- uchar read_byte()
- {
- RST=1;
- for(a=8;a>0;a--)
- {
- ACC7=IO;
- SCLK=1;
- SCLK=0;
- ACC=ACC>>1;
- }
- return(ACC);
- }
- void write_1302(uchar add,uchar dat)
- {
- RST=0;
- SCLK=0;
- RST=1;
- write_byte(add);
- write_byte(dat);
- SCLK=1;
- RST=0;
- }
- uchar read_1302(uchar add)
- {
- uchar temp;
- RST=0;
- SCLK=0;
- RST=1;
- write_byte(add);
- temp=read_byte();
- SCLK=1;
- RST=0;
- return(temp);
- }
- uchar BCD_Decimal(uchar bcd)
- {
- uchar Decimal;
- Decimal=bcd>>4;
- return(Decimal=Decimal*10+(bcd&=0x0f));
- }
- void ds1302_init()
- {
- RST=0;
- SCLK=0;
- write_1302(0x8e,0x00);
- write_1302(0x8e,0x80);
- }
- void write_sfm(uchar add,uchar dat)
- {
- uchar gw,sw;
- gw=dat%10;
- sw=dat/10;
- write_1602com(er+add);
- write_1602dat(0x30+sw);
- write_1602dat(0x30+gw);
- }
- void write_nyr(uchar add,uchar dat)
- {
- uchar gw,sw;
- gw=dat%10;
- sw=dat/10;
- write_1602com(yh+add);
- write_1602dat(0x30+sw);
- write_1602dat(0x30+gw);
- }
- void write_week(uchar week)
- {
- write_1602com(yh+0x0c);
- switch(week)
- {
- case 1:write_1602dat('M');write_1602dat('O');write_1602dat('N');break;
- case 2:write_1602dat('T');write_1602dat('U'); write_1602dat('E');break;
- case 3:write_1602dat('W');write_1602dat('E');write_1602dat('D');break;
- case 4:write_1602dat('T');write_1602dat('H');write_1602dat('U');break;
- case 5:write_1602dat('F');write_1602dat('R');write_1602dat('T');break;
- case 6:write_1602dat('S');write_1602dat('T');write_1602dat('A');break;
- case 7:write_1602dat('S');write_1602dat('U');write_1602dat('N');break;
- }
- }
- void settime()
- {
- if(key4n==0)
- {
- if(key1==0)
- {
- delay(9);
- if(key1==0)
- {
- beep=0;//蜂鳴器短響一聲
- delay(50);
- beep=1;
- alarmflag=0;
- key1n++;
- while(!key1);
- switch(key1n)
- {
- case 1:TR0=0;
- write_1602com(er+0x09);
- write_1602com(0x0f);
- temp=(miao)/10*16+(miao)%10;
- write_1302(0x8e,0x00);
- write_1302(0x80,0x80|temp);//miao
- write_1302(0x8e,0x80);
- break;
- case 2:write_1602com(er+6);
- break;
- case 3:write_1602com(er+3);
- break;
- case 4:write_1602com(yh+0x0e);
- break;
- case 5:write_1602com(yh+0x0a);
- break;
- case 6:write_1602com(yh+0x07);
- break;
- case 7:write_1602com(yh+0x04);
- break;
- case 8:key1n=0;
- write_1602com(0x0c);
- alarmflag=1;
- TR0=1;
- temp=(miao)/10*16+(miao)%10;
- write_1302(0x8e,0x00);
- write_1302(0x80,0x00|temp);
- write_1302(0x8e,0x80);
- break;
- }
- }
-
- }
- if(key1n!=0)
- {
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- beep=0;//蜂鳴器短響一聲
- delay(50);
- beep=1;
- while(!key2);
- switch(key1n)
- {
- case 1:miao++;
- if(miao==60)
- miao=0;
- write_sfm(0x08,miao);
- temp=(miao)/10*16+(miao)%10;
- write_1302(0x8e,0x00);
- write_1302(0x80,temp);
- write_1302(0x8e,0x80);
- write_1602com(er+0x09);
- break;
- case 2:fen++;
- if(fen==60)
- fen=0;
- write_sfm(0x05,fen);
- temp=(fen)/10*16+(fen)%10;
- write_1302(0x8e,0x00);
- write_1302(0x82,temp);
- write_1302(0x8e,0x80);
- write_1602com(er+6);
- break;
- case 3:shi++;
- if(shi==24)
- shi=0;
- write_sfm(2,shi);
- temp=(shi)/10*16+(shi)%10;
- write_1302(0x8e,0x00);
- write_1302(0x84,temp);
- write_1302(0x8e,0x80);
- write_1602com(er+3);
- break;
- case 4:week++;
- if(week==8)
- week=1;
- write_1602com(yh+0x0e);
- write_week(week);
- temp=(week)/10*16+(week)%10;
- write_1302(0x8e,0x00);
- write_1302(0x8a,temp);
- write_1302(0x8e,0x80);
- write_1602com(yh+0x0e);
- break;
- case 5:ri++;
- if(ri==32)
- ri=1;
- write_nyr(9,ri);
- temp=(ri)/10*16+(ri)%10;
- write_1302(0x8e,0x00);
- write_1302(0x86,temp);
- write_1302(0x8e,0x80);
- write_1602com(yh+10);
- break;
- case 6:yue++;
- if(yue==13)
- yue=1;
- write_nyr(6,yue);
- temp=(yue)/10*16+(yue)%10;
- write_1302(0x8e,0x00);
- write_1302(0x88,temp);
- write_1302(0x8e,0x80);
- write_1602com(yh+7);
- break;
- case 7:nian++;
- if(nian==100)
- nian=0;
- write_nyr(3,nian);
- temp=(nian)/10*16+(nian)%10;
- write_1302(0x8e,0x00);
- write_1302(0x8c,temp);
- write_1302(0x8e,0x80);
- write_1602com(yh+4);
- break;
- }
- }
- }
- if(key3==0)
- {
- delay(10);
- if(key3==0)
- {
- beep=0;//蜂鳴器短響一聲
- delay(50);
- beep=1;
- while(!key3);
- switch(key1n)
- {
- case 1:miao--;
- if(miao==-1)
- miao=59;
- write_sfm(0x08,miao);
- temp=(miao)/10*16+(miao)%10;
- write_1302(0x8e,0x00);
- write_1302(0x80,temp);
- write_1302(0x8e,0x80);
- write_1602com(er+0x09);
- break;
- case 2:fen--;
- if(fen==-1)
- fen=59;
- write_sfm(5,fen);
- temp=(fen)/10*16+(fen)%10;
- write_1302(0x8e,0x00);
- write_1302(0x82,temp);
- write_1302(0x8e,0x80);
- write_1602com(er+6);
- break;
- case 3:shi--;
- if(shi==-1)
- shi=23;
- write_sfm(2,shi);
- temp=(shi)/10*16+(shi)%10;
- write_1302(0x8e,0x00);
- write_1302(0x84,temp);
- write_1302(0x8e,0x80);
- write_1602com(er+3);
- break;
- case 4:week--;
- if(week==-0)
- week=7;
- write_1602com(yh+0x0c);
- write_week(week);
- temp=(week)/10*16+(week)%10;
- write_1302(0x8e,0x00);
- write_1302(0x8a,temp);
- write_1302(0x8e,0x80);
- write_1602com(yh+0x0e);
- break;
- case 5:ri--;
- if(ri==0)
- ri=31;
- write_nyr(9,ri);
- temp=(ri)/10*16+(ri)%10;
- write_1302(0x8e,0x00);
- write_1302(0x86,temp);
- write_1302(0x8e,0x80);
- write_1602com(yh+10);
- break;
- case 6:yue--;
- if(yue==0)
- yue=12;
- write_nyr(6,yue);
- temp=(yue)/10*16+(yue)%10;
- write_1302(0x8e,0x00);
- write_1302(0x88,temp);
- write_1302(0x8e,0x80);
- write_1602com(yh+7);
- break;
- case 7:nian--;
- if(nian==-1)
- nian=99;
- write_nyr(3,nian);
- temp=(nian)/10*16+(nian)%10;
- write_1302(0x8e,0x00);
- write_1302(0x8c,temp);
- write_1302(0x8e,0x80);
- write_1602com(yh+4);
- break;
- }
- }
- }
-
- }
- }
- }
- void setalarm()
- { if(flag==0)
- {if(key1n==0)
-
- {if(key4==0)
- {
- delay(10);
- if(key4==0)
- {
- beep=0;
- delay(50);
- beep=1;
- while(!key4);
- write_1602com(0x80);
- for(a=0;a<16;a++)
- {
- write_1602dat(tab3[a]);
- }
- if(key4n==0)
- {
- write_1602com(er+0x09);write_sfm(8,amiao);
- write_1602com(er+6);write_sfm(5,afen);
- write_1602com(er+3);write_sfm(2,ashi);
- }
- beep=0;key4n++;
- switch(key4n)
- {
- case 1:
- write_1602com(er+0x06);
- write_1602com(0x0f);
- temp=(fen)/10*16+(fen)%10;
- write_1302(0x8e,0x00);
- write_1302(0x82,0x82|temp);//miao
- write_1302(0x8e,0x80);
- break;
- case 2:write_1602com(er+3);
- break;
- case 3: key4n=0;
- write_1602com(0x0c);
- alarmflag=1;
- lcd_init();
- temp=(fen)/10*16+(fen)%10;
- write_1302(0x8e,0x00);
- write_1302(0x82,0x00|temp);
- write_1302(0x8e,0x80);
- break;
- }
- }
-
- }
- if(key4n!=0)
- {
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- beep=0;//蜂鳴器短響一聲
- delay(50);
- beep=1;
- while(!key2);
- switch(key4n)
- {
- case 1:afen++;
- if(afen==60)
- afen=0;
- write_sfm(0x05,afen);
- temp=(fen)/10*16+(fen)%10;
- write_1302(0x8e,0x00);
- write_1302(0x82,temp);
- write_1302(0x8e,0x80);
- write_1602com(er+6);
- break;
- case 2:ashi++;
- if(ashi==24)
- ashi=0;
- write_sfm(2,ashi);
- temp=(shi)/10*16+(shi)%10;
- write_1302(0x8e,0x00);
- write_1302(0x84,temp);
- write_1302(0x8e,0x80);
- write_1602com(er+3);
- break;
- }
- }
- }
- if(key3==0)
- {
- delay(10);
- if(key3==0)
- {
- beep=0;//蜂鳴器短響一聲
- delay(50);
- beep=1;
- while(!key3);
- switch(key4n)
- {
-
- case 1:afen--;
- if(afen==-1)
- afen=59;
- write_sfm(5,afen);
- temp=(fen)/10*16+(fen)%10;
- write_1302(0x8e,0x00);
- write_1302(0x82,temp);
- write_1302(0x8e,0x80);
- write_1602com(er+6);
- break;
- case 2:ashi--;
- if(ashi==-1)
- ashi=23;
- write_sfm(2,ashi);
- temp=(shi)/10*16+(shi)%10;
- write_1302(0x8e,0x00);
- write_1302(0x84,temp);
- write_1302(0x8e,0x80);
- write_1602com(er+3);
- break;
- }
- }
-
- }
- }
- }
- }
- }
- void timealarm()
- {
- if(shi>7)//大于7點才啟動報時
- {
- if(alarmflag==1)//不按下設置按鍵時才有效
- {
- if(fen==0 && miao<2)
- {
- beep=0;//啟動蜂鳴器
- }
- else if(fen==30 && miao==5)
- {
- beep=0;
- }
- else beep=1;
- }
- }
- }
- void init()
- {
- TMOD=0X01;
- EA=1;
- TH0=(65536-60000)/256;
- TL0=(65536-60000)%256;
- ET0=1;
- TR0=1;
- }
- void nz()
- {
- beep=0;
- delay(500);
- }
- void alarmoff()//按任意鍵關閉鬧鈴函數
- {
- if(flag==1)
- {
- if(key1==0||key2==0||key3==0||key4==0)
- {
- delay(10);
- if(key1==0||key2==0||key3==0||key4==0)
- {
- while(key1==0||key2==0||key3==0||key4==0)
- flag=0;
- lcd_init();
- }
- }
- }
- }
- void main()
- { beep=1;
- alarmflag=1;
- lcd_init();
- flag=0;
- ds1302_init();
- init();
-
- delay(10);
- while(1)
- {
- timealarm();
- settime();
- if(flag==1)
- {
- write_1602com(yh);
- for(a=0;a<16;a++)
- {
- delay(5);
- write_1602dat(tab4[a]);
- }
- write_1602com(er);
- for(a=0;a<16;a++)
- {
- delay(5);
- write_1602dat(tab5[a]);
- }
- }
- else if(flag==0&&key1n==0&&key4n==0)
- {
- miao=BCD_Decimal(read_1302(0x81));
- fen=BCD_Decimal(read_1302(0x83));
- shi=BCD_Decimal(read_1302(0x85));
- ri=BCD_Decimal(read_1302(0x87));
- yue=BCD_Decimal(read_1302(0x89));
- week=BCD_Decimal(read_1302(0x8b));
- nian=BCD_Decimal(read_1302(0x8d));
- write_sfm(8,miao);
- write_sfm(5,fen);
- write_sfm(2,shi);
- write_nyr(9,ri);
- write_nyr(6,yue);
- write_nyr(3,nian);
- write_week(week);
- }
- if((shi==ashi)&&(fen==afen))
- {
- if(0<miao&&miao<2)
- { nz();
- flag=1;
- }
-
- } else flag=0;beep=1;
- setalarm();
- alarmoff();
- }
- }
復制代碼
僅供參考
|