AD5933阻抗模块测量值校正
■ 前言
在博文 使用AD5933测量元器件的谐振特性 推导了测量阻抗校正公式。
为了简便起见,下面的分压电阻 R 1 , R 2 R_1 ,R_2 R1,R2取值相同,与待测元器件阻抗大体相同。
测量分为两步:
- 第一步:先使用分压电路测量各个频率的测量值: R c + j ⋅ I c R_c +j\cdot I_c Rc+j⋅Ic。
- 第二步:将 R 2 R_2 R2替换成待测元器件( R t + j ⋅ I t R_t + j \cdot I_t Rt+j⋅It),测量结果 R m + j ⋅ I m R_m + j \cdot I_m Rm+j⋅Im。
▲ 测量实验电路基本结构
根据第一步的分压,可以知道,输入交流复矢量:
U ˙ I N = 2 ⋅ U ˙ c = 2 ( R c + j ⋅ I c ) \dot U_{IN} = 2 \cdot \dot U_c = 2\left( {R_c + j \cdot I_c } \right) U˙IN=2⋅U˙c=2(Rc+j⋅Ic)
根据第二步,可以知道待选器件复阻抗 X ˙ = R t + j ⋅ I t \dot X = R_t + j \cdot I_t X˙=Rt+j⋅It与测量结果 U ˙ m \dot U_m U˙m之间的关系为:
X ˙ R + X ˙ ⋅ U ˙ I N = U ˙ m ⇒ X ˙ R + X ˙ = U ˙ m U ˙ I N = a ˙ {{\dot X} \over {R + \dot X}} \cdot \dot U_{IN} = \dot U_m \,\,\,\, \Rightarrow \,\,{{\dot X} \over {R + \dot X}} = {{\dot U_m } \over {\dot U_{IN} }} = \dot a R+X˙X˙⋅U˙IN=U˙m⇒R+X˙X˙=U˙INU˙m=a˙
那么,元器件的复阻抗为::
X ˙ = R a ˙ 1 − a ˙ = R ⋅ U ˙ m U ˙ I N − U ˙ m = R ⋅ ( R m + j ⋅ I m ) ( 2 R c − R m ) + j ⋅ ( 2 I c − I m ) \dot X = {{R\dot a} \over {1 - \dot a}} = {{R \cdot \dot U_m } \over {\dot U_{IN} - \dot U_m }} = {{R \cdot \left( {R_m + j \cdot I_m } \right)} \over {\left( {2R_c - R_m } \right) + j \cdot \left( {2I_c - I_m } \right)}} X˙=1−a˙Ra˙=U˙IN−U˙mR⋅U˙m=(2Rc−Rm)+j⋅(2Ic−Im)R⋅(Rm+j⋅Im)
复阻抗的的幅值和幅角计算公式如下:
X ˙ = x + j ⋅ y , ∣ X ˙ ∣ = x 2 + y 2 , ∠ X ˙ = arctan ( y x ) \dot X = x + j \cdot y,\,\,\,\,\,\left| {\dot X} \right| = \sqrt {x^2 + y^2 } ,\,\,\,\angle \dot X = \arctan \left( {{y \over x}} \right) X˙=x+j⋅y,∣∣∣X˙∣∣∣=x2+y2,∠X˙=arctan(xy)
a = R ⋅ R m , b = R ⋅ I m , c = 2 R c − R m , d = 2 I c − I m a = R \cdot R_m ,\,\,b = R \cdot I_m ,\,\,c = 2R_c - R_m ,\,\,d = 2I_c - I_m a=R⋅Rm,b=R⋅Im,c=2Rc−Rm,d=2Ic−Im
x = a c c 2 + d 2 + b d c 2 + d 2 , y = − a d c 2 + d 2 + b c c 2 + d 2 x = {{ac} \over {c^2 + d^2 }} + {{bd} \over {c^2 + d^2 }},\,\,y = - {{ad} \over {c^2 + d^2 }} + {{bc} \over {c^2 + d^2 }} x=c2+d2ac+c2+d2bd,y=−c2+d2ad+c2+d2bc
01实验测量
1.测量校正数据
(1) 测量条件
- R = 10 k R = 10k R=10k,
- 描频率范围: 500 H z − 5000 H z 500Hz\,\, - 5000Hz 500Hz−5000Hz。
- AD5933:工作频率: f o s c = 1 M H z f_{osc} = 1MHz fosc=1MHz
- 扫描模式:SWEEEP(1)
▲ 校正电阻10kΩ测量数据
2.测量电容阻抗
测量条件与上面相同,将R替换成电容:2.2nF。
▲ 电容222测量数据
由于测试是电容,上面的结果显示相角随着不同的频率呈现逐步变化的情况。并不是呈现基本上90°的超前特性。
之所以造成这个错误,主要是因为扫描电压过高了,超过了16238(0x4000)。
下面重新使用扫描模式SWEEP(7),也就是将输出激励信号幅值降低一倍,重新进行校正和测量,下面是测量后的结果。
结果显示相位基本上呈现90°。
▲ 使用SWEEP(7)扫描计算结果
电容 C C C在频率 f f f下的容抗公式为:
X c = 1 2 π j ⋅ f ⋅ C X_c = {1 \over {2\pi j \cdot f \cdot C}} Xc=2πj⋅f⋅C1
利用上面的电容阻抗模型计算出对应的容抗,与测量数值进行对比如下,可以看到它们基本上相符。
▲ 对比测量与计算模型
3.测量电感
电感使用GX913GX9/3型十进制电感箱测量。测量条件和上面相同。测量结果如下:
▲ 测量电感100mH的数据
电感 L L L在频率 f f f下的感抗为:
X ˙ L = 2 π ⋅ f ⋅ L \dot X_L = 2\pi \cdot f \cdot L X˙L=2π⋅f⋅L
具体测量数值与计算感抗对比:
▲ 电感测量值与理论计算值之间的关系
4.压电陶瓷片
▲ 带有谐振腔的压电陶瓷片的阻抗
▲ 不带有谐振腔的压电陶瓷片
▲ 大型带有谐振腔的压电陶瓷蜂鸣器
▲ 低频压电陶瓷蜂鸣器
5.高频测量
- 高频校正数据
- AD5933工作频率:10MHz
- 频率范围:50k~500kHz
▲ 高频校正数据,R=10k
测量455kHz中周频率特性
▲ AM中周455kHz的测量特性
▲ 时钟晶体校正数据
▲ 时钟晶体测量数据
▲ 时钟晶体测量数据,SettingTime=100
▲ 时钟晶体测量数据,SettingTime=500
▲ 时钟晶体测量数据,SettingTime=500
▲ 时钟石英阻抗测量结果
▲ 时钟石英阻抗测量结果
※ 结论
通过实验结果,验证了通过分压方式测量复阻抗的公式。并对于一些具有典型特性的复阻抗元器件进行测量。
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2020-06-25
#
# Note:
#============================================================
from headm import *
import ad5933
from tsmodule.tsstm32 import *
from tsmodule.tsvisa import *
from tsmodule.tsdraw import *
#------------------------------------------------------------
printf('Begin testing:\a')
calflag = 1
calname = 'clk32768'
SWEEP_MODE = 7
Resistor=10e3
fosc = 10
startf = 32760
stepf = 0.02
numf = 500
#------------------------------------------------------------
if calflag == 0:
f1, R1, I1, A1 = tspload(calname, 'f', 'R', 'I', 'A')
R1 = list(R1)
I1 = list(I1)
if len(f1) != numf+1:
printf("NUMF is not equal to calibrate length:(%d,%d)"%(len(f1), numf))
exit()
#------------------------------------------------------------
ad5933.init(500, 1)
while True:
f = ad5933.setsweep(startf, stepf, numf, oscf=fosc)
time.sleep(2)
ad5933.sweep(SWEEP_MODE)
while True:
time.sleep(.5)
val = stm32val()
if val[12] > 0: break
printf('\a')
R,I = stm32memo(2)
if len(R) == len(f): break
#------------------------------------------------------------
A = [sqrt(r**2+i**2) for r,i in zip(R,I)]
if calflag == 1:
tspsave(calname, f=f, R=R, I=I, A=A)
#------------------------------------------------------------
if calflag != 0:
plt.plot(f, R, label="Real")
plt.plot(f, I, label="Imaginary")
plt.plot(f, A, label='Amplitude')
plt.xlabel("Frequency(Hz)")
plt.ylabel("Value")
plt.grid(True)
plt.legend(loc="upper right")
plt.show()
exit()
#------------------------------------------------------------
Xabs = []
Xphase = []
for Rc,Ic,Rm,Im in zip(R1,I1,R,I):
a = Resistor * Rm
b = Resistor * Im
c = 2*Rc - Rm
d = 2*Ic - Im
ccdd = c*c+d*d
x = a*c/ccdd + b*d/ccdd
y = -a*d/ccdd + b*c/ccdd
Xabs.append(sqrt(x*x+y*y))
Xphase.append(arctan2(y, x)*180/pi)
tspsave('Impedance',f=f, xabs=Xabs, xphase=Xphase)
#------------------------------------------------------------
plt.subplot(311)
plt.plot(f, R, label="Real")
plt.plot(f, I, label="Imaginary")
plt.plot(f, A, label='Amplitude')
plt.xlabel("Frequency(Hz)")
plt.ylabel("Value")
plt.grid(True)
plt.legend(loc="upper right")
plt.subplot(312)
plt.plot(f, Xabs)
plt.xlabel("Frequency(Hz)")
plt.ylabel("Amplitude(ohm)")
plt.grid(True)
plt.subplot(313)
plt.plot(f, Xphase)
plt.xlabel("Frequency(Hz)")
plt.ylabel("Phase")
plt.grid(True)
#------------------------------------------------------------
plt.show()
#------------------------------------------------------------
# END OF FILE : TEST1.PY
#============================================================
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# AD5933.PY -- by Dr. ZhuoQing 2020-06-25
#
# Note:
#============================================================
from head import *
from tsmodule.tsstm32 import *
#------------------------------------------------------------
def init(settletime=100, extclock=0):
if extclock > 0:
stm32cmd('writeb 81 8')
else:
stm32cmd('writeb 81 0')
time.sleep(0.02)
stm32cmd('writeb 80 b1') # Enter standby mode
stm32cmd('writei 8a %x'%settletime)
time.sleep(0.02)
def temperature():
data = stm32cmdata('readt', wait=200)
if len(data) > 0:
return data[0] / 32
else: return 0
def setsweep(startf, incf, num=100, oscf=16.557):
startn = int(startf * (2**27) * 4 / (oscf*1e6))
incn = int(incf * (2**27) * 4 / (oscf*1e6))
# printff('%x %x %x'%(startn, incn, num))
stm32cmd('writel 82 %x'%startn)
time.sleep(.02)
stm32cmd('writel 85 %x'%incn)
time.sleep(.02)
stm32cmd('writei 88 %x'%num)
time.sleep(.02)
# stm32cmd('writeb 81 0') # D3: 0:Internal system clock 1:External
# time.sleep(.02)
stm32cmd('writeb 80 b1') # Standby
time.sleep(.02)
stm32cmd('writeb 80 11')
time.sleep(.02)
fdim = []
for n in linspace(startn, startn + incn * num, num+1, endpoint=True):
fdim.append(n * oscf * 1e6/4/(2**27))
return fdim
def startf(resultflag = 0):
if resultflag > 0:
stm32cmd('writeb 80 21 1')
else:
stm32cmd('writeb 80 21')
def incf(resultflag = 0):
if resultflag > 0:
stm32cmd('writeb 80 31 1')
else:
stm32cmd('writeb 80 31')
def repeatf(resultflag = 0):
if resultflag > 0:
stm32cmd('writeb 80 41 1')
else:
stm32cmd('writeb 80 41')
def readdata():
return stm32cmdata('readd', wait=100)
def sweep(code=0x1):
stm32cmd('CLEAR')
time.sleep(.02)
stm32cmd('sweep %x'%code)
#------------------------------------------------------------
if __name__ == '__main__':
tdim = []
for i in range(10):
data = temperature()
tdim.append(data)
time.sleep(.1)
printf(tdim)
#------------------------------------------------------------
# END OF FILE : AD5933.PY
#============================================================
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
提问与回答
老师您好,我还想请教您一个关于AD5933的问题,就是我从数据寄存器中读取到了实部和虚部,但是非常大,短接的时候差不多是20000,但是我把一个100K的带测电阻放上之后还是很大,变成了19000左右,请问老师您遇到过这种问题吗?
1.这种情况我并没有碰到过。2. 猜测的AD5933的接受端的运放已经饱和了。
你好,就是关于这个量程的问题,为什么最大值不是65535呢?
▲ d
对于AD5933内部的DSP引擎的细节,在其数据手册上也没有透露的特别清楚,所以有些结论我只能根据实际读出的数据进行测测。其中0x4000(16384)就是根据读出猜测其内部在不饱和情况下实际输出的最大值; 猜测原因:1)内部使用了二的补码表示测量的整数数据,所以正弦波的不失真的峰值只能是0x7fff;2)经过内部DFT变换的时候,又将有效范围减少了一半(这个原因不知道为何?),最终确定下来该芯片表示正弦波最大值对应的输出结果为0x4000左右。
文章来源: zhuoqing.blog.csdn.net,作者:卓晴,版权归原作者所有,如需转载,请联系作者。
原文链接:zhuoqing.blog.csdn.net/article/details/107014827
- 点赞
- 收藏
- 关注作者
评论(0)