简介:一套基于1MHz至6GHz USB接口的矢量网络分析仪(VNA)第二版工程资源,面向射频硬件工程师、嵌入式开发者与电子制作爱好者,提供可参考的软硬件设计方案,也适合作为高校射频课程的设计示例。其改进重点包括换用同性能低成本的射频芯片、改为5V供电以支持USB供电、通过微控制器配置FPGA从而无需JTAG编程器,并重新布局射频部分以提升端口隔离度。压缩包共704个文件、约10.67MB,主体为C/C++源码(h/cpp)与FPGA的VHDL文件,另有Qt界面文件、原理图/PCB工程、PDF说明及S参数数据,便于逐层学习射频前端与上位机数据处理流程。目前已有1151人学习浏览;借助PC端应用源码,读者可先在没有硬件的情况下运行应用,熟悉测量流程,再结合工程硬件继续完善动态范围、扫描速率等指标,或用于自定义扩展。
1. VNA2:为什么我要重做一台1MHz-6GHz的USB矢量网络分析仪
做射频的人都有这种经历:调一个滤波器,手边只有标量分析仪,只能看幅度,相位全靠猜。好不容易借到一台商用矢量网络分析仪,一看价格和时间预约,直接劝退。我也是一样,第一版VNA做出来能测S11和S21,但1MHz以下灵敏度差、6GHz附近校准后漂得厉害。所以有了第二版VNA2,目标很明确:1MHz到6GHz全程可用,USB连接电脑,测量结果能以标准Touchstone格式导出。这不只是把芯片换一换,而是从射频前端到固件时序到上位机算法都重推了一遍。这篇笔记适合想自己搭一台低成本矢量网络分析仪的硬件工程师或射频爱好者,你会看到常见的架构选型、PCB落地经验、以及我翻过车的几个校准坑。所有方案都是社区里被反复验证过的路线,不是玄学,但细节决定成败。
2. VNA2的架构与关键选型:从反射桥到幅相接收机
2.1 真正的矢量测量需要什么:激励源、反射桥和I/Q接收
矢量网络分析仪和标量最本质的区别,在于它同时测幅度和相位。要测相位,就必须有一个稳定的参考信号,和被测量信号做相干比较。一套完整的VNA前端,最基本的三件事:一个可扫频的激励源,一个把反射波和入射波分开的定向桥或耦合器,以及一路能同时输出I/Q或幅度/相位的接收机。
在VNA2里,激励源输出分两路:一路经过定向桥去DUT(被测器件),另一路直接进接收机做参考。反射信号从桥的耦合端口回到接收机,与参考信号混频或相减,得到复数比值S11。对于S21,则是把DUT串接在激励和接收之间,参考和直通信号做比值。注意,这里需要的是多个通道,而不是单通道功率计。第一版我偷懒只用了一个功率检波器,结果只测得了幅值,相位必须靠额外硬件补,工作量大,而且低频相位漂移严重。VNA2的接收链路改成双通道,用同样的本振做混频,保证相位相干。
2.2 器件选型:信号源用ADF4351,混频与检波怎么搭
信号源是整个机器的心脏。1MHz到6GHz,还要能扫频,选择空间其实不大。我选ADF4351做本振和激励源,因为它单芯片就能覆盖137.5MHz到4.4GHz,倍频后可以摸到6GHz,但要注意1MHz到137MHz之间的间隙。这个间隙我用了另一路低频DDS补低段,通过射频开关切换,低频段输出和高频段输出共用同一级放大和滤波。这是很多DIY VNA的标准做法,不必自己发明。
接收端有两种主流方案:一种是直接用AD8302这类对数幅度/相位检波器,另一种是用混频器加ADC做数字下变频。AD8302输出两个模拟电压,一个正比于幅度比,一个正比于相位差,接线简单,但它的相位检测范围有限,而且高频下精度随温度漂移明显。VNA2改用了混频方案:用ADL5801或类似的双平衡混频器,把RF信号和LO信号混到中频,再用一个24位ADC采样中频,在固件里做复数运算。这样好处是动态范围大,校准后残余误差小,缺点是电路复杂,需要多一路中频放大和抗混叠滤波。
自己搭VNA,不用追求测量精度达到商用机,但至少要保证重复性。重复性的关键不在于芯片的标称指标,而在于每一级之间的阻抗匹配和本振泄漏控制。我用混频器方案后,发现本振泄漏会直接叠加到中频信号上,产生固定频偏的杂散。解决方法是加了一级中频低通滤波器,带宽设置在10kHz到100kHz可调,软件扫频时同步切换滤波电容。
2.3 为什么不用网分仪专用芯片而选分离方案
市场上有集成的VNA前端芯片,比如一些宽带收发机,内部集成了混频器、本振、ADC,看起来节省大量设计时间。但它们的输出功率、滤波器带宽往往固定,想在1MHz到6GHz整个频段保持平坦输出,很难做。另外,专用芯片的评估板价格高,不适合个人第二版迭代。
我选择分离方案,还有一个实际原因:排查问题容易。如果接收机动态范围不对,我可以先用信号发生器直接灌信号,逐级测混频器、中频放大器和ADC的增益,哪一级不对一目了然。用专用芯片,一旦指标异常,根本不知道是内部哪一环节出问题,只能换板子。VNA2的前级小板和主控板分离,也是为了方便切开调试。射频板用四层板,主控板用两层板,之间用排针连接,信号质量差时还能临时飞线改路径。
3. 硬件设计与打样:1MHz-6GHz的PCB布局账
3.1 频率扩展方案:从1MHz到6GHz的分段覆盖
ADF4351的输出范围是137.5MHz至4400MHz,通过内部VCO和分频器,可以覆盖更低的频率,但实际测试发现VCO在低于500MHz时相噪明显变差。为了覆盖1MHz到6GHz,我把频段切成两段:低频段1MHz到300MHz用DDS加滤波器方案,高频段300MHz到6GHz用ADF4351加外部倍频。切换点放在300MHz,留出一定重叠,方便校准后拼接。
低频DDS我选的芯片最高时钟500MHz,理论输出到200MHz,但实际150MHz以上杂散变大,所以我也只让它输出到150MHz,剩余到300MHz用倍频链?这里要注意,如果你买到的DDS芯片是假的,或焊接温度过高导致内部电荷泵损坏,输出频率会偏差很大。另一个问题是DDS输出的阶梯波需要椭圆低通滤波,滤波器截止频率需要与当前扫频段对应。我的做法是用了三组可切换的低通滤波器,对应三个子频段,由单片机GPIO控制射频开关切换。
高频段倍频到6GHz时,ADF4351的基波在3GHz附近,用二倍频器后基波和三次谐波的抑制度取决于倍频器后面的带通滤波器。我用的是介质谐振器滤波形式,但尺寸太大,后来换成了微带带通滤波器,5.8GHz到6.1GHz插损约3dB,抑制度在30dB以上。6GHz的PCB布线要用50欧姆阻抗控制,走线宽度和介电常数有关,我用的是0.8mm厚的FR-4板材,50欧姆线宽大约1.35mm,但这只是参考,实际要按板材参数用计算工具算,别照抄别人的线宽,板材不一样就翻车。
3.2 定向桥与耦合器的偷学做法
定向耦合器在1GHz以下做宽带有难度,所以低频段我用电阻式定向桥。电阻桥的结构很简单:三个精密电阻加上两个隔离电阻,在低频段效果不错,但插损很大,典型值6dB以上。因为VNA2的激励源输出功率能到+10dBm,低频段插损大一点还能接受,但接收机的灵敏度必须足够。我的混频方案在中频有40dB增益,所以低频动态范围也能做到70dB左右。
高频段5GHz以上,电阻桥的寄生电容变得不可忽略,改用微带线平行耦合器。如果PCB面积紧张,还有一个偷学做法:用一对并联的1:1巴伦做反射桥,类似一些商用网分的宽带桥设计。巴伦桥的隔离度和方向性都远好于电阻桥,但带宽受巴伦本身带宽限制。我用的巴伦是1MHz到6GHz的宽带型号,实际上在低于10MHz时插损增加,所以低频段仍然保留电阻桥,通过射频开关切换。
设计定向桥时最容易翻车的是“方向性”指标。很多人拿万用表量电阻值,以为阻值匹配就行,实际上在GHz频率下,器件的寄生电感和焊盘的寄生电容会让桥失衡。我做第一版时,S11校准后曲线还是波浪状,就是因为桥的隔离端没有良好端接。后来我在隔离端口加了50欧姆到地的贴片电阻,并且直接压在微带线上,不留长引线,方向性才从20dB提升到35dB以上。
3.3 电源和屏蔽:拍频和地弹怎么压
VNA2内部有数字控制信号、模拟中频信号和射频本振信号,这三者混在一起,电源设计不好会直接导致测量曲线毛刺。我遇到的最典型问题是:当扫频频率切换时,ADC采集的数据会周期性地出现脉冲干扰,原因不是射频泄漏,而是USB控制器的时钟信号通过电源平面耦合到中频放大器。
解决方案有三层。第一层,所有敏感模拟电路用LDO单独供电,避免DC-DC的开关纹波直接进射频元件。第二层,把中频放大器和ADC的地平面与数字地平面用0欧电阻单点连接,模拟地和数字地分开铺铜。第三层,射频本振和混频器周围加屏蔽罩,屏蔽罩接地边栏尽量密集打孔,孔间距要小于最高频率波长的二十分之一。6GHz时波长是50毫米,二十分之一是2.5毫米,所以我的屏蔽罩打孔间距做到2毫米以内。另外,USB走线也要注意,最好走差分队,并保证阻抗连续性,否则USB信号完整性不够会导致误码,但这是后话。
还有个细节是供电电流。ADF4351的电荷泵输出电压调节不当,会导致VCO锁定不稳。我最初按照数据手册默认设置,结果在4GHz以上偶尔失锁,表现为输出功率瞬间跌落。后来发现是电荷泵电流与VCO调谐电压不匹配,通过寄存器配置把电荷泵电流调大一档后问题消失。这个调试过程需要反复读写寄存器,后面在固件里我会放一个示例。
4. 固件与上位机:让USB链路跑起S参数
4.1 下位机状态机:扫频和ADC采集的时序
VNA2的主控用的是一颗带USB高速接口的ARM芯片,固件里跑一个简单的状态机。上位机发送扫频指令,指令包含起始频率、截止频率、点数、中频带宽和输出功率。下位机收到后,先把参数解析成ADF4351和DDS的寄存器值,然后逐点做如下操作:设置频率,等待锁相环锁定和DDS稳定,切换对应的低通滤波器,清零ADC,然后触发一次带N次累加的采样。
采样时序是动态范围的关键。如果本振还没锁定就开始采样,测出来的幅度值会随机跳。ADF4351的锁定时间与环路滤波器带宽有关,我用的环路滤波器带宽设为10kHz,锁定时间约2毫秒,所以在每次频率切换后我至少等待3毫秒。DDS的稳定时间短一些,但也要留够50微秒。实际我统一等待3毫秒,这样代码简单,扫频速度慢一些但可靠。VNA2要求不高,测一次1001点的扫频在1秒左右,已经能接受。
ADC我用的是24位,理论上动态范围能到120dB,但由于前端中频放大器增益平坦度和混频器噪声,实际有效动态范围在80dB左右。ADC的采样率只要中频带宽的两到三倍即可。中频带宽我设为15kHz,那么ADC采样率取50kSPS,每次采样100个点做平均,可以有效抑制随机噪声。
固件代码核心如下:
uint32_t set_frequency(uint64_t freq_hz) { // 根据频率选择信号源路径 if (freq_hz < 300000000ULL) { dds_set_freq(freq_hz); rf_switch_set(PATH_LOW); // 切到DDS+低通滤波器 } else { uint64_t vco_freq = freq_hz / 2; // 高频段用二倍频,先设VCO为该频率 adf4351_set_freq(vco_freq); rf_switch_set(PATH_HIGH); // 切到倍频+带通滤波器 } delay_ms(3); // 等待锁相环锁定和滤波器稳定 return 0; }这段代码里,rf_switch_set是控制射频开关的宏,PATH_LOW和PATH_HIGH对应两种信号路径。dds_set_freq和adf4351_set_freq分别是DDS和PLL的寄存器配置函数。要注意:切到低频时,如果DDS输出频率低于10MHz,需要额外调整低通滤波器的截止频率,我用的滤波器组里有一档专门覆盖1到10MHz,否则低频段会出现严重衰减。
4.2 上位机Python驱动:一条扫频指令的往返
上位机我用Python写的。USB通信采用bulk传输,下位机把数据打包成固定长度结构体。Python端的USB库直接用PyUSB,对于非标准PID的设备需要手动指定VID/PID。这里我踩过坑:Linux下普通用户没有权限访问USB设备,需要写udev规则,Windows下还要装驱动。如果驱动不对,设备枚举成功但端点无效。
一次扫频的指令封装成字节流:
def build_sweep_cmd(f_start, f_stop, points, if_bw): cmd = bytearray(32) cmd[0] = 0xA5 # 帧头 cmd[1] = 0x5A # 帧头校验 cmd[2] = 0x01 # 命令类型:扫频 cmd[3] = points & 0xFF # 点数低字节 cmd[4] = (points >> 8) & 0xFF struct.pack_into('<Q', cmd, 8, f_start) # 8字节起始频率 struct.pack_into('<Q', cmd, 16, f_stop) # 8字节停止频率 struct.pack_into('<H', cmd, 24, if_bw) # 中频带宽 return bytes(cmd)注意struct.pack_into的偏移量必须与下位机结构体定义严格一致,否则会解析出巨大错误的频率值。端序统一用小端,字符串无。上位机发送后,下位机开始逐点采样,每完成一个点就通过另一个bulk端点往回发送8字节的复数数据(实部4字节,虚部4字节浮点数)。上位机收满points个点后,才算一次扫频完成。
4.3 校准后数据处理:为什么必须用复数
很多人第一次接触VNA校准,以为只是把空载/短路/负载的值存起来,然后拿测量值减去校准值。其实不是减,是射频误差模型里的矢量比值运算。比如S11测的是反射波的复数与入射波复数之比,反射波和入射波都是复数向量,仅仅用幅度校准无法修正相位偏移。
VNA2校准采用单端口SOLT简化版:分别测量开路、短路、负载三个标准件的反射系数,然后通过误差模型解出方向性误差、源失配误差和反射跟踪误差。这个过程需要把ADF4351扫频范围内的每个频点对应的复数数据都记录下来,存成三个复数数组。使用时,按下面的公式修正:
def solt_correct(raw, e00, e11, e10): # raw是原始测量复数 # e00是方向性误差,e11是源失配,e10是反射跟踪 # 典型的单端口误差模型:S11 = (raw - e00) / (e10 + e11 * (raw - e00)) return (raw - e00) / (e10 + e11 * (raw - e00))这里的e00、e10、e11三个误差项在校准时解出,背后是三个标准件的复数测量结果。实际操作中,我不会在python里做这个计算,而是把校准参数发给下位机,下位机在每个点实时计算后返回修正结果,因为这样后续如果要加IF滤波或降低采样率,上位机不用变,且实时性更好。
复数处理是VNA的核心,也是第一版翻车的地方。第一版我为了省事,用了双通道幅度检波器,然后单独测相位差,结果温度和频率变化时,两个通道的增益漂移不一致,校准后依然残留下几dB的纹波。VNA2直接采集中频复数,所有误差校准都基于原始复数,纹波问题才真正解决。
5. VNA2调试与校准避坑:我从第一版翻车换来的经验
5.1 现象:低频段S11曲线乱跳
第一版VNA在1MHz到10MHz范围内,测一个50欧姆负载,S11曲线不是平坦的,而是像锯齿一样上下抖动,幅度最大变化超过3dB。换了好几个电阻负载都一样。检查定向桥的每个焊点,没有虚焊。后来在示波器上观察DDS输出波形,发现低频段DDS的输出幅度有非常缓慢的起伏,周期约几毫秒。
原因:DDS的DAC输出在低频时,内部滤波器无法完全抑制采样时钟的镜像,这些镜像信号与主信号叠加,在测量频点附近形成低频率的差拍。因为扫频时间很短,差拍表现为“抖动”。解决:低频段必须加无源低通滤波器。我的滤波器截止频率设为最高输出频率的2.5倍,并且在滤波器前面用了放大器级联,确保DDS的输出电平在桥的动态范围内。另外,DDS的更新时钟不能太低,我用500MHz采样时钟,低频输出时可能触发SFDR问题,所以把DDS的参考时钟加了抖动模式,SFDR改善了约15dB。
5.2 现象:6GHz附近动态范围塌陷
VNA2高频段做到5.5GHz以上,测S21时,直通连接线全程,但得到的动态范围从80dB掉到60dB,而且噪声底抬高。一开始怀疑倍频器输出功率不够,用功率计测倍频器输出发现正常。后来把频谱仪接到混频器的RF端口,看到本振泄漏特别大,混频器出现拒斥不良。
原因:二倍频器后的带通滤波器中心频率偏了,导致本振(从ADF4351直接来的基波)没有被抑制,而是直接串入混频器。因为微带带通滤波器的加工精度受板材介电常数误差影响,我按1GHz对应线宽算的滤波器,实际中心频率偏移了约200MHz。解决:带通滤波器改用介质谐振器或贴片LC器件,不用微带。虽然插损稍大,但频率一致性很好。另外,混频器的LO端口和RF端口之间原本应该隔离,如果PCB布局不走成垂直方向,隔离度会下降。我重新布局后,把LO走线绕到板边远离RF走线,隔离度恢复了近20dB。
5.3 现象:USB枚举失败和广播风暴
连接USB后,电脑不识别设备,设备管理器中看到的未知设备或者枚举到一半断开。用示波器抓D+和D-波形,发现波形有回沟,幅值不到400mV。这是USB信号完整性问题。原因:主控芯片到USB座之间走线太长,且没有做阻抗匹配。我的板子是两层板,差分线宽间距不好控制,走线过长后信号反射严重。
解决:加了一个USB ESD保护管,把串联电阻改为22欧姆,并在差分对下方铺设完整的地平面。两层板上,尽量缩短USB走线,必要时可以牺牲一点美观把USB座放在主控芯片正上方。还有一个坑:USB线缆用劣质长线也会导致枚举失败,换一根几十厘米的优质线缆就好。这里不是玄学,USB高速对线材要求确实高。
5.4 现象:校准后仍然有纹波
做完SOLT校准后,测同一个空气线或直通件,S参数曲线依然呈现周期性的涟漪,周期约等于端口线缆电长度的两倍。这说明校准未能完全消除端口不匹配。原因:校准件本身的质量不过关。我用的开路和短路校准件是自己车出来的,开路件的寄生电容和短路件的电感都会让标准件模型失真。另外一个原因是校准时的线缆与测量时的线缆长度不一致,导致误差模型中的参考平面不同。
解决:校准件至少要用标准的开路、短路、负载校准件,如果买不到,可以用精密转接头自制,但要准确知道其寄生参数。更实际的办法是做完SOLT校准后,测量一个已知的空气线,再调整“端口延”参数。端口延时的作用是在不重新校准的情况下修正测量参考面。它本质上是一个相位补偿,公式为相位补偿量等于2×频率×电长度/光速。具体操作时,逐段调整延时,让已知负载的S21相位变成平坦的0°或180°,纹波就能压下来。
6. 把VNA2用得更好的几个进阶习惯
VNA2的硬件和校准都稳定之后,我总结出几个很实用的使用习惯。首先是“先看稳定性再测数据”。每次开机后,我先不接DUT,直接测一个50欧姆负载的S11,连续扫五次,看曲线重合度。如果五次曲线抖动超过0.1dB,说明还没热稳定,等几分钟再测。射频仪器尤其不能一上电就测,本振的相位噪声和混频器增益都需要时间稳定,这个习惯帮我避免了很多“假故障”。
第二个习惯是“校准和测量之间不要碰线缆”。SOLT校准后,我通常会把线缆固定住,用胶带粘在桌面上,防止线缆弯曲导致电长度变化。哪怕移动1毫米,相位也可能变化好几度。如果需要改变测量路径,宁可重新校准一次,不图省事。另外扫频点数不是越多越好,点数多扫得慢,中频带宽要降低才能保证动态范围。我一般设置为401点,中频带宽15kHz,扫频时间约0.8秒,曲线已经足够平滑。再增大点数,除了看起来精细,对真实分辨率的帮助不大,因为VNA2的硬件分辨率有限。
最后一个技巧是“用VNA2验证仿真模型”。我经常在ADS里仿真一个滤波器的S参数,然后实际焊一个在VNA2上测,把Touchstone文件导出后对比。如果仿真和实测的低频纹波形状一致,说明电路模型是准的;如果差异大,往往是因为模型里的寄生电容没建对。VNA2的端口延长特性在这种对比中非常有用,它可以把测试夹具的延时去除,让实测结果更接近理想参考面。
我已经养成了一个习惯:每次测量异常,先不怀疑VNA2硬件,而是先看数据文件里的相位曲线。如果相位在频带内呈现周期性的锯齿,八成是参考面和校准件的问题;如果相位是随机的,才去查硬件链路。这套排查顺序来自踩了几次坑的教训,帮你少走弯路。希望帮到你。
本文还有配套的精品资源,点击获取