一乐电子

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 15644|回复: 19

[其他综合] 看高人自制6位半电压表头

  [复制链接]
发表于 2012-3-4 19:52 | 显示全部楼层 |阅读模式
本帖最后由 gmliwei 于 2012-3-4 19:55 编辑

【转自两个论坛的文章】

LTC2400芯片,我试验了。
经过连续6天的测试,非线性的变化稳稳的保持在10ppm左右,总偏移小于1ppm,这几天的总温差约5至10度。调试电路时,经常焊接电路板,电路板反反复复的升温降温几十度,也未见因此而发生芯片老化。也就是说,经过非线性改正后,非线性误差小于1ppm。更有趣的是,它的非线性误差接于抛物线,所以只需做抛物线插值,就可以使非线误差减小到1ppm

LTC2400六位表头设计安装调试

    该电路制作之后,已连续上机测试6天,稳定性良好。于是,今天把非线性改正程序及菜单功能全部加进去,使之变成完整的表头。
    1、LTC2400的电源采用5V独立供电。数据手册给的测试电路,电源与基准共用,我上机实测效果不好。共电方案,造成自检值偏小数百个字。共电时,滤波电容越大,自检值越大,使用0.4uF比0.3uF,会增加100字左右,但还是很难达到5000,000字。当电路对电容敏感,电路稳定性稍差。所以本电路采用78L05对LTC2400独立供电,自检值接近5000,000字。所谓“自检”指的是将表笔输入端接到LTC2400的Vref端。

    2、78L05接了一个1.5k的负载,其作用是:当LTC2400输入电压过高,输入电流通过内部的输入限幅二极管倒灌进78L05,会靠成LTC2400供电电压抬升。接了1.5k负载,以防输入电压抬升过多。

    3、OP07运放输出加了一个2k限流的电阻,防止对LTC2400输入过强电流、电压。

    4、缓冲设计:LTC2400的Vin端输入阻抗很低,而且是非线性的,这是内部开关电容造成的。当输入信号为0V时Vin会有平均电流输出,约0.5uA至1uA,当输入为2.5Vref时,平均电流最小,当输入为等于Vref时Vin会有0.5uA至1uA平均电流流入。这种非稳恒的平均电流,在外部输入电阻上形成压降,会造成严重非线性的误差。为此,本电路采用OP07进行缓冲放大,得到低频段极低输出电阻,驱动LTC2400,消除输入非线性。

    5、LTC2400的信号输入端的0.22u电容的作用:LTC2400内部开关电容,会在输入端形成脉冲电压、电流,频率很高。加入这个电容后,输入端的脉冲电压基本消失,确保内部输入电容得到快速充电,提高AD的稳定性。由于OP07在高频段,输出电阻很大,因此加入了这个0.22u滤波电容后,在全频段内,得到了低阻抗缓冲输出,缓冲器的增益几乎为1,不易受其它不确定因素影响。该电容还可以减小高频干扰。

    6、与LTC2400连接的电容,使用CBB,有的使用独石,以得到稳定的容量、较低的噪声。试验过程中,曾更换为耐高温的高容量的电脑主板上用的贴片电容,噪声非常大,AD转换非常不稳定,这种电容的温漂非常巨大,决不可用于这个AD转换电路。

    7、7905输出接了一个2k的电阻:op07的工作电流很小,7905不能正常工作,所以接了一个负载。如果使用79L05,估计不接上电阻也能工作。

    8、调零后的自检值,应在5000,000字左右,正负误差几十字不要紧。如果小了几百字,可能是电容失效,或不能工作于高频。如果大了几百字,可能存在严重的电容噪声。

    9、菜单使用方法:
1)K1键,切换换菜单,每按一次,会在菜单0、1、2、3、4、5之间切换。
2)菜单0是默认菜单,显示已进行非线性矫正的AD转换结果。在菜单0下,按下K2键,显示未矫正的AD转换结果(将自动在最后一位加上一个小数点,以示区别)。再次按K2,则显示已矫正的结果。
3)菜单1设置零点偏移字数;菜单2设置中点非线性误差;
4)菜单3设置满量程字数的低4位;菜单4设置满量程字数的高3位
5)菜单5,设置滤波器步长。如:设置为8,约为8点平均。如果被置为负数并保存,下次开机时所有参数将被复位
6)在菜单1至5中,K2是光标移动键,K3是保存键,K4是更改键。光标移动到第6位,更改正负号。第7位显示菜单号。


    10、零点偏移的测量:将表笔短路得到的读数V0,并把V0保存到菜单1

    11、中点非线性误差的测定:
    在被测基准中,有4个分压电阻。R1、R2看作下臂电阻,R3、R4看作上臂电阻。设下臂电阻的压降为V1,上臂电阻的压降为V2,总电压为Va
如果表头线性度理想,存在关系式Va = V1+V2,如果不理想,中点非线性误差为a = (V1+V2-Va)/2
测定非线性误差a时,把表头置为无矫正模式(按下K2键)。
无矫正模式,是未调零的,所以测量Va、V1、V2时,应做零点偏移改正。设零点为读数为V0,那么就有 a = (V1+V2+V0-Va)/2。将夹子接在“0分压”与“2分压”得到V1,将夹子接在“2分压”与“4分压”得到V2,将夹子接在“0分压”与“4分压”得到Va。
由于OP07的输入电流不可忽略,所以也须改正。OP07的输入电流比较容易测得,分别测量“分压4”端子和“内阻测量端子”的电压,得一两个电压的差值,再把差值除以100,就得到了OP07的输入电流,单位是nA。若测得的输入电流是I纳安,那么所需的改正值是Vr = (1.5+1-0.5)*I = 2I,比如,测得I=3.5nA,那么Vr = 2*3.5 = 7
最后,a = (V1+V2-Va+V0+Vr)/2,然后把a值保存到菜单2即可。
如果觉得OP07输入阻抗低,可以试试OP177

    12、测试注意事项
    1)预热20分钟,测量期间,尽量减小空气流动或电路板移动,以免造成温度不稳定。OP07需要较长时间预热才会稳定下来。
    2)夹子不能用手切换,而应使用镊子操作。5个排针及2个夹子全应等温度才行。否则会产生几个uV的热电势,影响测量精度。
    3)在菜单设置了零点偏移参数,可以大大减小偏移,读取电压时,通常无需减去零点值。如果要求测量特别精确,最好将表笔短路,测出零点偏移量,然后在测量结果中减去该偏移值。


3DQ输出的信号比较小,不好测定,所以买了4位半表头,可测定10uV。
6 L6 S& H1 a4 i1 t/ u所以就想,能不能做个字数更多的。看到大店washu用TLC2400制作,故决定制作。经测试,这个芯片效果不错。
经过4天的监视,得到如下结果
非线性误差监测记录(程序矫正前)                                                               时间        总电压        下臂电压        上臂电压        短路电压        内压降        中点误差        相对误差(ppm)        备注+ i2 S: L) l, \/ n5 H  O3 H' `" w
7.15日07点        4998973        2497456        2501362        -41        3.7        -53.3        -10.7         电路1
7.15日12点        4998921        2497438        2501331        -40        3.7        -52.3        -10.5         电路1
7.15日13点        4998890        2497424        2501317        -44        3.4        -49.1        -9.8          电路1
7.15日14点        4998878        2497416        2501305        -43        3.4        -53.6        -10.7         电路2
7.15日15点        4998878        2497420        2501306        -40        3.4        -52.6        -10.5         电路2
7.15日16点        4998875        2497417        2501309        -41        3.4        -50.6        -10.1         电路2
7.15日19点        4998855        2497412        2501294        -41        3.4        -50.6        -10.1         电路2
7.15日21点        4998850        2497408        2501292        -40        3.4        -51.6        -10.3         电路2
7.16日06点        4998970        2497455        2501364        -41        3.5        -51.5        -10.3         电路2
7.16日07点        4998950        2497450        2501350        -41        3.5        -51        -10.2         电路2
7.16日08点        4998912        2497437        2501328        -41        3.5        -49.5        -9.9         电路2
7.16日12点        4998873        2497418        2501305        -41        3.5        -51        -10.2         电路2
7.16日14点        4998855        2497412        2501294        -41        3.5        -50.5        -10.1         电路2
7.16日15点        4998850        2497408        2501294        -41        3.5        -50        -10.0         电路2
7.16日17点        4998844        2497406        2501290        -41        3.5        -50        -10.0         电路2
7.16日20点        4998833        2497400        2501282        -41        3.5        -51.5        -10.3         电路2
7.16日21点        4998828        2497400        2501279        -41        3.5        -50.5        -10.1         电路2
7.19日07点        4999715        2497863        2501705        -40        3.5        -50        -10.0         电路3.

说明:                                                               
表中的内压降指被测电压信号的内阻引起的压降对本次测定影响的字数。                                                               
对于电路3,使用了“线性度测试基准源(二)”,测上臂电压时内阻1.5k,测下臂时内阻1k,测总电压时内阻0.5k,每纳安运放偏流引起误差为(1.5+1-0.5)/2=1字      
7.15日14点,AD电路板上对运放加限流,电路板被烙铁加热后,未完全复恢,所以此刻测值误差偏大一些。
7.19日07点,更换被测基准电路板。                                                               
7.17日、18日,也做了测试,但没有记录在Excel中,测值与上表差不多                                                               
非线性误差监测记录(程序矫正后)                                                               
时间        总电压        下臂电压        上臂电压        短路电压        内压降        中点误差        相对误差(ppm)        备注
7.19日16点        4999654        2497904        2501743        0        3.5        0        0.0         电路3
7.19日17点        4999667        2497910        2501750        0        3.5        0        0.0         电路3
7.19日20点        4999607        2497885        2501713        -2        3.5        0        0.0         电路3
                                                               
说明:                                                               
7.19日16点,具体时间没有记录,孩子吵闹,没有及时记录时间                                                               
修正后,三次测量均得到0ppm误差,不排除偶然因素。                                                               
                                                               
                                                            
下臂非线性误差监测记录(程序矫正后)                                                               
时间        总电压        下臂电压        上臂电压        短路电压        内压降        中点误差        相对误差(ppm)        备注
7.19日19点        2497883        1251452        1246431        -2        0.9        1.9        0.8         电路3
7.19日20点        2497881        1251449        1246429        -2        0.9        0.4        0.2         电路3
测试结果表明,非线性度很稳定,所以软件改正后,非线性误差几乎为零。

  夹子热电势:
被测基准的5个接点使用同种材料,即镀金排针。尽量使5们接点等温度。 测量时不得用手接触夹子,否则夹子被手加热,读值会偏差几个微伏。 切换夹点时,务必使用镊子控制夹子,不得用手,否则得不到正确值。

两个夹子及导线使用同种材料
电路中的滤波电容,对电路稳定工作起到一定的帮助作用。尽量使用容量稳定的电容。容量不稳的电容,噪声会比较大。
没有必要过份加大滤波电容。信号的干扰主要是0.1至3Hz的低频信号,加大电容,根本无法解决问题的。要防止电容本生产低频噪声。低频噪声主要通过软件滤波得到解决。
这个6位半表头,最后一位存在小量跳动,不是很稳定,摆幅约1至3个字。3位半或4位半万用表的最后一字摆幅约为1个字,甚至不跳动。但考虑到4位半万用表,很多只测到10uV,而本表是1uV,所以摆动一些,并不表明它的噪声比4位半表头差。
uV级的低频噪声,与AD586、运放、干扰等因素均有一定的关系。高频噪声可能也会有些影响,但影响有多大,目前还没有测试,今后抽控测试一次。字数、线性度,已经达到了很高的性能。这不是4位半表头可比的。
OP07的阻抗偏低一些。从数据手册看,OP07的升级版OP177阻抗高,但我还没有试验。
我的OP07是0.9元一个,所以指标不是很高,与PDF比对,有点擦边,没有达到典型值。

原理图:
LTC2400六位半表头.png
源程序:
/*************************************
6位半LTC2400驱动程序
xjw01 于莆田 2011.7
**************************************/
//====================================
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#include <reg52.h>
#include <math.h>
void delay(uint loop) { uint i; for(i=0;i<loop;i++); } //延时函数
//void delay2(uint k){ for(;k>0;k--) delay(10000); } //长延时,k=100大约对应1秒

//============================EEPROW偏程=========================
sfr IAP_data = 0xC2;
sfr IAP_addrH = 0xC3;
sfr IAP_addrL = 0xC4;
sfr IAP_cmd = 0xC5;
sfr IAP_trig = 0xC6;
sfr IAP_contr = 0xC7;
/********************
写字节时,可以将原有数据中的1改为0,无法将0改为1,只能使用擦除命令将0改为1
应注意,擦除命令会将整个扇区擦除
*********************/
uchar readEEP(uint k){ //读取
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
IAP_cmd = 1; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
IAP_trig = 0x5A; //先送5A
IAP_trig = 0xA5; //先送5A再送A5立即触发
return IAP_data;
}
void writeEEP(uint k, uchar da){ //写入
IAP_data = da; //传入数据
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
IAP_cmd = 2; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
IAP_trig = 0x5A; //先送5A
IAP_trig = 0xA5; //先送5A再送A5立即触发
}
void eraseEEP(uint k){ //擦除
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
IAP_cmd = 3; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
IAP_trig = 0x5A; //先送5A
IAP_trig = 0xA5; //先送5A再送A5立即触发
}
xdata struct Ida{
int xz0; //零点偏移
int xz1; //中点偏移
int FC0; //满程低4位
int FC1; //满程高4位
int en;
} cs;
void cs_RW(char rw){
uchar i,*p = &cs;
if(rw){
eraseEEP(0);
for(i=0;i<sizeof(cs);i++) writeEEP(i,p);
}else{
for(i=0;i<sizeof(cs);i++) p=readEEP(i);
}
}

/**********
字形编码图
32
-
64| | 128
- 16
1| | 8
_. 4
2
**********/
uchar code zk[20]={235,136,179,186,216,122,123,168,251,250}; //字库
uchar disp[7]={235,136,179,186,216,122,123};
sfr P1M1=0x91; //P1端口设置寄存器
sfr P1M0=0x92; //P1端口设置寄存器
sfr P0M1=0x93; //P0端口设置寄存器
sfr P0M0=0x94; //P0端口设置寄存器
sfr P2M1=0x95; //P2端口设置寄存器
sfr P2M0=0x96; //P2端口设置寄存器
sfr P3M1=0xB1; //P3端口设置寄存器
sfr P3M0=0xB2; //P3端口设置寄存器
sbit ds0=P2^1; //数码管扫描口
sbit ds1=P2^2; //数码管扫描口
sbit ds2=P2^3; //数码管扫描口
sbit ds3=P2^4; //数码管扫描口
sbit ds4=P2^5; //数码管扫描口
sbit ds5=P2^6; //数码管扫描口
sbit ds6=P2^7; //数码管扫描口
sbit K0=P3^4; //键盘
sbit K1=P3^5; //键盘
sbit K2=P3^6; //键盘
sbit K3=P3^7; //键盘


//功能程序开始

void cls(){ char i; for(i=0;i<7;i++) disp=0; } //清屏
void showDig(long f){ //显示数字
uchar i;
cls();
for(i=0;i<7;i++) { disp=zk[f%10], f/=10; if(!f) break; }
}

sbit P_SCK=P1^0; //时钟
sbit P_SDO=P1^1; //数据
sbit P_CS =P1^2; //片选
long pv=0; //一阶滤波的AD转换均值
long jz(long v){ //非线性改正
float n;
v -= cs.xz0;
n = v/1.0/(cs.FC0+cs.FC1*10000.0);
if(n>0&&n<1) v -= cs.xz1*n*(1-n)*4;
return v;
}
void get_adc(char zz){
char i; long v=0; //v是AD转换结果
if(P_SDO) return; //检测转换状态
for(i=0;i<32;i++){ //读取串行数据
P_SCK = 1; delay(1);
v <<= 1;
if(P_SDO) v++;
P_SCK = 0; delay(1);
}
v -= 0x20000000; //处理符号位
v = (cs.FC0+cs.FC1*10000.0)*v/0x10000000; //尺长变换
if(cs.en>0 && cs.en<=20){ //滤波
if(labs(v-pv/cs.en)>50) pv = v*cs.en; //限幅
else pv = v + pv - pv/cs.en; //一阶滤波
v = pv/cs.en; //取平均值
}
if(!zz) v = jz(v); //非线性改正
showDig(labs(v)); //显示
if(v<0) disp[6] += 16; //显示负号
if(zz) disp[0]+=4; //不矫正
}

void zd0(void) interrupt 0 {//int0中断(下降沿)
}

void timerInter(void) interrupt 1 {//T0中断
}
int inc_cs(int a,char d){ //a的d位加1
char i,f=1;
int v=10;
if(d<0) return a;
if(d==5) return -a;
if(a<0) a=-a,f=-1;
for(i=0;i<d;i++) v*=10;
if(a%v+v/10 < v) return f*(a+v/10);
else return f*(a+v/10-v);
}
main(){
uchar dispN=0; char nx=0; //显示扫描索引
uchar menu=0,gb=-1,kn=0,K,zz=0;
int *p;
TCON=0, TMOD=0x09; //将T0置为16位内部计数,并由外部启动计数。
IT0=1; //使int0下降沿中断有效。
TH0=0, TL0=0;
TR0=1; //T0启动计数
EX0=1; //开int0外部中断
ET0=1; //T0开中断
EA=1; //开总中断
PT0=1; //中断优先

P2M0 = 0xFE; //P2.1234567置为推勉输出
//P1M0 = 0x05; //P1.02置为推勉输出
//P1M1 = 0x02; //P1.1置为高阻抗
//P3M0 = 0x0C; //P3.23置为推勉输出口
delay(4000);
P_CS=1; delay(1);
P_SCK=0;delay(1);
P_CS=0;
cs_RW(0);
if(cs.en<0){ cs.xz0=0, cs.xz1=0, cs.FC0=0, cs.FC1=500, cs.en=8; cs_RW(1); }
while(1){
//显示disp
dispN = (++dispN)%7; //扫描器移动
nx++; if(nx>100)nx-=200;
ds0=ds1=ds2=ds3=ds4=ds5=ds6=0;
if(dispN==0) ds0=1;
if(dispN==1) ds1=1;
if(dispN==2) ds2=1;
if(dispN==3) ds3=1;
if(dispN==4) ds4=1;
if(dispN==5) ds5=1;
if(dispN==6) ds6=1;
if(dispN==gb && nx>0) P0 = 255; //不显示
else P0 = ~disp[dispN]; //显示
K = ( ~(P3>>4) ) & 15;
if(K) { if(kn<255) kn++; } else kn = 0; //判断是否有按键按下
if(kn!=20) K=0; //按下时间不够长,键值无产
if(K==1) { menu++; if(menu>5) menu=0,gb=-1; else gb=0; } //切换菜单
if(menu==0) { //读取AD电压
if(K==2) zz=(++zz)%2; //设置是否矫正
get_adc(zz);
}
if(menu>=1&&menu<=5){
if(menu==1) p = &cs.xz0;
if(menu==2) p = &cs.xz1;
if(menu==3) p = &cs.FC0;
if(menu==4) p = &cs.FC1;
if(menu==5) p = &cs.en;
if(K==2) { gb++; if(gb>5) gb=0; } //光标键
if(K==4) cs_RW(1); //保存
if(K==8) *p = inc_cs(*p,gb); //改值
showDig( abs(*p) );
if(*p<0) disp[5]=16; //显示负号
disp[6] = zk[menu]; //显示菜单号
disp[gb]+=4; //用小数点表示光标
}
delay(4000);
}//while end
}
发表于 2012-3-4 20:18 | 显示全部楼层
这玩意已经扔一边快2个多月了。。
DSC01304.jpg
回复

使用道具 举报

 楼主| 发表于 2012-3-4 20:21 | 显示全部楼层
这玩意已经扔一边快2个多月了。。
天风雪雨 发表于 2012-3-4 20:18 https://www.yleee.com.cn/images/common/back.gif


?为什么?只要真的能准确的话,很不错啊;我本来还想买5位半或6位半的二手表的,有这个就先不买了;校正电源和恒流电子负载用不知道是否可行?
回复

使用道具 举报

发表于 2012-3-4 20:27 | 显示全部楼层
LTC2400本身的测量范围只能到5V,而且由于输入反接保护二极管的原因几乎不能测量负压,所以要作为一个完整的数字电压表,缺少一个最为重要的前置分压电路,而对于高位表来说,这个前置电路的稳定性、噪声、温飘等的重要性不亚于A/D部分,但这些性能则要大部分靠元件自身的性能来保证,这样就造成了这部分的价格远高于图中的A/D部分本身。所以我图里的那个也只做了5V和10V两个量程。
回复

使用道具 举报

 楼主| 发表于 2012-3-4 20:33 | 显示全部楼层
LTC2400本身的测量范围只能到5V,而且由于输入反接保护二极管的原因几乎不能测量负压,所以要作为一个完整的 ...
天风雪雨 发表于 2012-3-4 20:27 https://www.yleee.com.cn/images/common/back.gif


嗯,这个倒是,我手头的是LTC2410,好像比2400好点;另外,如果前级用AD526 可编程增益运放,OP497四运放的话会不会可行?另外,实际只测量正电压也没问题,关键是准确度和线性度. 现在的问题是没有校准的设备。
回复

使用道具 举报

发表于 2012-3-4 20:39 | 显示全部楼层
回复 5# gmliwei

运放增益再怎么可变,输入电压始终不能超过VCC的。
回复

使用道具 举报

发表于 2012-3-4 20:40 | 显示全部楼层
而且输入运放的失调也不能太大,输入阻抗不能太小。
回复

使用道具 举报

发表于 2012-3-4 20:52 | 显示全部楼层

RE: 看高人自制6位半电压表头

回复  gmliwei

运放增益再怎么可变,输入电压始终不能超过VCC的。
天风雪雨 发表于 2012-3-4 20:39 https://www.yleee.com.cn/images/common/back.gif



        maxim的最新高边检流芯片MAX9634不需要电源,还有MAX34406等的VCC只有5V或3.3V,高边电压可以达到28V或更高,不知道是怎么做的。
回复

使用道具 举报

发表于 2012-3-4 21:07 | 显示全部楼层
前提是弄个精度更高的表来校准它,
问题是有了精度更高的表,要它何用?
回复

使用道具 举报

发表于 2012-3-4 21:20 | 显示全部楼层
MAX9634输入不能到地电位,所以还是不能用,MAX34406失调太大,一样不适用。
回复

使用道具 举报

本版积分规则

QQ|一淘宝店|手机版|商店|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-11-1 08:08 , Processed in 0.040746 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表