|
|
•它利用單片機(jī)STC89C51作為主控芯片。將家用電壓經(jīng)過穩(wěn)壓電路后,輸入AD芯片,單片機(jī)控制數(shù)字/模擬轉(zhuǎn)換器(PCF8591)的輸出電壓的大小,從而輸出恒定可調(diào)電壓。最后通過電位器分壓將輸出信號(hào)反饋到運(yùn)算放大器(LM358)上,使輸出電壓達(dá)到標(biāo)準(zhǔn),并且還可以進(jìn)行過壓過流檢測(cè),防止電壓過高產(chǎn)生事故。此設(shè)計(jì)通過鍵盤電路與單片機(jī)連接,讀入控制數(shù)據(jù),利用軟件進(jìn)行判斷,從而起到控制電源輸出的作用。通過LCD1602顯示數(shù)控電源的輸出電壓
單片機(jī)源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #define PCF8591_ADDR 0x90 //PCF8591地址
- #define DACOUT_EN 0x40 //DAC輸出使能
- #define uchar unsigned char
- #define uint unsigned int
- int a,b,c,t,s,w=0;
- uint AD_Value; //存儲(chǔ)AD轉(zhuǎn)換回的數(shù)字量
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void delay_5us()
- {
- _nop_();
- }
- void keyscan();
- sbit SDA = P2^0; //I2C串行數(shù)據(jù)
- sbit SCL = P2^1; //I2C串行時(shí)鐘
- sbit dula = P2^6;
- sbit wela = P2^7;
- sbit lcdrs=P3^7;
- sbit rw=P3^6;
- sbit lcden=P3^5;
- void write_com(uchar com)
- {
- lcdrs=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_date(uchar date)
- {
- lcdrs=1;
- P0=date;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void init()
- {
- rw=0;
- dula=0;
- wela=0;
- lcden=0;
- write_com(0x38);
- write_com(0x0c);
- write_com(0x06);
- write_com(0x01);
- }
- /*I2C總線初始化*/
- void I2C_init()
- {
- SDA = 1; //數(shù)據(jù)總線高
- _nop_();
- SCL = 1; //時(shí)鐘總線高
- _nop_();
- }
- /*I2C起始信號(hào)*/
- void I2C_Start()
- {
- SCL = 1;
- _nop_();
- SDA = 1;
- delay_5us();
- SDA = 0;
- delay_5us();
- }
- /*I2C停止信號(hào)*/
- void I2C_Stop()
- {
- SDA = 0;
- _nop_();
- SCL = 1;
- delay_5us();
- SDA = 1;
- delay_5us();
- }
- /*I2C主機(jī)發(fā)送應(yīng)答
- i為0時(shí)發(fā)送非應(yīng)答 為1時(shí)發(fā)送應(yīng)答*/
- void Master_ACK(bit i)
- {
- SCL = 0; // 拉低時(shí)鐘總線允許SDA數(shù)據(jù)總線上的數(shù)據(jù)變化
- _nop_(); // 讓總線穩(wěn)定
- if (i) //如果i = 1 那么拉低數(shù)據(jù)總線 表示主機(jī)應(yīng)答
- {
- SDA = 0;
- }
- else
- {
- SDA = 1; //發(fā)送非應(yīng)答
- }
- _nop_();//讓總線穩(wěn)定
- SCL = 1;//拉高時(shí)鐘總線 讓從機(jī)從SDA線上讀走 主機(jī)的應(yīng)答信號(hào)
- _nop_();
- SCL = 0;//拉低時(shí)鐘總線, 占用總線繼續(xù)通信
- _nop_();
- SDA = 1;//釋放SDA數(shù)據(jù)總線。
- _nop_();
- }
- /*I2C檢測(cè)從機(jī)應(yīng)答
- 0為非應(yīng)答 1為應(yīng)答*/
- bit Test_ACK() // 檢測(cè)從機(jī)應(yīng)答
- {
- SCL = 1;//時(shí)鐘總線為高電平期間可以讀取從機(jī)應(yīng)答信號(hào)
- delay_5us();
- if (SDA)
- {
- SCL = 0;
- I2C_Stop();
- return(0);
- }
- else
- {
- SCL = 0;
- return(1);
- }
- }
- /*I2C發(fā)送一個(gè)字節(jié)
- byte 要發(fā)送的字節(jié)*/
- void I2C_send_byte(uchar byte)
- {
- uchar i;
- for(i = 0 ; i < 8 ; i++)
- {
- SCL = 0;
- _nop_();
- if (byte & 0x80)
- {
- SDA = 1;
- _nop_();
- }
- else
- {
- SDA = 0;
- _nop_();
- }
- SCL = 1;
- _nop_();
- byte <<= 1;
- }
- SCL = 0;
- _nop_();
- SDA = 1;
- _nop_();
- }
- /*I2C讀一個(gè)字節(jié)
- 讀取的字節(jié)*/
- uchar I2C_read_byte()
- {
- uchar i, dat;
- SCL = 0 ;
- _nop_();
- SDA = 1;
- _nop_();
- for(i = 0 ; i < 8 ; i++)
- {
- SCL = 1;
- _nop_();
- dat <<= 1;
- if (SDA)
- {
- dat |= 0x01;
- }
- _nop_();
- SCL = 0;
- _nop_();
- }
- return(dat);
- }
- /*DAC輸出*/
- bit DAC_OUT(uchar DAT)
- {
- I2C_Start();
- I2C_send_byte(PCF8591_ADDR+0);
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_send_byte(DACOUT_EN); //DA輸出使能
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_send_byte(DAT);
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_Stop();
- return(1);
- }
- /*讀AD數(shù)據(jù)*/
- bit ADC_Read(uchar CON)
- {
- I2C_Start();
- I2C_send_byte(PCF8591_ADDR+0);
- if (!Test_ACK())
- {
- return(0);
- }
- I2C_send_byte(CON);
- Master_ACK(0);
- I2C_Start();
- I2C_send_byte(PCF8591_ADDR+1);
- if (!Test_ACK())
- {
- return(0);
- }
- AD_Value = I2C_read_byte();
- Master_ACK(0);
- I2C_Stop();
- return(1);
- }
- void main()
- {
- init();
- I2C_init();
- while(1)
- {
- ADC_Read(0x43);//外部
- keyscan();
- DAC_OUT((double)s/3*5.12);
- }
-
- }
- void keyscan()
- {
- P1=0xfe;
- t=P1;
- t=t&0xf0;
- while(t!=0xf0)
- {
- delay(5);
- t=P1;
- t=t&0xf0;
- while(t!=0xf0)
- {
- t=P1;
- switch(t)
- {
- case 0xee:a=0,w=0;break;
- case 0xde:a=1,w=0;break;
- case 0xbe:a=2,w=0;break;
- case 0x7e:a=3,w=0;break;
- }
- while(t!=0xf0)
- {
- t=P1;
- t=t&0xf0;
- }
- }
- }
- P1=0xfd;
- t=P1;
- t=t&0xf0;
- while(t!=0xf0)
- {
- delay(5);
- t=P1;
- t=t&0xf0;
- while(t!=0xf0)
- {
- t=P1;
- switch(t)
- {
- case 0xed:a=4,w=0;break;
- case 0xdd:a=5,w=0;break;
- case 0xbd:a=6,w=0;break;
- case 0x7d:a=7,w=0;break;
- }
- while(t!=0xf0)
- {
- t=P1;
- t=t&0xf0;
- }
- }
- }
- P1=0xfb;
- t=P1;
- t=t&0xf0;
- while(t!=0xf0)
- {
- delay(5);
- t=P1;
- t=t&0xf0;
- while(t!=0xf0)
- {
- t=P1;
- switch(t)
- {
- case 0xeb:a=8,w=0;break;
- case 0xdb:a=9,w=0;break;
- case 0xbb:b=a*10,w=0;break;
- case 0x7b:c=a,w=0;break;
- }
- while(t!=0xf0)
- {
- t=P1;
- t=t&0xf0;
- }
- }
- }
- P1=0xf7;
- t=P1;
- t=t&0xf0;
- while(t!=0xf0)
- {
- delay(5);
- t=P1;
- t=t&0xf0;
- while(t!=0xf0)
- {
- t=P1;
- switch(t)
- {
- case 0xe7:s=s+1,w=1;break;
- case 0xd7:s=s-1,w=2;break;
- }
- while(t!=0xf0)
- {
- t=P1;
- t=t&0xf0;
- }
- }
- }
- if(w==0)
- {
- s=b+c;
- write_com(0x80);
- write_date('D');
- write_date('C');
- write_date(':');
- write_date(s/10+0x30);
- write_date('.');
- write_date(s%10+0x30);
- write_date(0+0x30);
- write_date('V');
- }
- if(w==1)
- {
- if(s>99)
- {
- s=0;
- }
- write_com(0x80);
- write_date('D');
- write_date('C');
- write_date(':');
- write_date(s/10+0x30);
- write_date('.');
- write_date(s%10+0x30);
- write_date(0+0x30);
- write_date('V');
- }
- if(w==2)
- {
- if(s<0)
- {
- s=99;
- }
- write_com(0x80);
- write_date('D');
- write_date('C');
- write_date(':');
- write_date(s/10+0x30);
- write_date('.');
- write_date(s%10+0x30);
- write_date(0+0x30);
- write_date('V');
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
終極電源程序.rar
(34.42 KB, 下載次數(shù): 28)
2018-6-22 16:11 上傳
點(diǎn)擊文件名下載附件
穩(wěn)壓電源的控制程序 下載積分: 黑幣 -5
|
|