
水平有限,画电压表电路图有压力,有机会尽量补上
发出来给新手看一下,写了一下制作过程中遇到的一些问题,有些错误的地方请大家提出来
电源参数:
可调电压范围±0.02V~±20V
纹波<1mV
0-7V输出1A电流
7-12V输出0.5A电流
(变压器功率20W)
电压表参数:
测量范围0~±20V
正电压误差<0.1V
负电压误差<0.08V (我比较懒,这个误差还可以调下程序缩小的,但是第一个小电压表把我折腾的够呛的,所以电路焊好之后,程序大致上那样就没管它了)
(因没有电子负载,用5V直流电机和12V直流电机作负载测试最大电流,7V时最大输出1A电流,12V时最大输出0.5A电流,电流超过此标准输出电压mv级减小。分析原因:变压器功率不足,散热片散热能力不够。)
电路图采用的是LM317和LM337基本应用电路,稍微作了一些修改。由于LM317的基准电压是1.25V,输出电压下限为1.25V,所以需要在它的输出接地端需要外加一个-1.25V的电压来抵消它的基准电压,从而实现输出0V起调;LM337同理,在电位器和地之间接一个1.25V的电压来抵消-1.25V,这里使用了2个1.235V的电压基准,就是图中的LM385-1.2,与之串联的电阻和LED分别用来限流和做指示灯。关于电容的选择,104用来减少高频干扰,焊接电路时离稳压片输入端越近越好;4.7uf的小电容用来稳定稳压片的工作;2200uf大电容,用来滤低频波,使输出电压平滑稳定,如果需要输出大电流需要加大电容容量,并加大功率三极管扩大输出电流。
关于数码管电压实时显示,使用的是STC15F204EA单片机(单片机自带8通道10位AD转换功能),电压表供电由该电源提供,使用LM7815和LM7815稳压给运放供电,使用LM7805稳压给单片机供电;考虑到成本,使用单片机自带AD功能。关于单片机外围电路,因为此单片机只能采样不超过他的工作电压的电压,单片机正电压采样电路用电阻分压来扩大它的测量范围,为了提高精度,当采样电压小于4.1V时自动切换AD通道由单片机直接采样;负电压的采样,用的是反相比例运算电路,放大倍数为0.209倍,所测电压经反相运算放大后再送到单片机I/O口。电压基准使用的是TL431,电压为2.5V。数码管显示部分,带有小数点自动切换功能,数码管位选由单片机控制138译码器实现,段选直接由单片机I/O口控制。
实际制作这个电压表的时候,开始是先做了一个简易的只能测量正电压的电压表,熟悉了AD转换之后,又开始做双显示正负电压的电压表,制作过程中,遇到很多问题,也学到了很多。数码管显示暗淡,需要外加驱动电路,后来在芯片手册里看到STC15F204EA带有强推挽输出,所以就在程序里设置了I/O推挽的输出,免去了数码管驱动电路;然后就是数码管消隐,刚开始做的时候显示的数字很不清晰,然后在网上看了一些关于数码管消隐的例程,知道了消隐的原理之后,修改程序把显示部分做好了;还有就是运放的使用,刚开始做的时候,使用的是一般的音频运放,运放工作很不稳定,无法稳定输出,在论坛问了一些网友,按他们推荐的去买了个仪表用运放,然后把电路板上的运放电路那块拆了,重新焊上新运放,焊好之后,用电压表测量,0输入的时候饱和输出,就是一直输出最大电压VCC,不知道什么原因,又去网上看一些运放电路的知识,偶然看到了运放供电需要加去耦电容,然后尝试着在供电两端各加了一个10uf电容,再测输出,为零点几毫伏了,然后调节调0电阻,使输出为0,给运放加上输入信号,慢慢调节输入电压,和运算电路输出电压比较,放大倍数一直是0.209很稳定,运放工作正常。
下面是制作过程中的拍的几张图片
电源

第一次做的电压表。。。。


两个数码管洞洞板不好焊,只能这样先处理数码管


万用表只有一个。。。所以那个小电压表也上场了


[font='宋体']


秀秀我的书桌,工具不多,暂时够用了~~


[电压表程序,自己胡乱写的,哪位高手能帮忙改一下,提高一下效率
- #include<stc15f204ea.h>
 - #include<intrins.h>
 - #define ADC_POWER 0x80 //ADC 电源控制位
 - #define ADC_FLAG 0x10 //ADC 完成标志
 - #define ADC_START 0x08 //ADC 启动控制位
 - #define ADC_speed_LL 0x00 //540 时钟
 - #define ADC_speed_L 0x20 //360 时钟
 - #define ADC_speed_H 0x40 //180 时钟
 - #define ADC_speed_HH 0x60 // 90 时钟
 - typedef unsigned long ul;
 - void delay(unsigned int x); //函数声明
 - void LCD_one(ul LedNumVal); //函数声明
 - void LCD_two(ul LedNumVal); //函数声明
 - void Delay1ms(); //函数声明
 - void Delay150us(); //函数声明
 - void AD_Init(); //函数声明
 - ul ADC(unsigned char m); //函数声明
 - void Delay200us(); //函数声明
 - unsigned char code Disp_Tab[] = {0xd7,0x11,0xcd,0x5d,0x1b,0x5e,0xde,0x15,0xdf,0x5f}; // 数组 0-9
 - unsigned char code dispbit[8]={0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0}; // 位选控制 8位
 - /************主函数**********************/
 - void main()
 - {
 - ul V1,V2,Int_V1,Int_V2,Int_V1S,Int_V2S,Vcc, Vcc_S;
 - unsigned char m,M;
 - P3M1=0x00;
 - P3M0=0xff; //设置P3口强推挽输出
 - AD_Init(); //AD初始化
 - M=1;
 - while(1)
 - {
 - Int_V1S=0;
 - Int_V2S=0;
 - Vcc_S=0;
 - m=0;
 - if(M==0)
 - {
 - for(m;m<10;m++)
 - {
 - Delay200us(); //采样电压等待时间
 - Int_V1S += ADC(6);
 - Delay200us();
 - Int_V2S += ADC(3);
 - Delay200us();
 - Vcc_S += ADC(7);
 - Int_V1 = Int_V1S/10;
 - Int_V2 = Int_V2S/10;
 - Vcc = Vcc_S/10; //采样10次电压求平均值
 - }
 - V1=2500*Int_V1/Vcc;
 - V2=25*488*Int_V2/Vcc;
 - LCD_one(V1); //电压显示
 - LCD_two(V2);
 - if(2500*Int_V1/Vcc>4000)M=1;
 - }
 - if(M==1) //这里的if语句实现量程转换 M==0时ADC通道6-P1.6直接采样电压
 - { // M==1时ADC通道4-P1.4采样电阻分压后的电压
 - for(m;m<10;m++)
 - {
 - Delay200us(); //采样电压等待时间
 - Int_V1S += ADC(4);
 - Delay200us();
 - Int_V2S += ADC(3);
 - Delay200us();
 - Vcc_S += ADC(7);
 - Int_V1 = Int_V1S/10;
 - Int_V2 = Int_V2S/10;
 - Vcc = Vcc_S/10; //采样10次电压求平均值
 - }
 - V1=2500*5*Int_V1/Vcc;
 - V2=25*488*Int_V2/Vcc;
 - LCD_one(V1); //电压显示
 - LCD_two(V2);
 - if(25*496*Int_V1/Vcc<4000) M=0;
 - }
 - }
 - }
 - /*******数码管显示函数*************/
 - void LCD_one(ul LedNumVal)
 - {
 - unsigned int LedOut[4]; //变量定义
 - if(LedNumVal>9999)
 - {
 - LedOut[0]=Disp_Tab[LedNumVal%100000/10000]; // 千位
 - LedOut[1]=Disp_Tab[LedNumVal%10000/1000]|0x20; // 百位
 - LedOut[2]=Disp_Tab[LedNumVal%1000/100]; // 十位
 - LedOut[3]=Disp_Tab[LedNumVal%100/10]; // 个位
 - }
 - if(LedNumVal<10000)
 - {
 - LedOut[0]=Disp_Tab[LedNumVal%10000/1000]|0x20; // 千位
 - LedOut[1]=Disp_Tab[LedNumVal%1000/100]; // 百位
 - LedOut[2]=Disp_Tab[LedNumVal%100/10]; // 十位
 - LedOut[3]=Disp_Tab[LedNumVal%10]; // 个位
 - } // if语句 实现 小数点自动切换
 - P3=LedOut[3];
 - P2=dispbit[0];
 - P10=1;
 - delay(500);
 - P10=0;
 - P3=LedOut[2];
 - P2=dispbit[1];
 - P10=1;
 - delay(500);
 - P10=0;
 - P3=LedOut[1];
 - P2=dispbit[2];
 - P10=1;
 - delay(500);
 - P10=0;
 - P3=LedOut[0];
 - P2=dispbit[3];
 - P10=1;
 - delay(500);
 - P10=0;
 - }
 - void LCD_two(ul LedNumVal)
 - {
 - unsigned int LedOut[4]; //变量定义
 - if(LedNumVal>9999)
 - {
 - LedOut[0]=0x08; //显示负号
 - LedOut[1]=Disp_Tab[LedNumVal%100000/10000];
 - LedOut[2]=Disp_Tab[LedNumVal%10000/1000]|0x20;
 - LedOut[3]=Disp_Tab[LedNumVal%1000/100];
 - }
 - if(LedNumVal<10000)
 - {
 - LedOut[0]=0x08;
 - LedOut[1]=Disp_Tab[LedNumVal%10000/1000]|0x20;
 - LedOut[2]=Disp_Tab[LedNumVal%1000/100];
 - LedOut[3]=Disp_Tab[LedNumVal%100/10];
 - } // if语句 实现 小数点自动切换
 - P3=LedOut[3];
 - P2=dispbit[4];
 - P10=1;
 - delay(500);
 - P10=0;
 - P3=LedOut[2];
 - P2=dispbit[5];
 - P10=1;
 - delay(500);
 - P10=0;
 - P3=LedOut[1];
 - P2=dispbit[6];
 - P10=1;
 - delay(500);
 - P10=0;
 - P3=LedOut[0];
 - P2=dispbit[7];
 - P10=1;
 - delay(500);
 - P10=0;
 - }
 - /***********AD初始化***************/
 - void AD_Init()
 - {
 - P1M1=0xfe;
 - P1M0=0x08; //设置高阻和开漏,ADC采样运放输出端电压时需要断开相应I/O口内部上拉,即开漏输入
 - ADC_RES=0x00;
 - ADC_RESL=0x00;
 - P1ASF=0xfe;
 - ADC_CONTR=ADC_POWER|ADC_speed_LL;
 - Delay1ms();
 - }
 - /*********电压采样*********/
 - ul ADC(unsigned char m)
 - {
 - if(m==3)
 - {
 - ADC_CONTR &=0xf8; //清空通道
 - ADC_CONTR |=0x03; //更换通道
 - Delay150us(); //更换通道延时
 - }
 - if(m==4)
 - {
 - ADC_CONTR &=0xf8;
 - ADC_CONTR |=0x04;
 - Delay150us();
 - }
 - if(m==6)
 - {
 - ADC_CONTR &=0xf8;
 - ADC_CONTR |=0x06;
 - Delay150us();
 - }
 - if(m==7)
 - {
 - ADC_CONTR &=0xf8;
 - ADC_CONTR |=0x07;
 - Delay150us();
 - }
 - ADC_CONTR |=ADC_START; //开启AD转换
 - _nop_();
 - _nop_();
 - _nop_();
 - _nop_();
 - while(!(ADC_CONTR & 0x10));
 - ADC_CONTR &= ~ADC_FLAG;
 - ADC_RES = (ADC_RES<<2)|ADC_RESL; //高八位按位左移2位与低两位结果按位或运算得到10位转换结果
 - return ADC_RES; //返回10位AD转换结果
 - }
 - /*******************延时函数**********/
 - void delay(unsigned int x)
 - {
 - char j;
 - for(x; x> 0; x--)
 - for(j = 400; j > 0; j--);
 - }
 - void Delay1ms() //@12.000MHz
 - {
 - unsigned char i, j;
 - i = 2;
 - j = 239;
 - do
 - {
 - while (--j);
 - } while (--i);
 - }
 - void Delay150us() //@12.000MHz
 - {
 - unsigned char i, j;
 - i = 2;
 - j = 189;
 - do
 - {
 - while (--j);
 - } while (--i);
 - }
 - void Delay200us() //@12.000MHz
 - {
 - unsigned char i;
 - _nop_();
 - i = 97;
 - while (--i);
 - }
 
			
			
			
						
			
 我要赚赏金
