xjw01
发表于 2022-4-6 11:00:19
本帖最后由 xjw01 于 2022-4-6 11:04 编辑
abbey_tom 发表于 2022-4-6 09:00
单次采样结果有正有负,
我是取绝对值求和后再平均的。
代码如下:
直接求平均,不要取绝对值。
遇到24bit的负数,但他表示负数的话,转32bit时,在前面的8bit补上8个1就可以了。
sigma delta ADC,读数要取平均值,否则效果不好(有效位数会少了几个bit)。
abbey_tom
发表于 2022-4-6 12:30:02
washu 发表于 2022-4-6 10:16
这个测试不是叫你取平均值,而是统计 100 个样本的峰峰值(或者求其标准差、有效值),然后和手册对比。
...
有没有您用过的用于统计的测试代码?
abbey_tom
发表于 2022-4-6 12:31:39
xjw01 发表于 2022-4-6 11:00
直接求平均,不要取绝对值。
遇到24bit的负数,但他表示负数的话,转32bit时,在前面的8bit补上8个1就 ...
如果不取绝对值的话,
正负可能相互抵消,
结果会比较好看。
xjw01
发表于 2022-4-8 10:29:16
本帖最后由 xjw01 于 2022-4-8 10:33 编辑
abbey_tom 发表于 2022-4-6 12:31
如果不取绝对值的话,
正负可能相互抵消,
结果会比较好看。
这类ADC芯片,没有过多可以优化的。取平均值就可以了。
手册上说,非线性最大10ppm,因此,做成5位半的毫伏表是没有问题的。也就是说,最后一位就忽略了吧,这样省事。非要提取最后一位,要想办法降低噪声,同时要做非线性改正,那就太费劲。5位半的表头,相对于4位半的,能更有效的分辨温漂等现象。
我们常用的器件,温漂大,用5位到6位数字显示比较合适,能更突出显示出主要的字数,略去无用字。如果用7位的,环境状态轻微改变,末字就漂,看那飘忽不定末位数,很烦的,也很浪费时间。
正因为末位的不确定性,所以才有各种各样的“统计”方法,对于一般的使用,很讨厌那些统计方法,我们希望得到相对稳定的末位。比如跳动2字是可以接受的,如果跳动10字,还不如把末字隐藏。
abbey_tom
发表于 2022-4-8 15:13:39
本帖最后由 abbey_tom 于 2022-4-8 15:40 编辑
xjw01 发表于 2022-4-8 10:29
这类ADC芯片,没有过多可以优化的。取平均值就可以了。
手册上说,非线性最大10ppm,因此,做成5位半 ...
许老师说得有道理。
其实在我们业余环境下,
所能应用到的环境没有那么高的测量需求,
即使ADC芯片做得再好,
稳定的基准源也是一个大问题。
我现在的目标也不高,
能够做一个精度不低于我23S的毫伏表就可以,
300mV档是0.05%+3d。
但我现在大致比对了一下,
好像在毫伏量级,
能够稳定的有效位数并不如23S,
比如50mV左右,
连稳定的4位都很难做到(23S可测得稳定的50.00mV,末位会变但基本稳定)。
测1.5V的电池可以做到1580.64X
是不是因为基准太高(目前是2.5V)导致的。
还有,
也不知道PGA该怎么选取。
xjw01
发表于 2022-4-8 16:47:12
本帖最后由 xjw01 于 2022-4-8 17:11 编辑
abbey_tom 发表于 2022-4-8 15:13
许老师说得有道理。
其实在我们业余环境下,
所能应用到的环境没有那么高的测量需求,
我曾做过LTC2400和ads1232等,适当做平均处理后,一般可以达到手册中的指标。
当时,LTC2400测试过程比较长,虽然十几年了,却还有一些印象。可以做到500万字,约1uV左右。具体值我记不清了,但我当时保留到500万字,说明末字跳动2、3个uV以内,否则当年只会保留50万字
从手册上看,ads1256的PGA选大一些,噪声小,功耗也变大。功耗大了,容易引起基准的额外温漂。
这种ADC,要注意电容的选用。因为瓷片电容(现在常用一些新名词,如x7r,cog,npo等等),容量大的,往往介电吸收也很大,噪声电流不可忽略。
我实测过多种电容,uF级的瓷片电容,表现很糟糕,它会引起ADC读数不稳定。
我曾在LM317+Ro的测试中讨论到:“有容乃大”的原理,相同容量,体积小容易受到温度的影响,电流噪声大,稳定性差。不管是晶体管还是电容器,基本上都是这样的。特别是温补型的陶瓷电容,哪怕0.01度的温度扰动,也会有噪声电流的。
我看到你的板子上,用了超小型的电容器。要担心那些电容器对噪声的影响。
正品的ads1256、ads1232、LTC2400等,是很贵的,一般是淘宝上买了一些便宜的,这些ADC,指标差一点,我觉得也正常。芯片制造过程中,总有一些指标差一些的,厂家不要了,却流向市场。
washu
发表于 2022-4-8 17:42:30
abbey_tom 发表于 2022-4-6 12:30
有没有您用过的用于统计的测试代码?
十几年前我用 Basic 写的,估计参考意义不大 :lol
写一个 FIFO(Move Window)数组,新的测量结果丢进去、最早的测量结果抛弃,数组长度就是样本数,然后对这个数组做统计(峰峰值、标注差、有效值)就可以了,挺简单的。我那个编译器很蹩脚(不支持 float 数组),所以用了比较蛋疼的方式去做这个 FIFO,你用普通 C 编译器要简单得多。
washu
发表于 2022-4-8 18:29:47
本帖最后由 washu 于 2022-4-8 18:31 编辑
abbey_tom 发表于 2022-4-8 15:13
...稳定的基准源也是一个大问题。
我现在的目标也不高,
能够做一个精度不低于我23S的毫伏表就可以,
300mV档是0.05%+3d。
但我现在大致比对了一下,
好像在毫伏量级,
能够稳定的有效位数并不如23S,
比如50mV左右,
连稳定的4位都很难做到(23S可测得稳定的50.00mV,末位会变但基本稳定)。
测1.5V的电池可以做到1580.64X
是不是因为基准太高(目前是2.5V)导致的。
还有,
也不知道PGA该怎么选取。
ADR4525 指标足够好(0.02% 精度、1ppm 温度系数、1.25uVpp 噪声),不是你系统中的短板。
你的问题,根据我玩 1232 的经验看主要是,
1、芯片电源、基准电源和基准、输入的退耦处理你做好没有?使用什么电容?你看我的 1232 用的据大个头的薄膜电容 :lol 你看看是否相关(环境温度稳定且无振动的话,铁电介质电容也不是那么糟糕,但如果确实有问题可以考虑 NP0 介质或薄膜)
2、进一步降低速度,作为肉眼观察的表,10Sa/s 速度还快了,1232 是慢不下来,你这个可以再慢到 2.5Sa/s
3、进一步滤波处理
此外,如果你要做一个 Range 50mV 的表,没有什么理由不开片内 PGA,人家本来就是给你干这活的。PGA 取到你的应用中的最大值或你的应用对 PGA 其它指标需求的最大值,比如失调和温度系数是否有额外的要求?
washu
发表于 2022-4-8 18:42:38
xjw01 发表于 2022-4-8 16:47
...正品的ads1256、ads1232、LTC2400等,是很贵的,一般是淘宝上买了一些便宜的,这些ADC,指标差一点,我觉得也正常。芯片制造过程中,总有一些指标差一些的,厂家不要了,却流向市场。
这些便宜货基本是翻新的,我当初发行 Voltgen 采购过几百片 LTC2400,和厂家样片对比没啥区别,除了外表...
我 4 月下旬可能会有点空,刚跑去买了点几块钱的 ADS1247 和 1255,到时候有机会测试看看,1255 我也是有样片的,可以对比。
当初也买过一批便宜的 1232,和徳姨样片对比,也没发现问题。
washu
发表于 2022-4-8 18:50:18
xjw01 发表于 2022-4-8 16:47
我曾做过LTC2400和ads1232等,适当做平均处理后,一般可以达到手册中的指标。
当时,LTC2400测试过程 ...
2400/1232 的噪声指标是硬指标,是不能做平均处理的,我前面贴的 1232 噪声就是没做平均处理的,直接采样连续若干样本,然后用其中最大值减去最小值得到的(峰峰值)。
washu
发表于 2022-4-8 19:04:59
abbey_tom 发表于 2022-4-6 12:30
有没有您用过的用于统计的测试代码?
不记得贴图用的代码是哪份了,反正都差不多,供参考
Do
' --------------- Wait the Convert ---------------
FontSet F0HD
iBusystp = 0
Do
iBusystp = iBusystp + 1
WaitMs 1
Loop While IO_ADC_DAT = 1 ' theAnalog 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,5)
fTrn = 2.5 * (65536 * iDa + 256 * iDb + iDc - 8388608) / 8388608
'Print fTrn
'GLcd (0,4), "Cur:"; fTrn; " VDC"
' --------------- Print the Convert Result ---------------
fOut = fTrn / Gainerr - Offseterr
FontSet F3HD
Format(2,4)
GLcd(0, 2), fOut
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
fOut = fOut / Gainerr - Offseterr
'fOut = 2.5 + fOut
'GLcd (1,1), "SMT:"; fOut; " VDC"
FontSet F0HD
Format(2,6)
GLcd (0,4), "SMT:"; fOut; " VDC"
'FontSet F3HD
'Format(1,6)
'GLcd(0, 2), fOut
FontSet F0HD
Format(1,6)
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"
Loop
xjw01
发表于 2022-4-8 20:45:21
本帖最后由 xjw01 于 2022-4-8 20:48 编辑
刚才找到了LTC2400,测试了15分钟。前几分钟等待稳定。之后,读数基本稳定为0uV,概率分布为:
0 uV,90%以上
- 1uV,5%
+1uV,5%(1分钟内,难得见到一两次+-1uV)
数字由0跳变为-1uV时,偶尔会同步出现-2uV,可能是数码管驱动电流比较大,产生了额坏的干扰。
也就是说,当时的制作,零点稳定性(短路),噪声电压小于1uV
手册止的指标是,0.5ppm跳动占比60%左右,也就是说跳动+-2uV以内。当时做了平均处理,噪声略有下降。
pgldyx
发表于 2022-4-8 21:07:10
对于这么高级的芯片ad转换,外围设计可不能马虎,费的功夫可能比编程还要多。采用低纹波三端稳压,高精度基准芯片(如果有的话),供电采用磁珠+电容的LC滤波,数字地与模拟地分离。还有人提到前面加缓冲运放,芯片下面不做覆铜处理。。。。。。。这些可能比修改程序有效。我以前用TM7705的16bitdac,根本不用多次采样取平均值,输出数值只跳动1个字。
abbey_tom
发表于 2022-4-8 21:17:04
xjw01 发表于 2022-4-8 16:47
我曾做过LTC2400和ads1232等,适当做平均处理后,一般可以达到手册中的指标。
当时,LTC2400测试过程 ...
这块板子我买的是半成品,
我对焊接这种贴片已经无缘了。
不过,
从对电池的测量来看,
可以达到1580.06x
我基本还是满意的,
噪声略大也就是偶尔超出5个uV,
现在比较头大的是,
测量小信号不行,
试了改变PGA还是不行,
我没有来得及仔细研究手册,
改变PGA(基本代码不动),
显示也没有什么变化。
就我的理解,
输入50mV,
假如PGA选择64,
输入到ADC的电压应该是50*64=3200mV
但显示仍然是50mV
abbey_tom
发表于 2022-4-8 21:17:43
washu 发表于 2022-4-8 19:04
不记得贴图用的代码是哪份了,反正都差不多,供参考
谢谢,收到代码。
有时间测试一下。
页:
1
[2]
3
4
5
6
7
8
9
10
11