矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
楼主: washu

一步一步试探:玩具级 6 位半万用表 DIY 探讨@只有分辨率的 6 位半是可以的吗?

  [复制链接]
发表于 2013-2-9 14:52:53 | 显示全部楼层
lht5631080 发表于 2012-11-30 23:49
其实,不管是否是玩具,至少我认为这是件值得尝试的事。大多数人手中是没有6位7位等高档万用表的,能 ...


前辈说的很有道理,贵在多实践
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2013-2-9 15:04:57 | 显示全部楼层
ldch 发表于 2013-2-9 10:14
有时间就发发资料吧,不发,大家怎么照做啊

大家都没啥热情嘛

这是目前的原理图,已经扩展好 2.5/25/250V 电压量程和 0.25A/10A 电流量程,以及 2.5K、25K、250K 电阻测量功能,另一组模拟输入端未使用。有兴趣的可以先画画 PCB

dmm1.png
回复 支持 反对

使用道具 举报

     
发表于 2013-2-9 15:05:22 | 显示全部楼层
精度能够达到5位半,还是有搞头的
回复 支持 反对

使用道具 举报

     
发表于 2013-2-9 16:08:37 | 显示全部楼层
本帖最后由 LEER 于 2013-2-9 16:14 编辑

这个感觉比LTC2400实用些,很好还有不少扩展功能,可以的话,还请LZ上传程序.个人认为能够实现自动量程,基本的AC.DC.V.A.二极管.通断等测量功能,达到比较实用,就比较好了.
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2013-2-9 16:34:59 | 显示全部楼层
LEER 发表于 2013-2-9 16:08
这个感觉比LTC2400实用些,很好还有不少扩展功能,可以的话,还请LZ上传程序.个人认为能够实现自动量程,基 ...

那就已经是完整的万用表而不是表头了   而且这样一来就必须有人机界面才行了,所以应该做到什么程度,目前还没有计划。目前写了一点代码,主要是测试当前硬件是否 OK,就先传上来吧,含部分自动量程和模拟条图代码了

'/////////////////////////////////////////////////////////
'///   FastAVR Basic Compiler for AVR by MICRODESIGN   ///
'///   Name of Your project
'/////////////////////////////////////////////////////////
$Device= m16                        ' used device
$Stack = 32                                ' stack depth
$Clock = 8                        ' adjust for used crystal
$Timer2 = PWM, 8, Normal
$GLCD HD61202, Data=PORTC, Ctrl=PORTA, 128, 64, 3
$Gctrl EN=0, WR=2, DI=1, CS1=5, CS2=4
$LeadChar="0", Format(2,6)
$Baud = 9600,n,8,1
'************** Config the IO **************
$Def IO_ADC_DAT = PINB.0
$Def IO_ADC_CLK = PORTB.1
$Def IO_REG_CLK = PORTB.2
$Def IO_REG_DAT = PORTB.3
$Def IO_REG_STB = PORTB.4
$Def IO_KEY_DAT = PINB.6
$Def IO_KEY_CLK = PORTB.7
'************** Config the IO **************

'************** Config the ADC Setting **************
Const InputA = &b00000000
Const InputB = &b00000001
Const InputT = &b00000010
Const GainHI = &b00110000
Const GainMD = &b00010000
Const GainLO = &b00000000
Const SpedHI = &b01000000
Const SpedLO = &b00000000
'************** Config the ADC Setting **************

'************** Declared the Hard Interrupt **************
Declare Interrupt Int0()
'************** Declared the Hard Interrupt **************

'************** Define the Variable **************
' Define the Soft fonts with Graph LCD
Dim F0HD As Flash Byte
Dim F3HD As Flash Byte
Dim F2HD As Flash Byte
Dim F1HD As Flash Byte
Dim LTC2400arr1 As Flash Byte
' Define the Readbyte Variable
Dim iDa As Byte
Dim iDb As Byte
Dim iDc As Byte
' Define the Tranbyte Variable
Dim iTa As Byte
Dim iTb As Byte
Dim iTc As Byte
' Define the Move Window Array Variable
Dim bREGa(129) As Byte
Dim bREGb(129) As Byte
Dim bREGc(129) As Byte
Dim bSmthlength As Byte
' Define the Min-Max(Peak to Peak) Arithmetic Variable
Dim iMax As Byte
Dim iMin As Byte
Dim lMax As Long
Dim lMin As Long
Dim lrec As Long
' Define the Other Variable
Dim i As Byte
Dim iBusystp As Byte
Dim iOverload As Byte
Dim iDraw As Byte
Dim iDactting As Byte 'Set&Return the DAC Setting Value
Dim iKeypress As Byte
Dim iKeycode As Word
' Define the Switch and Range&Function Config Variable
Dim iManswitch As Byte
Dim iOhmrange As Byte
Dim iOrangeConfig As Byte
Dim iRangechanged As Byte
' Define the Mathematical float Variable
Dim fOut As Float
Dim fTrn As Float
Dim fMax As Float
Dim fMin As Float
'************** Define the Variable **************

Const Gainerr = 1.000157e+00
Const Offseterr = 4.5e-5
Const rOhmrg1 = &b00000001
Const rOhmrg2 = &b00000010
Const rOhmrg3 = &b00000011
Dim rOhmRange(3) As Byte
Dim rOhm As Byte
'************** Config the MCU **************
DDRD =  &b11111010 'bit 0 = UART RX(INPT); bit 1 = UART TX(OUTP); bit3 = INT0(INPT)...
PORTD = &b00000000 'all Input is Up to VCC, Output = High
DDRB =  &b10111110 'bit 0 = ADC Data in;...bit 6 = Key Data in; bit 7 = Key Clock Out
PORTB = &b01100000 ' bit 6 Setting the Input up to VCC
'************** Config the MCU **************

'**************  Declare User Function **************
Declare Function WriteSReg(bDat1 As Byte, bDat2 As Byte, bDat3 As Byte) As Byte
Declare Function ReadSPI() As Byte
Declare Function ReadKEY() As Byte
Declare Function OffsetCAL() As Word
Declare Function InitADC(Channel As Byte, Gain As Byte, Speed As Byte) As Byte
'**************  Declare User Function **************

'************** initialize the Program **************
'Load Value
' Greator LCD Voltage by PWM Sch.
Pwm2 = 3
Start Timer2
' Reset Graph LCD
DDRA.3 = 1
PORTA.3 = 0 : WaitMs 200 : PORTA.3 = 1 : GLcdInit
Gcls
' Set Graph LCD Sont Fonts
FontSet F0HD
GLcd (1,1), "ADS1232 Test...Ver 5"
' init Analog Switch and Sethe Range&Function
iManswitch = &b01000100
'bit0 and bit 1 = OHM Range, 00=Volt,01=5K,10=50K,11=500K
'bit2 = Wire Config, 0=4W,1=2W
'bit3 = Bias, 0=VREF * 1/2, 1=Analog GND
' Init ADC and Calibration the ADC Input Offset
iDactting = InitADC(InputB, GainLO, SpedLO)
GLcd (1,2), "Init ADC="; iDactting
GLcd (1,3), "Offset CAL1="; Hex(OffsetCAL())
GLcd (1,4), "Offset CAL2="; Hex(OffsetCAL())
GLcd (1,5), "Offset CAL3="; Hex(OffsetCAL())
Wait 1
Gcls
bSmthlength = 16' Setting the Smooth Move-Window Lenght
GLcd (0,7), "Ln:"; Hex(bSmthlength)

iOrangeConfig = iManswitch And &b00001000
Select Case iOrangeConfig
       'Case 0 : GLcd (37,7), "LOtCoM"
       'Case 8 : GLcd (37,7), "LOtGnD"
End Select

FontSet F0HD
'GLcd(0, 5), "0     Min    Max    5"
'GLcd(0, 7), "AZ:OFF FILT:SMTH 32Pt"

FontSet F1HD
GLcd(0, 0), "Voltmeter"
GLcd(0, 1), "Range 002"



FontSet F2HD
GLcd(94, 0), "VDC"




'************** initialize the Program **************

'************** Enable the Keyboard **************
Int0 Rising 'Falling '
Enable Interrupts
Enable Int0
'************** Enable the Keyboard **************
iKeypress = 0
iKeycode = 0

Do
   ' --------------- Wait the Convert ---------------
   FontSet F0HD
   iBusystp = 0
   Do
     iBusystp = iBusystp + 1
     WaitMs 1   
   Loop While IO_ADC_DAT = 1 ' the  Analog to Digtial Convert Busy Bit at ADChipset DOUT Pin
   GLcd (80,7), "Setp:"; Hex(iBusystp)
   ' --------------- Wait the Convert ---------------
   
   ' --------------- Read the ADC ---------------
   ' Read all Analog to Digtial Convert Byte
   iDa = ReadSPI()
   iDb = ReadSPI()
   iDc = ReadSPI()

   ' Config the Negative numbers from the Complement Code.
   If iDa > 128 Then
      iDraw = iDa - 128
   Else
      iDraw = iDa
   End If
   iDa = iDa - 128
    ' Set the ADChipset Busy-wait Bit
   IO_ADC_CLK = 1 : WaitUs 1 : IO_ADC_CLK = 0
   ' --------------- Read the ADC ---------------
     
   ' --------------- Automatic theRange ---------------

   ' --------------- Automatic theRange ---------------   

   
   ' --------------- Print the Convert Result ---------------
   'Print the Current Convert Result
   FontSet F0HD
   Format (1,6)
   fTrn = 2.5 * (65536 * iDa + 256 * iDb + iDc - 8388608) / 8388608
   'Print fTrn
   GLcd (0,4), "Cur:"; fTrn; " VDC"
   ' --------------- Print the Convert Result ---------------
   

   
   For i = 0 To bSmthlength - 1
       bREGc(i) = bREGc(i + 1)
       bREGb(i) = bREGb(i + 1)
       bREGa(i) = bREGa(i + 1)                 
   Next i
   bREGc(bSmthlength) = iDc
   bREGb(bSmthlength) = iDb
   bREGa(bSmthlength) = iDa

   '排查最大最小值   
   lrec = 65536 * iDa + 256 * iDb + iDc - 8388608
   lMax = lrec
   lMin = lrec
   iMax = 1
   iMin = 1  
   fOut = 0
   For i = 1 To bSmthlength
       iTa = bREGa(i)
       iTb = bREGb(i)
       iTc = bREGc(i)
      
       lrec = 65536 * iTa + 256 * iTb + iTc - 8388608
       fTrn = 2.5 * (65536 * iTa + 256 * iTb + iTc - 8388608) / 8388608
       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
   
   fOut = fOut / bSmthlength
   'GLcd (1,1), "SMT:"; fOut; " VDC"

   FontSet F3HD
   Format(1,6)
   GLcd(0, 2), fOut / Gainerr - Offseterr

   FontSet F0HD
   iTa = bREGa(iMax)
   iTb = bREGb(iMax)
   iTc = bREGc(iMax)
   fMax = 2.5 * (65536 * iTa + 256 * iTb + iTc - 8388608) / 8388608
   'GLcd (1,2), "MIN:"; fMax; " VDC"
   iTa = bREGa(iMin)
   iTb = bREGb(iMin)
   iTc = bREGc(iMin)
   fMin = 2.5 * (65536 * iTa + 256 * iTb + iTc - 8388608) / 8388608
   'GLcd (1,3), "MAX:"; fMin; " VDC"
   GLcd(0, 5), fMin; " - "; fMax
   fOut = 1000000 * (fMax - fMin)   
   Format(3,1)
   GLcd (0, 6), "Noise:"; fOut; " uVpp"
   
   If iKeypress = 1 Then
      iKeypress = 0
      WaitMs 1
      iKeycode = ReadKey() + ReadKey() * 256
   End If
   
   GLcd (0, 7), "Key:"; Hex(iKeycode)
Loop
End


Function WriteSReg(bDat1 As Byte, bDat2 As Byte, bDat3 As Byte) As Byte
Local bWritedat As Byte
Local bWritebit As Byte
Local i As Byte
Local j As Byte
'bWritedat = bDat
IO_REG_DAT = 0
IO_REG_CLK = 0
IO_REG_STB = 0
WaitUs 1

For j = 1 To 2
   Select Case j
          Case 1 : bWritedat = bDat1
          Case 2 : bWritedat = bDat2
   End Select
   For i = 1 To 8
       bWritebit = bWritedat And &b10000000
       If bWritebit = 128 Then
          IO_REG_DAT = 1
       Else
          IO_REG_DAT = 0
       End If
       WaitUs 1
       IO_REG_CLK = 1 : WaitUs 1 : IO_REG_CLK = 0
       bWritedat = Shift(Left, 1, bWritedat)  
   Next i
Next j

WaitUs 1
IO_REG_STB = 1 : WaitMs 1 : IO_REG_STB = 0
IO_REG_DAT = 0
IO_REG_CLK = 0

Return 0
End Function

Function ReadSPI() As Byte
Local myByte As Byte
Local i As Byte
myByte = 0

For i = 0 To 7
    IO_ADC_CLK = 1   
    Rotate(Left,1,myByte)
    myByte = myByte + IO_ADC_DAT
    WaitUs 1
    IO_ADC_CLK = 0
    WaitUs 1      
Next i

Return myByte
End Function

Function ReadKey() As Byte
Local myByte As Byte
Local i As Byte
myByte = 0

For i = 0 To 7
    Rotate(Left,1,myByte)
    myByte = myByte + IO_KEY_DAT
    IO_KEY_CLK = 1
    WaitUs 1
    IO_KEY_CLK = 0
    WaitUs 1      
Next i

myByte = Not myByte
Return myByte
End Function

Function OffsetCAL() As Word
Local i As Byte
Local wBusy As Word

' Wait the ADC Ready to Calibration or Any anOther Operation
wBusy = 0
Do
  wBusy = wBusy + 1
  WaitMs 1   
Loop While IO_ADC_DAT = 1
' Sett the ADC to Offset Calibration
For i = 1 To 26
     IO_ADC_CLK = 1 : WaitUs 1 : IO_ADC_CLK = 0
Next i
' Wait the ADC Ready After Calibration
wBusy = 0
Do
  wBusy = wBusy + 1
  WaitMs 1   
Loop While IO_ADC_DAT = 1
'Return the Calibration Cycle,its maybe 790-810 ms
Return wBusy
End Function

Function InitADC(Channel As Byte, Gain As Byte, Speed As Byte) As Byte
Local DacSetting As Byte
DacSetting = 0
DacSetting = Channel Or Gain Or Speed
WriteSReg(DacSetting, iManswitch ,0)
WaitUs 100
DacSetting = DacSetting Or &b10000000
WriteSReg(DacSetting, iManswitch, 0)
Return DacSetting
End Function

Interrupt Int0(), Save 0
iKeypress = 1
End Interrupt

$Include "..\Help\samples\F3HD.bas"
$Include "..\Help\samples\F2HD.bas"
$Include "..\Help\samples\F1HD.bas"
$Include "..\Help\samples\F0HD.bas"
$Include "..\Bitmap\LTC2400arr1.bas"

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2013-2-10 09:47:05 | 显示全部楼层
lht5631080 发表于 2012-11-30 23:49
其实,不管是否是玩具,至少我认为这是件值得尝试的事。大多数人手中是没有6位7位等高档万用表的,能 ...

很多年前看电子报的感觉,是呀,现在有理论分析又有实践的文章越来越少,
回复 支持 反对

使用道具 举报

     
发表于 2013-2-11 11:24:07 | 显示全部楼层
感谢分享
先收藏了
回复 支持 反对

使用道具 举报

     
发表于 2013-2-11 14:20:05 | 显示全部楼层
本帖最后由 lizhijun1 于 2013-2-11 14:21 编辑

LZ的想法是能够实现的,但是高位表最主要还是稳定性,也就是长期使用的精度问题,一天或者一个星期的精度好实现,一个月,一年或者更长时间就难了。这个需要精挑细选的零件加上繁多的补偿电路来实现
回复 支持 反对

使用道具 举报

     
发表于 2013-2-11 14:57:18 | 显示全部楼层
路过,好好学习。
回复 支持 反对

使用道具 举报

     
发表于 2013-2-11 15:40:22 | 显示全部楼层
谢谢楼主,期待5位半 6位半。
回复 支持 反对

使用道具 举报

发表于 2013-2-12 20:13:35 | 显示全部楼层
支持楼主继续深入
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2013-2-12 21:05:09 | 显示全部楼层
hnhuqiong 发表于 2013-2-12 16:13
楼主文章其实很多人应该在看,并且持支持态度。但解说和实验略显凌乱。

既然准备为坛友做高分辨表头,那 ...

因为之前反响不大,就没有进行什么太多的解说,或者说心思也懒得放在这边,主要嘀咕我的电压源去了:
http://www.crystalradio.cn/thread-367703-1-1.html

如果大家有兴趣,过完年回去我开始着手这个不靠谱的万用表设计

标定仪器的话,电压方面我有上面那个自制的 Voltage Generator,它是因为我用商品电压电流源 YOKOGAWA 7651 感到不满而着手自制的,性能全面超越 7651,可以信赖,此外我还有几台 8 位半万用表可以作为辅助仪器,因此勉强能对付这个设计。电阻方面前面貌似展示过我有一台 2724 标准电阻源。

002556tpu7ptxba12u27l9.jpg
回复 支持 1 反对 0

使用道具 举报

     
发表于 2013-2-12 21:09:10 | 显示全部楼层
只有想不到的,没有做不到的,楼主加油啊!
回复 支持 反对

使用道具 举报

发表于 2013-2-13 01:42:05 | 显示全部楼层
无法保证不确定度,没意义吧?
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2013-2-13 10:11:59 | 显示全部楼层
zhenhaitun 发表于 2013-2-13 01:42
无法保证不确定度,没意义吧?

短时间内的不确定度取决于噪声的大小,根据 Ti 的手册,ADS1232 的输入噪声为 1.79uVpp,不确定度为其方差 420nV/2.5V 满度 = 0.168ppm。我自己对它进行实测,结果符合手册指标,因此测量结果的不确定度可以被保证。

2341068zq606hp77qarhq6.jpg
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-30 14:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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