根据51hei论坛上的图纸原理做的可调电源实测0.2v-11.5v可调,步进0.1v。本程序没有用查表方式给tlc5615输入AD值(费时间,懒。。。),所以输入电压与输出电压有误差。
源图纸用的是89c51单片机,本人用的15w408as单片机,自带AD功能,可以将输出的电压返回单片机处理。显示部分没有用数码管,感觉没有OLED连线方便(IIC接口)
原理图用的OPA2107运放,我买了两个这个运放不能用,不知道我买的是坏的还是本身这个电路有问题,后面改用LM358可以正常使用。此电路我用两个LM358,其中一个用来放大检测电流电阻上的电压,再输入到单片机的AD脚进行计算处理。
此电路有电流检测功能,但是程序里没有设置短路保护功能。
实际做下来也不费劲,但是这个图纸经我验证有以下缺点:
1,电流只能达到600ma,再高场效应管发热严重,输入功率能达到40w而输出功率只有5-8w。
2,效率不高,感觉效率能有50%就很不错了,而且电流过大造成场馆有异响。
3,调电压的时候测量TL431的基准电压2.5v,这个电压数值会随着电压的调节略微变动,造成输出误差增大。给单片机的基准电压我用的是ASM1117的 3.3v做基准电压,感觉这个芯片的稳压要比TL431好。
本人也就是普通的爱好者,一些东西还是靠论坛来实现的。有什么不对的地方希望指点一下。
制作出来的实物图如下:
电路原理图如下:
单片机源程序如下:
- #include <STC15F2K60S2.H>
- #include "OLED.h"
- #include "TLC5615.h"
- #include "EC11.h"
- #define ADC_POWER 0x80
- #define ADC_FLAG 0x10
- #define ADC_START 0x08
- #define ADC_SPEEDLL 0x00
- #define ADC_SPEEDL 0x20
- #define ADC_SPEEDH 0x40
- #define ADC_SPEEDHH 0x60
- unsigned int EC11_Value1;
- unsigned char ch=2; //定义通道0位P1^0;1为P1^1;2为P1^2;
- float voltage=0, voltage1=0; //??????
- unsigned int Power1,ElectricC,RefAd=0,vin=0,PowerA=0,Wat=0;//P1^0,Power为电压值,P1^2,refad为参考电压3.3v的ad值.P1^1为采样AD值
- /******************显示函数**********************/
- void OLEDDisplay()
- {
- //设定电压值
-
- OLED_DisplayCharacter(1, 9, (PowerSet+1)/100+'0', OLED_NOT_INVERT_COLOR);
- OLED_DisplayCharacter(1, 10, (PowerSet+1)%100/10+'0', OLED_NOT_INVERT_COLOR);
- OLED_DisplayCharacter(1, 12, (PowerSet+1)%10+'0', OLED_NOT_INVERT_COLOR);
- //显示电压值
- OLED_DisplayCharacter(2, 9, Power1/1000+'0', OLED_NOT_INVERT_COLOR);
- OLED_DisplayCharacter(2, 10, Power1%1000/100+'0', OLED_NOT_INVERT_COLOR);
- OLED_DisplayCharacter(2, 12, Power1%100/10+'0', OLED_NOT_INVERT_COLOR);
- OLED_DisplayCharacter(2, 13, Power1%100%10+'0', OLED_NOT_INVERT_COLOR);
- //显示电流值
- OLED_DisplayCharacter(3, 10, ElectricC/1000+'0', OLED_NOT_INVERT_COLOR);
- OLED_DisplayCharacter(3, 12, ElectricC%1000/100+'0', OLED_NOT_INVERT_COLOR);
- OLED_DisplayCharacter(3, 13, ElectricC%100/10+'0', OLED_NOT_INVERT_COLOR);
- // //显示编码器值
- // OLED_DisplayCharacter(3, 6, EC11_Value/1000+'0', OLED_NOT_INVERT_COLOR);
- // OLED_DisplayCharacter(3, 7, EC11_Value%1000/100+'0', OLED_NOT_INVERT_COLOR);
- // OLED_DisplayCharacter(3, 8, EC11_Value%100/10+'0', OLED_NOT_INVERT_COLOR);
- // OLED_DisplayCharacter(3, 9, EC11_Value%10+'0', OLED_NOT_INVERT_COLOR);
- // OLED_DisplayCharacter(3, 11, KeyNumber+'0', OLED_NOT_INVERT_COLOR);
- }
- /**********************主函数*******************************/
- void main()
- {
- unsigned int i;
- OLED_Init();//初始化OLED
- P1ASF=0x07;//0x70=00000111,用P1^0,1^1,1^2三个IO口当ADC口
- ADC_RES=0;
- ADC_CONTR=ADC_POWER|ADC_SPEEDLL | ADC_START | ch;
- for(i=0;i<1000;i++);
- IE=0xA0;
- EC11_Value1=EC11_Value;
- while(1)
- {
- OLEDDisplay(); //扫描显示函数
-
- if(KeyNumber==1)
- {
- OLED_DisplayText(0, 6, "开", OLED_NOT_INVERT_COLOR);
- if(EC11_Value!=EC11_Value1)
- TLC5615DateOut(EC11_Value);
- EC11_Value1=EC11_Value;
- }
- else
- {
- OLED_DisplayText(0, 6, "关", OLED_NOT_INVERT_COLOR);
- TLC5615DateOut(0);
- }
- }
-
-
- }
- /****************************ADC中断函数***********************/
- void adc_int() interrupt 5 //ADC中断
- {
- static unsigned char i;
- unsigned int j=0;
- EC11_Display(); //扫描编码器函数
- ADC_CONTR &=!ADC_FLAG;//清除中断
- if(ch==0)
- {
- RefAd=(ADC_RES*4+ADC_RESL); //P1^2的参考AD值保存到RefAD中,这里用ASM1117的3.3v稳压做参考AD值
- }
- if(ch==1)
- {
- vin=(ADC_RES*4+ADC_RESL); //读取P1^1的值保存在vin中,这里读到的是输出电压经10K电阻分压得到的电压值。
- voltage1=(3.318*vin)/RefAd;
- Power1=voltage1*1000;
- }
- if(ch==2) //读取P1^0的AD值保存在PowerAD中,计算经运放过来的放大电压,算出电流
- {
- PowerA=(ADC_RES*4+ADC_RESL);
- voltage=(3.318*PowerA)/RefAd;
- ElectricC=voltage*200;
- }
- ch=i;
- i++;
- if(i==10)i=0;//防止AD值过快有跳动
- ADC_RES=0;
- ADC_RESL=0; //AD数据位清零
- ADC_CONTR=ADC_POWER |ADC_SPEEDLL | ADC_START | ch; //启动ADC中断
-
- }
复制代码
所有代码51hei提供下载:
OLED显示数字电压.zip
(90.92 KB, 下载次数: 142)
|