AD5933阻抗转换器网络分析仪初步实验

网友投稿 1058 2022-05-30

■ 简介

AD5933阻抗变换模块 是基于AD(ANALOG DEVICES)公司 的 AD5933 芯片的阻抗转换器、网络分析仪。此外,AD公司还提供了一款小型的 AD5934 。

该模块在TMALL上的零售价格为¥188。

D5933是一款高精度的阻抗转换器系统解决方案,片上集成频率发生器与12位、1 MSPS的模数转换器(ADC)。用频率发生器产生的信号来激励外部复阻抗,外部阻抗的响应信号由片上ADC进行采样,然后由片上DSP进行离散傅里叶变换(DFT)处理。DFT算法在每个频率上返回一个实部®数据字和一个虚部(I)数据字。然后根据实部数据字与虚部数据字可计算出待测器件的阻抗值与相位值。

模块特性

可编程输出峰峰值激励电压,输出频率高可达100 kHz

可编程频率扫描功能和串行I2C®接口

频率分辨率:27位(<0.1 Hz)

阻抗测量范围:1 kΩ至10 MΩ

利用附加电路可测量100Ω至1 kΩ阻抗

内部温度传感器(±2°C)

01模块基本分析

1.I-V测量反馈电阻

从购买的网站上并没有给出该模块以下信息:

RFB 的选择与大小:因为在模块中只有一个VIN,并没有显示出RFB的接口大小。

这部分将模块上的金属壳顶盖打开,便可以看到其中的内部主要电路。

通过测量,在AD5933上边的电阻(22k欧姆)是连接在RBF(PIN4)和VIN(PIN5)之间的电阻。这说明反馈的电阻为22kΩ。

2.模块工作电源

模块供电端口的电源为+5V。内部有AS1117-3.3V线性稳压电源。AD5933工作电源为3.3V。

3.模块运放接口电路

在金属屏蔽盒中包括有一个基于 AD8606 精密运放接口电路。

这部分电路与手册中的参考辅助电路结构很相似。是在了AD5933的输出和输入部分增加了基于AD8606的运放缓冲。提高了电路对了的驱动能力。

启动这部分电路,需要将内部电路的几个焊接点进行重新调整,将这部分的电路接入测量电路中。

02测试电路

1.硬件设计1

由于AD5933使用I2C总结接口,利用STC8G1K08所提供的I2C做接口芯片,完成与PC即连接。

使用快速制版,设计实验电路板并进行焊接。集成在面包板上完成实验。

2.软件设计2

工作频率:35MHz

STC8G1K软件设置:

AD5933阻抗转换器、网络分析仪初步实验

STC8G.H: #define PACKAGE_SOP8 1, #define I2C_EN 1

03实验测试

1.AD5933基础测试

供应工作电压+5V,测量此时工作电流:5mA。

测量芯片周围的工作电压:3.296V;

测量内部AD8606运放的工作电压:3.296V;两个运放的静态输出为1.64V。

2.I2C总线测试

下图显示连接AD5933的I2C总结对8G1K的I2C总线输出波形的影响:

数据线的幅度在连接AD5399的时候降低到了3.3V。数据线的幅值没有改变;

数据线在连接AD5933的时候,被主动拉高的一些变化。

3.建立AD5933相关的模块

建立AD5933.H, AD5933.C的相关模块并定义一系列的相关底层函数

相应的模块参见工程文件中的相应的文件。

基于串口的命令接口

这部分在serialtxt.c文件中实现。具体命令参加下面程序:

else IFARG0("setp") { sscanf(SDA(1), "%x", &nNumber); AD5933SetPointer((unsigned char)nNumber); printf("Set Pointer:%d\r\n",nNumber); } else IFARG0("readb") { sscanf(SDA(1), "%x", &nNumber); AD5933ReadBlock((unsigned char)nNumber, ucDim); for(i = 0; i < nNumber; i ++) { printf("%02bx ", ucDim[i]); } if(STD_NUM == 2) printf("\r\n"); } else IFARG0("readt") { AD5933WriteByte(0x80, 0x90); WaitTime(10); AD5933SetPointer(0x92); AD5933ReadBlock(2, ucDim); nNumber = ucDim[0]; nNumber = nNumber * 256 + ucDim[1]; printf("%d\r\n", nNumber); } else IFARG0("reada") { AD5933SetPointer(0x80); for(i = 0; i < 0x18; i ++) { printf("%0bx ", AD5933ReadByte()); } if(STD_NUM == 1) printf("\r\n"); } else IFARG0("writeb") { sscanf(SDA(1), "%x", &nNumber); ucAdd = (unsigned char)nNumber; sscanf(SDA(2), "%x", &nNumber); i = (unsigned char)nNumber; AD5933WriteByte(ucAdd, i); } else IFARG0("writei") { sscanf(SDA(1), "%x", &nNumber); ucAdd = (unsigned char)nNumber; sscanf(SDA(2), "%x", &nNumber); AD5933SetPointer(ucAdd); AD5933WriteBlock(2,(unsigned char *)&nNumber); } else IFARG0("writel") { sscanf(SDA(1), "%x", &nNumber); sscanf(SDA(2), "%lx", &lnNumber); AD5933SetPointer((unsigned char)nNumber); AD5933WriteBlock(3, ((unsigned char *)&lnNumber) + 1); } else IFARG0("readd") { AD5933SetPointer(0x94); AD5933ReadBlock(4, ucDim); printf("%0bx %0bx %0bx %0bx", ucDim[0], ucDim[1], ucDim[2], ucDim[3]); if(STD_NUM == 1) printf("\r\n"); } else IFARG0("reads") { AD5933SetPointer(0x8f); printf("%0bx", AD5933ReadByte()); if(STD_NUM == 1) printf("\r\n"); }

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

04PYTHON程序测试

建立 ad5933.py,利用MCU的接口命令,完成对AD5933的操作。

1.读取温度

ad5933temperature

Control registger(0x80) = 0x90

读取:0x92,0x93:

数值处理:将读取的数值乘以 0.03125.

下面的曲线是从AD5933内部读取的数值,在此过程中,使用手指触摸芯片,可以引起芯片的温度上下波动。所以芯片内的温度传感器对于环境温度还是非常敏感的。

2.设置输出激励信号

setsweep(startf, incf, num, oscf)

如下是设置输出频率为30kHz, 幅值为2Vp-p的波形。

实际测量的参数:频率:29.608; 电压RSM= 0.695V。

频率的偏差

设置100kHz, 实际使用DM3068输出的频率为98.695kHz。原来假定的频率 f 0 o s c = 16.776    M H z f_{0osc} = 16.776\,\,MHz f0osc =16.776MHz。经过修规:

经过上述修正之后, 实际输出聘用:99.993MHz。

3. 使用模块的AD8606缓冲

将模块的运放缓冲连接上。可以增加模块对于低电阻的测量能力。相关的实验在下一次的时候继续验证。

※ 结论

通过制作基于STC8G1(SOP8)的I2C接口板,可以使用上位机通过WiFi-UART来控制和读取AD5933的内部寄存器。完成信号的输出和测量结果。

更加详细的测量和应用。需要按照使用手册的要求进行标定和测量。相关的应用在后面的实验中陆续给出。

相关的交叉引用文档

//============================================================================== // PROCESS THE DEBUG BUFFER //------------------------------------------------------------------------------ void SerialDebugProcessBuffer(void) { unsigned int nNumber; unsigned char ucDim[8], i, ucAdd; unsigned long lnNumber; SerialDebugBuffer2Argument(); if(g_ucSDANumber == 0) return; if(strcmp("hello", (char *)STD_ARG[0]) == 0) printf("%s is ready !\r\n", VERSION_STRING); else IFARG0("setp") { sscanf(SDA(1), "%x", &nNumber); AD5933SetPointer((unsigned char)nNumber); printf("Set Pointer:%d\r\n",nNumber); } else IFARG0("readb") { sscanf(SDA(1), "%x", &nNumber); AD5933ReadBlock((unsigned char)nNumber, ucDim); for(i = 0; i < nNumber; i ++) { printf("%02bx ", ucDim[i]); } if(STD_NUM == 2) printf("\r\n"); } else IFARG0("readt") { AD5933WriteByte(0x80, 0x90); WaitTime(10); AD5933SetPointer(0x92); AD5933ReadBlock(2, ucDim); nNumber = ucDim[0]; nNumber = nNumber * 256 + ucDim[1]; printf("%d\r\n", nNumber); } else IFARG0("reada") { AD5933SetPointer(0x80); for(i = 0; i < 0x18; i ++) { printf("%0bx ", AD5933ReadByte()); } if(STD_NUM == 1) printf("\r\n"); } else IFARG0("writeb") { sscanf(SDA(1), "%x", &nNumber); ucAdd = (unsigned char)nNumber; sscanf(SDA(2), "%x", &nNumber); i = (unsigned char)nNumber; AD5933WriteByte(ucAdd, i); g_ucTime0MS = 0; g_ucTime0MS100 = 0; if(STD_NUM > 3) { for(;;) { AD5933SetPointer(0x8F); // Set the pointer to status register address:0x8F ucAdd = AD5933ReadByte(); if(ucAdd & 0x2) break; } i = g_ucTime0MS; ucAdd = g_ucTime0MS100; AD5933SetPointer(0x94); AD5933ReadBlock(4, ucDim); nNumber = ucDim[0]; nNumber = (nNumber << 8) + ucDim[1]; printf("%d ", nNumber); nNumber = ucDim[2]; nNumber = (nNumber << 8) + ucDim[3]; printf("%d ", nNumber); nNumber = ucAdd; nNumber = (nNumber << 8) + i; printf("%d\r\n", nNumber); } } else IFARG0("writei") { sscanf(SDA(1), "%x", &nNumber); ucAdd = (unsigned char)nNumber; sscanf(SDA(2), "%x", &nNumber); AD5933SetPointer(ucAdd); AD5933WriteBlock(2,(unsigned char *)&nNumber); } else IFARG0("writel") { sscanf(SDA(1), "%x", &nNumber); sscanf(SDA(2), "%lx", &lnNumber); AD5933SetPointer((unsigned char)nNumber); AD5933WriteBlock(3, ((unsigned char *)&lnNumber) + 1); } else IFARG0("readd") { AD5933SetPointer(0x94); AD5933ReadBlock(4, ucDim); nNumber = ucDim[0]; nNumber = (nNumber << 8) + ucDim[1]; printf("%d ", nNumber); nNumber = ucDim[2]; nNumber = (nNumber << 8) + ucDim[3]; printf("%d", nNumber); if(STD_NUM == 1) printf("\r\n"); } else IFARG0("reads") { AD5933SetPointer(0x8f); printf("%0bx", AD5933ReadByte()); if(STD_NUM == 1) printf("\r\n"); } else IFARG0("sweep") { i = 0x1; if(STD_NUM > 1) { sscanf(SDA(1), "%x", &nNumber); i = (unsigned char)nNumber; } for(nNumber = 0; nNumber < 10; nNumber ++) { AD5933WriteByte(0x80, i | 0x20); WaitTime(10); for(;;) { AD5933SetPointer(0x8F); // Set the pointer to status register address:0x8F ucAdd = AD5933ReadByte(); if(ucAdd & 0x2) break; } if((ucAdd & 0x4)) continue; } AD5933SetPointer(0x94); AD5933ReadBlock(4, ucDim); nNumber = ucDim[0]; nNumber = (nNumber << 8) + ucDim[1]; printf("%d ", nNumber); nNumber = ucDim[2]; nNumber = (nNumber << 8) + ucDim[3]; printf("%d ", nNumber); lnNumber = 0; for(;;) { AD5933SetPointer(0x8F); // Set the pointer to status register address:0x8F ucAdd = AD5933ReadByte(); if(ucAdd & 0x4) break; lnNumber ++; if(lnNumber >= 512) break; AD5933WriteByte(0x80, i | 0x30); for(;;) { AD5933SetPointer(0x8F); // Set the pointer to status register address:0x8F ucAdd = AD5933ReadByte(); if(ucAdd & 0x2) break; } AD5933SetPointer(0x94); AD5933ReadBlock(4, ucDim); nNumber = ucDim[0]; nNumber = (nNumber << 8) + ucDim[1]; printf("%d ", nNumber); nNumber = ucDim[2]; nNumber = (nNumber << 8) + ucDim[3]; printf("%d ", nNumber); } printf("\r\n"); } else printf("Error command : %s !\r\n", STD_ARG[0]); } #endif // SERIALTXT_EN //============================================================================== // END OF THE FILE : SERIALTXT.C //------------------------------------------------------------------------------

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

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

#!/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) / (oscf*1e6/4)) incn = int(incf * (2**27) / (oscf*1e6/4)) # 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

实验电路板AD工程文件:AD\Test\2020\AD5933\AD59338G1K.PcbDoc * ↩︎

下位机软件工程:C51\STC\Test\2020\AD5933\AD59338G1K\AD59338G1K.uvproj ↩︎

单片机 硬件开发 网络

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:滚雪球学 Python 之怎么玩转时间和日期库
下一篇:【NumPy】常用姿势积累
相关文章