lilith 发表于 2011-7-21 22:10:57

用 LTC2400 做的 6.5 位表头阶段性完成并粗略测试

主要是之前搞那个先入先出的平滑算法,好像某个 AVR 编译器的数组边界与电脑上的编程环境不太一样,结果数组老是越界,今天终于搞完了,算法为 10 点先入先出,剔除最大最小值的 8 点平滑算法,每秒读数大约是 6.2 个读数,相当于 34401/3457 的 NPLC=10 的速度。对比测试源使用了横河可编程电源 7651,对比参照表 6581。因为手头上没有高速光耦,所以还没有做至少 5 万点的编程测试


第一个测试视频:先入先出平滑算法测试源为锂离子电池的视频
http://www.tudou.com/programs/view/f3snD1PI-7U/

第二个测试视频:用 7651 可调电源为源,6581 为参考表的测试视频,前半段为 50 点对照绝对误差(亦可作为线性度)测试,后半段为灵敏度测试
http://www.tudou.com/programs/view/axLrS1Jawvc/

电路总图:



测试中:


测试中 2:



与 6581 的对照测试图表,为与 6581 的绝对误差(ppm)与输入电压的关系。表格 I 为 6581 读数(认为是准确值),表格 J 为此表头读数,K 为绝对误差

lilith 发表于 2011-7-21 22:12:39

代码如下,.......反正我就只会 BASIC 啦


'/////////////////////////////////////////////////////////
'///   FastAVR Basic Compiler for AVR by MICRODESIGN   ///
'///   Name of Your project
'/////////////////////////////////////////////////////////
$Device= m8   
$Stack = 32   
$Clock = 8   
$Lcd=PORTB.0, RS=PORTB.5, EN=PORTB.4, 16, 2
$LeadChar="0", Format(2,6)
$ShiftIn Data=PORTC.4, Clock=PORTC.5, Msb
$Baud = 1200,n,8,1
$1Wire=PORTD.7
Dim i As Byte
Dim iBusystp As Byte
Dim iSMPL As Byte
Dim iSiG As Byte
Dim iExR As Byte
Dim iTrd As Byte
Dim iDa As Byte
Dim iDb As Byte
Dim iDc As Byte
Dim iDd As Byte
Dim iTa As Byte
Dim iTb As Byte
Dim iTc As Byte
Dim iTd As Byte
Dim iWRa As Byte
Dim iWRb As Byte
Dim iWRc As Byte
Dim iWRd As Byte
Dim bREGa(15) As Byte
Dim bREGb(15) As Byte
Dim bREGc(15) As Byte
Dim bREGd(15) As Byte
Dim iMax As Byte
Dim iMin As Byte
Dim lMax As Long
Dim lMin As Long
Dim lrec As Long
Dim fOut As Float
Dim fTrn As Float
DDRC.3 = 1
PORTC.3 = 0

InitLcd()
Cls
Lcd "Init Program...."

Wait 1
Cls
Locate 1,1 : Lcd "Result=10Smth8"
iSMPL = 0
Do      
   '等待 LTC2400 的 ADC 忙碌信号
   'iBusystp = 0
   Do
   'iBusystp = iBusystp + 1
   WaitMs 1   
   Loop While PINC.4 = 1
   'Locate 1,1 : Lcd iBusystp
   ' 读出 LTC2400 的所有字节
   iDa = ShiftIn
   iDb = ShiftIn
   iDc = ShiftIn
   iDd = ShiftIn
   'Locate 1,1 : Lcd Hex(iDa); Hex(iDb); Hex(iDc); Hex(iDd)
   '获得低 8 位转换结果
   iDd = iDd And &b11110000
   iDd = Swap(iDd)
   iTrd = iDc And &b00001111
   iTrd = Swap(iTrd)
   iTd = iDd + iTrd
   '获得中 8 位转换结果
   iTrd = iDc And &b11110000
   iTc = Swap(iTrd)
   iTrd = iDb And &b00001111
   iTrd = Swap(iTrd)
   iTc = iTrd + iTc
   '获得高 8 位转换结果
   iTrd = iDb And &b11110000
   iTb = Swap(iTrd)
   iTrd = iDa And &b00001111
   iTrd = Swap(iTrd)
   iTb = iTrd + iTb
   'Locate 1,1 : Lcd Hex(iTb); Hex(iTc); Hex(iTd);
   iTrd = iDa And &b00110000
   iTa = Swap(iTrd)
   '先入先出寄存器
   For i = 1 To 9
       bREGd(i) = bREGd(i + 1)
       bREGc(i) = bREGc(i + 1)
       bREGb(i) = bREGb(i + 1)
       bREGa(i) = bREGa(i + 1)               
   Next i
       bREGd(10) = iTd
       bREGc(10) = iTc
       bREGb(10) = iTb
       bREGa(10) = iTa
   
   iWRa = bREGa(9)
   iWRb = bREGb(9)
   iWRc = bREGc(9)
   iWRd = bREGd(9)
   'Locate 1,5 : Lcd Hex(iWRa); Hex(iWRb); Hex(iWRc); Hex(iWRd)
   '识别正负符号
   iSiG = iWRa And &b00000010
   If iSiG = 2 Then
      iTrd = iWRa And &b00000001
      lrec = 16777216 * iTrd + 65536 * iWRb + 256 * iWRc + iWRd
   Else
      lrec = 65536 * iWRb + 256 * iWRc + iWRd - 16777216
   End If   
   'Locate 1,1 : Lcd Str(lrec)
   
   '寻找最大最小值
   lMax = lrec
   lMin = lrec
   iMax = 1
   iMin = 1
   fOut = 0
   For i = 1 To 10
       iWRa = bREGa(i)
       iWRb = bREGb(i)
       iWRc = bREGc(i)
       iWRd = bREGd(i)
       '识别正负符号
       iSiG = iWRa And &b00000010
       If iSiG = 2 Then
          iTrd = iWRa And &b00000001
          lrec = 16777216 * iTrd + 65536 * iWRb + 256 * iWRc + iWRd
          fTrn = 5 * (16777216 * iTrd + 65536 * iWRb + 256 * iWRc + iWRd) / 16777216
       Else
          lrec = 65536 * iWRb + 256 * iWRc + iWRd - 16777216
          fTrn = 5 * (65536 * iWRb + 256 * iWRc + iWRd - 16777216) / 16777216
       End If
       '找出最大值
       If lrec > lMax Then
          lMax = lrec
          iMax = i
       End If
       '找出最小值
       If lrec < lMin Then
          lMin = lrec
          iMin = i
       End If
       fOut = fOut + fTrn
   Next i   
   'Locate 1,1 : Lcd iMax
   'Locate 2,1: Lcd Hex(bREGb(iMax)); Hex(bREGc(iMax)); Hex(bREGd(iMax))
   'Locate 1,15 : Lcd iMin
   'Locate 2,11: Lcd Hex(bREGb(iMin)); Hex(bREGc(iMin)); Hex(bREGd(iMin))
   '剔除最大值
   iWRa = bREGa(iMax)
   iWRb = bREGb(iMax)
   iWRc = bREGc(iMax)
   iWRd = bREGd(iMax)
   iSiG = iWRa And &b00000010
   If iSiG = 2 Then
      iTrd = iWRa And &b00000001
      fTrn = 5 * (16777216 * iTrd + 65536 * iWRb + 256 * iWRc + iWRd) / 16777216
   Else
      fTrn = 5 * (65536 * iWRb + 256 * iWRc + iWRd - 16777216) / 16777216
   End If
   fOut = fOut - fTrn
   '剔除最小值
   iWRa = bREGa(iMin)
   iWRb = bREGb(iMin)
   iWRc = bREGc(iMin)
   iWRd = bREGd(iMin)
   iSiG = iWRa And &b00000010
   If iSiG = 2 Then
      iTrd = iWRa And &b00000001
      fTrn = 5 * (16777216 * iTrd + 65536 * iWRb + 256 * iWRc + iWRd) / 16777216
   Else
      fTrn = 5 * (65536 * iWRb + 256 * iWRc + iWRd - 16777216) / 16777216
   End If
   fOut = fOut - fTrn   
   
   fOut = fOut / 8
   Locate 2,1: Lcd fOut; " VDC"
   
   Select Case iSMPL / 4
          Case 0
               Locate 2,16: Lcd "S"
          Case 1
               Locate 2,16: Lcd "M"
          Case 2
               Locate 2,16: Lcd "P"
          Case 3
               Locate 2,16: Lcd "L"                                          
   End Select
   iSMPL = iSMPL + 1
   If iSMPL > 15 Then iSMPL = 0
   'WaitMs 200   
Loop
End

lilith 发表于 2011-7-21 22:22:59

一些另外的构思和测试,还待完善的,主要是

1、将量程扩展到 10V(12.5V)
2、用模拟开关、程序消除放大电路的失调
3、引入高稳定度基准(LM399、LTZ1000 等)并用模拟开关和程序进行自校准

消除失调的测试已经尝试了,特意用了失调非常大的 TL062 运放,可以控制在 1-2 个字
测试用电路图:


测试中:


短路输入端:


与电脑的接口

由于手头上没有高速光耦进行隔离,所以没有很好制作这个部分,尝试过在程序中直接输出到串口,似乎还是会有一点干扰的,还是等弄到高速光耦再说吧


大约有这么多的不稳定

daijun 发表于 2011-7-21 22:29:24

真是高手啊。

爱好者 发表于 2011-7-21 22:34:56

6.5位,强啊。

liulwn 发表于 2011-7-21 22:42:51

chq1 发表于 2011-7-21 22:50:45

额的神啊,水平咋这么高涅?

src100 发表于 2011-7-21 23:10:59

期待楼主进一步完善。

src100 发表于 2011-7-21 23:14:39

先入先出平滑算法 和 台表里的那个什么 NPL 是一回事吗?

src100 发表于 2011-7-22 00:02:41

线性好像没有2400的datasheet给出的好啊。那个0-3V才1-2个ppm。这个有几十ppm了。

yjm2000 发表于 2011-7-22 00:05:49

又一个DIY的6位半表

lilith 发表于 2011-7-22 00:16:34

引用第10楼src100于2011-07-2200:02发表的:
线性好像没有2400的datasheet给出的好啊。那个0-3V才1-2个ppm。这个有几十ppm了。 images/back.gif



我测试的图表是绝对误差值,你需要根据手册上的 Note 6 将其转换为积分非线性值,这个计算比较麻烦,我懒得手工计算了,打算等找到高速光耦后用电脑进行自动化的 5 万点数据测试采集,并计算积分非线性和绘制图表...

strive 发表于 2011-7-22 00:44:41

很强大!!!赞!

lilith 发表于 2011-7-22 01:08:43

引用第10楼src100于2011-07-2200:02发表的:
线性好像没有2400的datasheet给出的好啊。那个0-3V才1-2个ppm。这个有几十ppm了。 images/back.gif



手工计算了一下积分非线性,两个尖峰可能是数据记录或别的问题导致,可以认为是非正常值、予以排除,因此基本符合手册描述。另外注意哦,这是满度为 5V,刻度 1uV,因此每读数(1uV)相当于 0.2ppm,你不要直接看绝对误差多少 uV 就当作多少 ppm,至少要给我除以 5;经过 INL 计算后,实际上线性是很好滴

iking921 发表于 2011-7-22 02:08:45

传说中的高手!

szmsos 发表于 2011-7-22 05:30:47

高啊。

longshort 发表于 2011-7-22 07:03:31

做这类东西,最有意思的就是过程。高!

kangxin 发表于 2011-7-22 07:43:35

这论坛有卖垃圾的奸商,也有能说能干的高手!

晓雯电子 发表于 2011-7-22 08:01:41

支持DIY

xiaosun 发表于 2011-7-22 08:15:30

LZ开板不,我也有两片2400 ,
MCU用51的,MEGA8不会用
高速光耦6N137很好找的

atl0402 发表于 2011-7-22 08:44:29

LZ用的什么原理图原件,想学习下,ORCAD?

hldiy 发表于 2011-7-22 09:02:42

高手,绝对高手。羡慕中

youngliu 发表于 2011-7-22 10:00:52

6871也有smooth功能,就是移动平均,平均数据数可以很大

lilith 发表于 2011-7-22 10:17:28

引用第20楼xiaosun于2011-07-2208:15发表的:
LZ开板不,我也有两片2400 ,
MCU用51的,MEGA8不会用
高速光耦6N137很好找的
images/back.gif



我还想找人给我做板呢,另外我也不会画 PCB 有人用 51 做的,所以你用 51 一样也可以做,M8 不会比 51 强到哪里去。


引用第21楼atl0402于2011-07-2208:44发表的:
LZ用的什么原理图原件,想学习下,ORCAD? images/back.gif



电路图是用 bSCH 画的,Multisim 没有这样的器件的时候我一般就用 bSCH 来画画

lilith 发表于 2011-7-22 10:18:54

引用第23楼youngliu于2011-07-2210:00发表的:
6871也有smooth功能,就是移动平均,平均数据数可以很大 images/back.gif



很多表都有,1071/1081 必须打开这个才能出 7 位半,有的表把这个功能放到数学运算中,比如 3457、6581,算法上有所不同,实现起来对我的编译器来说太操了,算了,现在都把 M8 的程序空间用掉 85% 了。

xiaosun 发表于 2011-7-22 10:46:29

画 PCB 没时间,而且模拟部分水平不够

selena2211 发表于 2011-7-22 12:54:53

PCB我可以给你画,不要太复杂就行

heize0 发表于 2011-7-22 13:10:30

支持DIY!
PCB的话,我或许也可以帮上忙!

大胡子 发表于 2011-7-22 13:33:46

凑一个热闹,PCB我可以帮忙LT20Bit的ADC应用过,当时画了四次板;算是有一点点小小经验。

richard 发表于 2011-7-22 14:30:51

不錯,支持!
页: [1]
查看完整版本: 用 LTC2400 做的 6.5 位表头阶段性完成并粗略测试