高精度R2R电阻梯
01 梯形电阻
一、前言
刚刚拿到了购买的高精度电阻, 200片 10k 欧姆电阻。 下面将会利用它, 重新测试一下 R2R 梯形电阻 DAC的精度。 这是前两天使用普通制作的 10 bit DAC的效果。 在 3.3V的范围内, 线性误差最大达到了 28mV。 下面来看一下使用这些 千分之一精度的电阻制作的效果。 对于究竟能够达到多高的精度, 我现在也是充满着好奇。
二、电路设计
这一次使用的单片机为 STM32F401。 由于手边只有10k欧姆高精度电阻, 所以使用两个 10k电阻并联形成 5k 电阻。 铺设单面电路板, 适合一分钟制板方法。
▲ 图1.2.1 电路原理图
AD\Test\2024\March\R2RF40110K.SchDoc
▲ 图1.2.2 PCB电路
一分钟之后获得了电路板。 使用的覆铜板表面有些氧化, 对后面焊接很不友好。 但这还不是最致命的, 直到焊接前, 才意识地自己犯了一个愚蠢的错误。 所购买的电阻是 0805 封装, 但是制作的测试电路板则是0603 封装。 没有办法, 重新修改电路板再制作一块实验电路板。
将原来的 0603 封装的电阻修改成 0805 封装。 一分钟之后, 得到了新的电路板。 下面对它进行焊接。 电路比较简单, 焊接很容易。 QFN封装的单片机应用热风枪进行焊接, 下面开始对电路进行上电测试。
好事多磨, 现在使用 ST-LINK 无法访问到 单片机。 这就不好玩了, 这样无法进行软件测试了呀。 这个电路实在是太简单了, 因此猜测在原来电路设计中, 是直接把 BOOT0 连接到地线造成的影响。 现在使用 一个 10k欧姆把 BOOT0 接地。 重新制版, 焊接后测量, 果然, 现在可以访问了。 不过这就奇怪了, 在其他单片机单片机电路设计中, 直接到BOOT0 接地没有问题的。 不知道为什么在这里翻船了。
三、软件测试
下载测试软件, 可以看到电路板开始运行。 下面将之前测试的程序, 移植到现在的工程文件中。 输出锯齿波, 可以看到信号变化正常。
使用万用表测量 DAC 在不同的设置下对应的输出电压。 记录 100个数据点, DAC 输出从 0 到 1023 变化。 通过记录的数据, 来评估一下输出DAC的特性。 没有对比, 就没有伤害, 可以看到使用高精度电阻之后, 输出电压与DAC之间的线性关系非常好。 通过计算, 可以知道, 输出电压与线性拟合之间的误差, 在正负1.5mV 之内。 只有一个数据超过了这个误差范围。
▲ 图1.3.1 DAC输出与电压
dacdim=[0.0000,10.0000,20.0000,30.0000,40.0000,50.0000,60.0000,70.0000,80.0000,90.0000,100.0000,110.0000,120.0000,130.0000,140.0000,150.0000,160.0000,170.0000,180.0000,190.0000,200.0000,210.0000,220.0000,230.0000,240.0000,250.0000,260.0000,270.0000,280.0000,290.0000,300.0000,310.0000,320.0000,330.0000,340.0000,350.0000,360.0000,370.0000,380.0000,390.0000,400.0000,410.0000,420.0000,430.0000,440.0000,450.0000,460.0000,470.0000,480.0000,490.0000,500.0000,510.0000,520.0000,530.0000,540.0000,550.0000,560.0000,570.0000,580.0000,590.0000,600.0000,610.0000,620.0000,630.0000,640.0000,650.0000,660.0000,670.0000,680.0000,690.0000,700.0000,710.0000,720.0000,730.0000,740.0000,750.0000,760.0000,770.0000,780.0000,790.0000,800.0000,810.0000,820.0000,830.0000,840.0000,850.0000,860.0000,870.0000,880.0000,890.0000,900.0000,910.0000,920.0000,930.0000,940.0000,950.0000,960.0000,970.0000,980.0000,990.0000,1000.0000,1010.0000,1020.0000]
vdim=[0.0009,0.0333,0.0656,0.0979,0.1299,0.1622,0.1937,0.2166,0.2592,0.2915,0.3236,0.3559,0.3882,0.4199,0.4522,0.4846,0.5165,0.5488,0.5812,0.6133,0.6458,0.6781,0.7103,0.7425,0.7747,0.8069,0.8365,0.8687,0.9009,0.9331,0.9652,0.9976,1.0301,1.0622,1.0947,1.1269,1.1588,1.1913,1.2234,1.2552,1.2876,1.3196,1.3518,1.3842,1.4162,1.4489,1.4811,1.5132,1.5455,1.5776,1.6099,1.6424,1.6757,1.7082,1.7405,1.7724,1.8048,1.8371,1.8693,1.9020,1.9339,1.9660,1.9986,2.0305,2.0624,2.0948,2.1267,2.1593,2.1913,2.2234,2.2556,2.2884,2.3203,2.3526,2.3850,2.4169,2.4493,2.4789,2.5110,2.5430,2.5755,2.6075,2.6397,2.6724,2.7044,2.7367,2.7693,2.8010,2.8333,2.8658,2.8975,2.9294,2.9621,2.9943,3.0260,3.0585,3.0912,3.1229,3.1556,3.1880,3.2195,3.2523,3.2845]
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2024-03-24
#
# Note:
#============================================================
from headm import *
from tsmodule.tsstm32 import *
from tsmodule.tsvisa import *
dm3068open()
dacdim = arange(0, 1023, 10)
vdim = []
for d in dacdim:
stm32cmd('dac %d'%d)
time.sleep(2)
v = dm3068vdc()
vdim.append(v)
printff(d, v)
tspsave('measure', dacdim=dacdim, vdim=vdim)
plt.plot(dacdim, vdim, lw=3)
plt.xlabel("DAC(N)")
plt.ylabel("Voltage(V)")
plt.grid(True)
plt.tight_layout()
plt.show()
#------------------------------------------------------------
# END OF FILE : TEST1.PY
#============================================================
▲ 图1.3.2 DAC的线性误差
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST2.PY -- by Dr. ZhuoQing 2024-03-24
#
# Note:
#============================================================
from headm import *
from scipy.optimize import curve_fit
dacdim, vdim = tspload('measure', 'dacdim', 'vdim')
def linefun(x, a, b):
return a*x + b
param = (1e-3, 0)
param, conv = curve_fit(linefun, dacdim, vdim, p0=param)
printf(param)
vfit = linefun(dacdim, *param)
err = [v1-v2 for v1,v2 in zip(vdim, vfit)]
plt.plot(dacdim, err, lw=3)
plt.xlabel("DAC(N)")
plt.ylabel("Error(V)")
plt.grid(True)
plt.tight_layout()
plt.show()
#------------------------------------------------------------
# END OF FILE : TEST2.PY
#============================================================
※ 总 结 ※
本文测试了高精度电阻组成的梯形电阻 DAC 的性能。 在输出 3.3V的范围内, 误差在正负1.5mV 之内。 这比起前两天使用普通电阻对应的 28mV的误差范围来看, 精度得到了很大的提高。 在电路设计中, 对于STM32F401单片机, 不知道为何需要使用电阻将 BOOT0 连接到地线, 直接连接ST-LINK 无法访问单片机。 不过后来, 将 10k欧姆电阻替换成0欧姆, 单片机也能够被访问了。 所以,开始遇到的问题也许是其他的故障。
● 相关图表链接: