简介:这是一份面向射频测量、嵌入式设计与开源硬件爱好者的VNA2矢量网络分析仪完整方案,覆盖1MHz至6GHz频段,也是作者自述VNA的改进第二版。设计亮点包括替换部分射频芯片为性价比相近的型号、电源从12V改为5V以支持USB供电、通过微控制器配置FPGA免除JTAG编程器,以及重新布局射频部分增强端口隔离度。整套打包文件共704个,容量10.67MB,主要包含C++/C上位机程序源码、VHDL逻辑代码、PCB与原理图工程(brd/sch)、固件配置文件以及多种文档说明,基本涵盖了从软件界面到硬件底层的关键模块,便于按目录结构逐层研读。目前已有1151人学习浏览,适合具备一定RF和嵌入式基础的工程师、学生或DIY极客用于复现验证、二次开发或作为VNA设计参考资料。压缩包中还附有初步规格与工作原理介绍,能帮助读者快速理解系统框架并开展实际调试。
1. VNA2:1MHz到6GHz的USB矢量网络分析仪,第二版到底改了什么
标题里的VNA2,是我基于USB接口做的一台矢量网络分析仪的第二版,频率覆盖1MHz到6GHz。它要解决的事情很具体:给天线调匹配、查一段同轴线的驻波、验证滤波器通带,不再需要去和台式VNA预约机时。1MHz到6GHz这个跨度,难点其实不在6GHz,而在1MHz——低频端定向电桥的方向性会掉得很厉害,校准件的开路器也不再是理想开路。第二版的大部分改动,都围绕校准可重复性展开:射频通路分段、本地保存校准数据、把连接器参考面固定下来。这篇文章把我从第一版到第二版积累的选型逻辑、校准流程和踩坑记录摊开讲,适合正在做USB VNA、或者手头有类似设备但总测不准的人。
2. 硬件框架:1MHz到6GHz怎么放进同一台USB VNA
2.1 为什么1MHz和6GHz不能共用一套前端
矢量网络分析仪测S11,核心是定向电桥把入射波和反射波分开。方向性(directivity)直接决定最小可测反射。一个宽带电桥在几百MHz能到30dB方向性,在1MHz附近经常只剩20dB出头;在6GHz也不乐观,桥臂之间的寄生耦合会把方向性拉回去。方向性不够,测小反射时,电桥漏过去的入射波会淹没真正的反射波,S11曲线会出现一条虚假的“地板”。这就是为什么很多宽带VNA在低频段看起来“什么都测不出来”。
第二版的处理方式是分段射频路径。常见做法是把1MHz到6GHz切成三段:1MHz到100MHz、100MHz到1.5GHz、1.5GHz到6GHz。低段用一个宽带功率放大器加低通滤波,中段用差分对加衰减器做电平调整,高段用PLL倍频链。两处射频开关把三段前端切入同一套接收机,接收机用低中频方案:先混频到几十MHz,再用数字下变频得到I/Q。选低中频而不是零中频,是为了躲开直流偏置和1/f噪声,低频段测量更干净。
这里有个常见的坑:为了省成本用一颗宽带混频器覆盖全部频段,结果1MHz下混频器本振泄漏直接饱和接收机。第二版改成每段前端自带一组滤波器,射频开关切换时先给PLL留出稳定时间,再开启ADC采集。这个稳定时间写进固件状态机,后面第3章会展开。分段之后,各段增益可以独立调节,低段不需要为了6GHz的高频段牺牲增益,高频段也不用为了低频段放大器的压摆率问题妥协。
2.2 第一版到第二版的板级改动:分腔、桥接与本地校准表
第一版做的是单块PCB,模拟前端、数字控制、USB接口全挤在一起,6GHz时数字电路的高次谐波直接串进接收机。第二版做了三处改动。第一处分腔:把射频前端、数字主板、电源分成三个独立腔体,中间用黄铜隔板加指簧搭接。隔板不是装饰,6GHz下信号通过空间辐射的路径比走线耦合更危险。分腔之后,我测到6GHz处的本底噪声明显下降,S21小信号测量的可信度上了一个台阶。
第二处是USB桥接。完整扫4001个点,S11的I/Q数据打包后也就几十KB,USB2.0高带宽模式完全够用,瓶颈根本不在USB口。真正要处理的是固件怎么把浮点I/Q转成低位定点又不丢精度,以及上位机读取慢时扫描会不会中断。第二版把扫描数据放进FIFO,FIFO半满时暂停触发,而不是丢弃后半段。这样即使上位机用慢速脚本读数据,曲线也稳定。
第三处是校准数据存本地。第一版把校准文件放在PC端,换一台电脑、换一个USB口就要重校准,非常麻烦。第二版在校准完成后把误差项写进板上的EEPROM,上电自动加载,误差项按频率点存储,占用的空间很小。这个改动把设备从“开发板”变成“仪器”。配合前面说的分腔结构,整机在6GHz的稳定性和可重复性都比第一版好不少。
2.3 参数水平与实际测量预期
| 参数 | 第二版典型值 | 说明 |
|---|---|---|
| 频率范围 | 1MHz – 6GHz | 三段射频路径自动切换 |
| 最大扫描点数 | 10001 | 默认4001,接近FFT友好点数 |
| IF带宽 | 10Hz – 100kHz | 决定噪声底座和扫描速度 |
| 典型动态范围 | 1MHz处约70dB,6GHz处约50dB | 低段表现好于高段 |
| 源输出电平 | -20dBm 到 0dBm,步进1dB | 高段输出电平偏低 |
| 校准方式 | SOLT单端口 | 误差项存设备EEPROM |
| USB接口 | USB2.0 | 控制命令走SCPI子集 |
参数看懂之后,测量预期就清楚了。动态范围50dB意味着,S21测一条插损40dB的滤波器还留有10dB余量,再小的信号就分不清噪声和真实响应。S11测到-30dB以下基本是这类DIY方案的极限,想测-40dB的驻波,需要把输出功率调高、把IF带宽收窄。另一个预期是扫描时间:IF带宽10kHz、4001个点时,单次扫描在4秒左右,属于典型慢扫,适合先看整体形状再决定要不要做精细扫描。
3. 固件与校准流程:扫频状态机、SCPI命令和SOLT三项误差模型
3.1 固件扫频状态机:单次扫描不丢点、连续扫描不重复
每次扫描从SCPI命令触发开始,固件状态在IDLE、ARMED、SWEEPING、DATA_READY之间流转。收到INIT命令进入ARMED;切换到SWEEPING后,固件按频率表逐点执行:先切换射频路径,等待PLL锁定,然后ADC采集中频信号,由数字下变频算出该点的I/Q,写入FIFO。全部点完成后进入DATA_READY,上位机可以读取。这个状态机解决的是扫描中途被打断的问题,比如上位机在扫频过程中发送了其他命令,固件不会响应,直到本轮结束。
连续扫描模式也很常用,但要注意:如果上位机读数据比固件扫得快,FIFO会满,固件会暂停触发直到数据被取走。所以在连续模式下看到曲线上出现随机跳变点,先怀疑读取速率而不是硬件坏了。单次扫描模式配合*WAI来用,是最稳的组合。这里的PLL锁定时间我一般设100us左右,频率步进越小,切换越频繁,锁定时长对总扫描时间的影响越明显。
3.2 用PyVISA控制VNA2扫频的最小命令脚本
import pyvisa rm = pyvisa.ResourceManager() # 列出所有设备,确认你的VNA2对应哪个地址 print(rm.list_resources()) vna = rm.open_resource('USB0::0x1234::0x5678::VNA2-A::INSTR') vna.timeout = 5000 # 扫描可能超过4秒,超时时间给足 vna.write(':SENS1:FREQ:STAR 1e6') # 起始频率 1MHz vna.write(':SENS1:FREQ:STOP 6e9') # 终止频率 6GHz vna.write(':SENS1:SWE:POIN 4001') # 扫描点数 vna.write(':CALC1:PAR:DEF "CH1",S11') # 定义测量参数为S11 vna.write(':INIT1:CONT OFF') # 关闭连续扫描 vna.write(':INIT1;*WAI') # 启动一次扫描并等待完成 raw = vna.query(':CALC1:DATA:SDATA? "CH1"') vna.close()SDATA返回的是交织格式的复数,固件不同解析略有差异,常见的是“RE0,IM0,RE1,IM1”这样交替排列。timeout参数不要省,4001点加上窄IF带宽时单次扫描会超过1秒,设太短会误判成超时。先设频率范围再设点数,固件会重新计算频率表;顺序反了可能导致start和stop互相覆盖。
3.3 SOLT校准的复误差模型:开路件寄生效应的长尾
单端口S11测量的误差可以用三项误差模型表示:S11_measured = Ed + (Er * S11_actual) / (1 - Es * S11_actual)。其中Ed是方向性误差,Es是源匹配误差,Er是反射跟踪误差。用短路、开路、负载三个标准件分别测量,得到三个方程,解出Ed、Er、Es,再反向求解S11_actual。这是SOLT校准的内核。
落到代码上,关键不是矩阵求逆,而是标准件模型要足够准。尤其是开路件,频率升高后端接电容不能再忽略,6GHz下一段很短的引脚就有零点几皮法的寄生电容,反射系数的相位会偏。简单模型可以写成C(f) = C0 + C1 * f,再换算成反射系数:
import numpy as np def open_gamma(freq): # 开路件寄生电容模型,C0和C1按你的校准件实际标定 C0, C1 = 0.15e-12, 0.02e-24 C = C0 + C1 * freq Zc = 1 / (2j * np.pi * freq * C) return (Zc - 50) / (Zc + 50) def s11_correct(s11_meas, ed, er, es): # 三项误差模型反解 return (s11_meas - ed) / (er + es * (s11_meas - ed))参数说明:C0取0.15pF是针对常见的SMA开路校准件,C1反映电容随频率的爬升;如果你的校准件是N型或者自定义的,这两个值要重新拟合。反解时注意复数除法,我见过有人在PC端校准脚本里用abs()做除法,结果相位信息全丢,测出来的S11只有模值没有符号。单端口SOLT只能修正S11本身,要测S21还得做直通响应校准:直通状态下的S21作为参考值存下来,后续测量做复数除法归一化。这个步骤我在第4章的完整测量里一起处理。
4. 在PC上跑通VNA2第一次完整测量:环境搭建、扫频与s2p落盘
4.1 装好PyVISA与USB后端,让系统先认出VNA2
PC端控制VNA2最常见的一套是PyVISA加pyvisa-py后端。安装命令很简单:
pip install pyvisa pyvisa-py装完先运行rm.list_resources()看设备是否被识别。Linux下最常见的坑是权限不足:设备能列出来,但open_resource时超时或者报权限错误。用lsusb查vendor ID和product ID,然后写一条udev规则:
SUBSYSTEM=="usb", ATTR{idVendor}=="1234", ATTR{idProduct}=="5678", MODE="0666"注意把idVendor和idProduct换成你自己设备的实际值。写完执行sudo udevadm control --reload,重新插拔USB线。Windows下一般是装好VISA后端驱动后,设备以USBINSTR资源出现,识别顺序靠资源字符串末尾的序列号区分。
4.2 完整测量脚本:参数设置、触发、数据解析与保存
这段代码把第3章的片段串成一次完整测量,并把结果保存成标准Touchstone s1p文件,方便后续处理或喂给仿真工具:
import pyvisa import numpy as np def measure_s11(start_hz=1e6, stop_hz=6e9, points=4001, ifbw=10e3): rm = pyvisa.ResourceManager() vna = rm.open_resource('USB0::0x1234::0x5678::VNA2-A::INSTR') vna.timeout = 15000 vna.write(f':SENS1:FREQ:STAR {start_hz}') vna.write(f':SENS1:FREQ:STOP {stop_hz}') vna.write(f':SENS1:SWE:POIN {points}') vna.write(f':SENS1:BAND {ifbw}') vna.write(':CALC1:PAR:DEF "CH1",S11') vna.write(':INIT1:CONT OFF') vna.write(':INIT1;*WAI') raw = vna.query(':CALC1:DATA:SDATA? "CH1"') vals = np.array(raw.split(), dtype=float) re, im = vals[0::2], vals[1::2] # 交织格式拆成实部和虚部 freq = np.linspace(start_hz, stop_hz, points) vna.close() return freq, re + 1j * im def save_s1p(filename, freq, s11): with open(filename, 'w') as f: f.write('! VNA2 S11 measurement\n') f.write('# Hz S RI R 50\n') for fi, s in zip(freq, s11): f.write(f'{fi:.6e} {s.real:.6e} {s.imag:.6e}\n') freq, s11 = measure_s11() save_s1p('dut.s1p', freq, s11)要点说明:IF带宽设为10kHz时单次扫描约4秒,timeout给15秒才够用。SDATA返回的数据里,如果出现NaN或者空行,多半是扫描没有真正完成,先检查*WAI是否执行。s1p文件的第二行格式很关键,“# Hz S RI R 50”表示频率单位Hz、参数为S参数、数据格式为实部虚部(RI)、参考阻抗50欧;有些CAD工具只认大写RI,小写ri会解析失败。测量结果落盘之后,后面做TDR或者其他后处理都方便。
4.3 结果怎么看:模值、相位和时域位移三件事
拿到S11曲线后,我习惯先做三件事。第一件看模值曲线,找有没有清晰的谐振凹陷,谐振频率和凹陷深度决定匹配该不该调。第二件看相位,S11相位能判断负载偏感性还是容性:谐振频率往低偏,说明等效负载偏容性,加串联电感可以拉回来;往高偏则相反。第三件是做一次时域变换,看反射发生在被测件的哪个位置。
常见误读是把毛刺当真实响应。IF带宽太宽时,噪声底座的起伏看起来像谐振,尤其是高频段。处理方式很简单:先把IFBW收窄,再看曲线是否还保持同样的形状。不要一看到怪波形就怀疑设备坏了,先排除参数设置问题,再动硬件。这一条对刚上手VNA的人尤其重要。
5. VNA2测量避坑与常见问题排查:校准漂移、地弹噪声和6GHz抖动
5.1 连接器扭矩不足:校准完S11仍然忽高忽低
现象:校准完成后测一个50欧负载,S11在2.4GHz附近出现一个-20dB的尖峰,换一个负载尖峰跟着走。
原因:SMA接头没有拧到位,接触面间隙产生不连续电容,等效成一段负载和连接器的谐振网络,谐振点正好落在2.4GHz。另一个同源问题是测试线在校准后又被弯折,参考面位置发生位移,测量结果自然对不上。
解决:校准前用扭矩扳手统一拧紧所有连接器,测量夹具和校准件用同一个扭矩。测试线固定好后不要再弯折,尤其不要拿手捏着线缆测量。这个坑在DIY场景里反复出现,我第一版在这里吃了不少亏,后面直接把扭矩扳手写进操作清单才稳定下来。
5.2 USB供电波动:电平漂移先查电源与地环路
现象:电脑在编译程序或拷贝大文件时,S11电平缓慢漂移;插入U盘的瞬间曲线出现明显跳变。
原因:USB的5V电压随电脑负载变化而波动,电源纹波直接进入前端检波器;地回路电流经过测量电路时,在接地阻抗上产生压降,等效于在小信号测量路径上注入干扰。
解决:外接一个独立供电的USB Hub,或者用隔离5V电源给VNA2供电,别让电脑的功率波动直接影响模拟前端。USB线尽量用短而屏蔽好的,过长线缆不但加剧压降,还会在6GHz附近引入辐射干扰。机壳地单点接电脑地,避免形成大地环路。不要指望LDO把所有纹波都滤掉,6GHz下LDO的电源抑制比往往不够用。
5.3 高频S21抖动:IF带宽、平均次数和扫描点数怎么调
现象:6GHz附近S21曲线呈锯齿状,重复扫描时相邻两次的峰值位置不一样,曲线看起来很“毛”。
原因:IF带宽太宽导致噪声底座抬高;源的高次谐波在6GHz附近泄漏进接收机;扫描点数太少时频响内插误差也会放大抖动。这三个原因经常叠加出现。
解决:按这个顺序调参数。先把IFBW从100kHz降到10kHz,再开平均,平均次数设16次,最后把点数从4001提到10001。IFBW和平均解决八成抖动,点数解决剩余的内插问题。代价是扫描时间明显变长,从0.5秒变成十几秒,但换来的是可重复的曲线。调参时注意每次改完参数要重新触发扫描,别只改配置不触发。
5.4 同一根天线两次结果对不上:校准失效与环境变化
现象:同一根天线上午测S11是-18dB,下午测变成-12dB,中间没动任何线缆和连接器。
原因:校准失效了。连接器反复插拔会改变接触阻抗,温度变化会改变前端增益和相位,校准件本身也不是长期稳定的。环境里如果有金属物体移动,也可能改变被测天线的近场,但在我这次的案例里,主要偏差来自校准状态漂移。
解决:测量前先接一个标准负载复测,如果S11偏离初始校准值1dB以上,重新校准;设备开机预热20分钟后再做校准和测量;被测天线放在固定支架上,别用手拿着。环境温度也值得记进日志,宽带放大器的温度系数可能到0.1dB/℃以上,夏天和冬天的测量结果本来就不该一样。
6. 用VNA2的频域数据做TDR:把USB盒子变成线缆故障定位仪
6.1 从S11反演反射距离:补零IFFT与峰值判读
VNA2扫出来的S11是频域反射系数,对它做逆傅里叶变换,就能直接看到反射波在时间轴上的位置,再乘上介质中的光速并除以2,就是反射点到参考面的距离。这是把USB VNA当线缆故障仪用的经典玩法,不需要额外硬件,软件层面就能完成。代码很短:
import numpy as np def s11_to_tdr(freq, s11): n = 1 << int(np.ceil(np.log2(len(s11) * 2))) window = np.hanning(len(s11)) pad = np.pad(s11 * window, (0, n - len(s11))) resp = np.fft.irfft(pad) t = np.arange(len(resp)) / (freq[-1] - freq[0]) d = t * 299792458 / (2 * np.sqrt(2.2)) return d, np.abs(resp)介电常数2.2对应实心聚乙烯同轴线的典型值,发泡介质要换成1.4到1.6。频率跨度6GHz时距离分辨率约2.5厘米,足够定位馈线里的断点、接头压伤或者进水位置。用已知长度的电缆先验证一次,如果峰值位置和物理位置对不上,优先检查介电常数设置。
我第一版最大的教训是把校准当成开机后的例行公事,结果每次换线缆都重新校准一遍,浪费了大半天。后来我给自己定了条习惯:每测一个被测件之前,先花30秒接标准负载验证校准,偏差超过1dB就重校。VNA2的价值不是那几GHz的带宽,而是每次测量结果都可信。这个习惯比任何硬件改动都值得先养起来。希望帮到你。
本文还有配套的精品资源,点击获取