简介:面向微波工程、射频电路与材料测试相关学习者,这份压缩包提供基于 HFSS 仿真结果反演介电常数的完整 MATLAB 处理方案。脚本围绕 S 参数(S11、S21、S12、S22)自动导入与解析,结合复折射率换算提取介电常数实部、虚部,系统覆盖从散射参数到材料电磁参数的完整换算流程,可有效弥补手动处理仿真数据的繁琐。压缩包共 2 个文件,均为 .m 脚本,整体仅 1KB,轻量而完整,可直接读取 HFSS 导出的 ASCII 格式数据运行,也可根据具体模型修改参数。已有 1881 人学习,适合科研工程师、研究生与高年级本科生在天线、滤波器、微波器件设计中快速评估材料电磁特性。借助该方案还能基于 Debye、Cole-Cole 等模型完成随频率变化的介电常数拟合,为微波器件仿真、信号完整性分析与损耗评估提供可靠参数输入。
1. 为什么用S参数反演介电常数
用HFSS的S参数反演介电常数,是射频材料测试中最实用的方法之一。介电常数并不能像电阻那样用万用表直接触碰,尤其是毫米波频段,网络分析仪探头接触本身就引入误差。常规做法是把待测介质做成特定厚度的薄片,放入仿真软件建立的传输线夹具中,用HFSS扫出S11、S21,再借助MATLAB脚本把S参数还原成复介电常数。这个思路同时覆盖两个场景:验证PCB板材来料一致性,把介质损耗参数填回滤波器或天线仿真。适合负责板材选型、介质谐振器设计以及耦合线带通滤波器调试的工程师,也能用来校对实测夹具的误差预算。
2. HFSS中S参数提取的结构与端口设置
要让反演结果落在5%误差以内,仿真阶段必须先答对三个问题:用什么传输线结构,激励端口怎么设,导出的S参数用什么格式。许多教程直接给公式,忽略了HFSS输出数据本身的质量。端口参考面没校准、扫频点太稀,都会让后续MATLAB里算出带振荡的损耗正切。
2.1 选择适合反演的传输线结构
最常用的夹具是微带线和带状线。微带线的上方是空气,电磁场分布并不完全集中在介质内,用S参数直接反演得到的是有效介电常数,后续还要做保角校正才能换回材料真实值,误差链比较长。带状线把样品夹在上下地平面之间,除了边缘场外,场基本集中在被测介质中,反演关系更直接。如果样品能压成薄片,我一般会优先选带状线,或者用带地孔的差分线结构,这与hfss多端口带状线设计里的经验一致。多端口结构还能顺便提取材料的各向异性,但端口数量增加后,交叉耦合会让S21在低频段出现非预期波纹。
无论哪种结构,夹具模型的尺寸必须精确,尤其是介质厚度h和导体宽度w。加工公差0.02mm在18GHz时就会让损耗正切出现可观的偏差。建模型时不要把“理想薄片”填成0厚度,那会让波阻抗计算在数值上失效。
2.2 wave port、deembed与参考面
HFSS中馈电方式应选wave port,而不是lumped port。wave port能唯一确定模式特性,尤其适合带状线主模。但wave port的参考阻抗不是默认50Ω,而是由端口尺寸间接决定的特性阻抗。反演过程只依赖S参数的幅度和相位,理论上参考阻抗不影响介质参数结果,但如果之后的MATLAB脚本里有归一化到50Ω的操作,就得先在HFSS里执行一次端口阻抗重归一化。
wave port与样品端面之间一般要保留一小段直通传输线,用于消除高次模。这段线在反演中相当于延长了样品,所以必须在HFSS里用波端口的deembed功能把参考面平移回样品边缘。deembed的距离就是直通段长度,正负号按照端口法向方向确认。漏掉这一步时,S21相位会附加与频率成正比的线性项,反演出的ε虚部会随频率抬升,容易被人误判成材料损耗。hfss波端口的deem功能在操作面板上叫“Deembed”,设定好距离后再看S11相位,理想情况下在截止频率以下应近似线性且延迟量等于该段长度。
2.3 扫频参数与边界条件
对于完全封闭的带状线,用理想导体边界即可,不需要辐射边界。微带线模型里则需要空气盒,并在HFSS中使用自动生成辐射边界,把盒顶高度设置在最高频率波长的四分之一以上。辐射边界不会显著影响S参数幅度,但会影响高频端的S11相位,尤其是介质损耗较小时更明显。
扫频类型建议用离散列表,步进不要超过样品厚度对应相移的限制。下表是我处理2-18GHz频段常用的一组参数。
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 材料样品厚度 | 0.2-1.0 mm | 太薄对相位分辨差,太厚出现半波谐振 |
| 频率范围 | 2-18 GHz | 受制于夹具尺寸和波导截止 |
| 扫频点数 | 200-400 | 点数过少会导致分支选择困难 |
| 求解频率 | 1.5倍中心频率 | 兼顾网格精度和计算时间 |
| 导出数据格式 | Real/Imag | 避免在MATLAB里做度到弧度转换 |
“hfss的扫描角是什么意思”和这里的扫频不同,那是指far field扫描角,用于天线方向图。材料反演不需要设置扫描角,只关注频率扫点即可。扫频点越密,后续相位展开越容易,但仿真时间也线性增长。一般200个点足够。
2.4 导出S参数的格式要求
仿真完成后,在HFSS结果右键导出矩阵,选择ASCII格式并保存为.s2p。建议在导出设置里选中复数R/I格式,而不是Magnitude/Angle或dB。R/I格式直接给出实部和虚部,MATLAB读取后无需角度展开。Touchstone文件头部会有类似# HZ S RI R 50的标记,其中RI表示实部虚部。若导出为MA(幅度角度),角度单位是度,需要在脚本里换算成弧度。文件内容通常是第一列频率,后面依次是S11实部、虚部、S21实部、虚部、S12实部、虚部、S22实部、虚部。要注意端口排列顺序,不要误把S21和S12位置搞混,对于互易网络两者应相等,但若差值超过1e-9,说明仿真网格或端口设置不对称。
3. MATLAB读取HFSS S参数脚本怎么写
压缩包里的Untitled.m和Untitled1.m,常见分工是前者负责读取和显示原始S参数,后者实现反演。读取脚本最忌讳写死格式,因为HFSS不同版本导出的文件列数、注释行数量都有差异。我通常写一个可复用函数,先识别头部标记,再自动分配数据列。
3.1 解析Touchstone/ASCII文件
HFSS导出的.s2p文件虽然是行业标准,但有时保存为.rtdata时会在数据段之前多出几行功率和端口信息。无论哪种格式,文件前半部分都包含以#开头的选项行,以及以!或%开头的注释。数据段则是一行一个频点,列数固定。
读取时的第一个关键决定是“先读满整行再拆数”。不能直接用textscan跳过,否则遇到可变数量的空白或换行会导致错位。我习惯逐行读取,判断行首字符,再从数据行中解析浮点数。
3.2 读取函数read_hfss_s2p
下面这段MATLAB代码可以处理HFSS导出的RI和MA两种常见格式。
function [f, S11, S21] = read_hfss_s2p(filename) fid = fopen(filename, 'r'); if fid == -1 error('cannot open file: %s', filename); end fmt = 'RI'; % 默认RI格式 data = []; while ~feof(fid) line = fgetl(fid); if isempty(line) continue; end if line(1) == '#' % 选项行,例如 # HZ S RI R 50 tokens = regexp(line, '#\s*\S+\s+\S+\s+(\w+)', 'tokens'); if ~isempty(tokens) fmt = tokens{1}{1}; end continue; elseif line(1) == '!' || line(1) == '%' continue; % 注释行 end vals = sscanf(line, '%f').'; if isempty(vals) continue; end if length(vals) >= 9 % 2端口数据至少9列 data = [data; vals(1:9)]; end end fclose(fid); if isempty(data) error('no data parsed'); end f = data(:,1); switch upper(fmt) case 'RI' S11 = data(:,2) + 1i * data(:,3); S21 = data(:,4) + 1i * data(:,5); case 'MA' mag11 = data(:,2); ang11_deg = data(:,3); S11 = mag11 .* exp(1i * ang11_deg * pi/180); mag21 = data(:,4); ang21_deg = data(:,5); S21 = mag21 .* exp(1i * ang21_deg * pi/180); otherwise error('unsupported format %s', fmt); end end这段代码的可复用点在于:底部用fmt决定S参数构造方式,而不是每种格式写一套循环。line(1) == '#'判断头部,sscanf对整行解析,vals(1:9)只取前9列,避免少数文件中出现额外的归一化功率列。如果您的文件只有6列(单端口或非标准),需要把判断条件改为length(vals) >= 5,并调整列索引。这个函数返回的S11和S21已经是复数向量,相位单位是弧度,后续可直接用于反演。
3.3 数据清洗与插值
HFSS离散扫频得到的频点本身是均匀的,但若使用插值扫频,频点间隔可能变化,反演公式中对频率求导或做相位展开时会不够平滑。此时需要对f网格做一次线性插值。在插值前,先把S11幅度大于1的异常值限幅到0.9999,防止在后续开根号时出现负数判别式。
S11(abs(S11) > 1) = 0.9999 .* exp(1i * angle(S11(abs(S11) > 1)));限幅不会影响正常频段,但能避免少数边界频点上HFSS数值振荡导致复数开方分支突变。随后检查S21的相位是否在相邻频点内连续移动。如果出现明显的跳变,先不要插值,回到HFSS确认deembed距离。这个工作放在读取脚本中很合适,我一般会把Untitled.m写成:先调用读取函数,然后绘制S11和S21的幅度相位图,快速判断数据是否可信。
3.4 用Untitled.m和Untitled1.m划分任务
如果只有两个脚本,我会把读取、检查、插值放在Untitled.m,把第四章的反演算法放在Untitled1.m。这样跑通一个已知材料案例后,换新材料只需改文件路径,不必重新审查算法代码。Untitled1.m的入口参数至少应包括:S11、S21、频点向量、样品厚度d。不要把文件名路径写死在算法脚本里,否则交接给同事时会不断改动主程序。
4. S参数反演介电常数的公式与代码
这一章是整个流程的核心。反演的基本思路是先把S参数转换成均匀介质段的传播常数γ和归一化波阻抗Z,再由Z和γ反推复介电常数。整个过程可以用一条链路表示:S参数到ABCD矩阵,ABCD到γ和Z,最后到ε。
4.1 由S参数到复折射率和波阻抗
假设样品是均匀无磁材料,厚度为d,嵌入在传输线中间。此时二端口网络是对称互易的,S11等于S22,S21等于S12。根据S参数到ABCD矩阵的转换关系:
A = (1 - S11^2 + S21^2) / (2 S21) B = ((1 + S11)^2 - S21^2) / (2 S21) C = ((1 - S11)^2 - S21^2) / (2 S21)
对于均匀传输线段,A等于cosh(γd),归一化波阻抗Z等于sqrt(B/C)。于是有:
γ d = acosh(A) Z = sqrt(B/C)
自由空间波数k0 = 2πf/c0,复折射率n与γ的关系为γ = j k0 n。MATLAB中j表示虚数单位,因此n = -jγ/k0。在μr=1的假设下,介电常数由ε = n / Z得到。这里的除法是逐元素复数除法,不是矩阵求逆。
我提供一个可直接运行的核心循环:
function [epsilon, n, gamma] = extract_dk(f, S11, S21, d) c0 = 2.99792458e8; S11 = S11(:); S21 = S21(:); f = f(:); N = length(f); n = zeros(N,1); gamma = zeros(N,1); epsilon = zeros(N,1); for idx = 1:N k0 = 2*pi*f(idx)/c0; % ABCD参数,注意S21可能在某频点接近0 A = (1 - S11(idx)^2 + S21(idx)^2) / (2*S21(idx)); B = ((1 + S11(idx))^2 - S21(idx)^2) / (2*S21(idx)); C = ((1 - S11(idx))^2 - S21(idx)^2) / (2*S21(idx)); % 主分支gamma和Z gamma0 = acosh(A) / d; Z0 = sqrt(B / C); % 物理上取实部为正的阻抗分支 if real(Z0) < 0 Z0 = -Z0; end n0 = -1i * gamma0 / k0; % 按前一个频点选择折射率实部最近的分支 if idx == 1 m_best = 0; else m_candidates = -4:4; n_cand = n0 - m_candidates * c0 / (f(idx) * d); [~, m_best] = min(abs(real(n_cand) - real(n(idx-1)))); end n(idx) = n0 - m_candidates(m_best) * c0 / (f(idx) * d); % 与候选分支对应的gamma gamma(idx) = -1i * k0 * n(idx); epsilon(idx) = n(idx) / Z0; end end这段代码的关键在于分支选择。acosh返回的是主值,对应的γd可能在虚部上相差2π的整数倍,但实际传播常数的虚部应按物理连续性变化。代码中通过候选m值构造n的多个可能值,用“与上一频点折射率实部最接近”作为判据,这就是在频域内做相位展开。如果频点间隔太大,相邻点的实部差异仍会超过一个分支周期,此时应当减小扫频步进,而不是依赖算法去寻找。
Z0的符号也有讲究。对于无源介质,归一化波阻抗的实部应为正。如果开根号后实部为负,就取相反数。虚部符号会根据S参数方向约定自然给出,不要人为翻转。
4.2 多值性来源与扫频点选择
多值性来源于复对数函数。由于T = exp(-γd)在γd上加2πi的整数倍后T不变,S参数无法区分这些分支。换句话说,样品厚度d内每经过一个完整波长,相位就多一圈,但S参数相同。因此扫频点越密,相邻频点之间的折射率变化越小,分支选择就越可靠。
下表总结了典型情况下的分支周期:
| 频率 | 样品厚度 | 有效折射率约为3 | 相邻分支间隔(GHz) |
|---|---|---|---|
| 10GHz | 1mm | 3 | 10/(3*1) = 3.3GHz |
| 18GHz | 0.5mm | 4 | 18/(4*0.5) = 9GHz |
当分支间隔大于扫频带宽时,整个频段没有歧义,可以不做分支选择。但多数宽带测试的带宽远大于该间隔,所以分支处理不能省略。
4.3 损耗与Debye模型拟合
反演得到的是每个频点的复介电常数,实部是储能能力,虚部包含材料损耗。有时虚部会被参考面误差污染,表现为随频率线性下降或上升。为了提取真正的弛豫参数,我会用一个简单的Debye模型拟合复介电常数:
ε(f) = ε∞ + (εs - ε∞) / (1 + j f / f_relax)
在MATLAB中可以用lsqcurvefit拟合。虽然这不是反演必需步骤,但拟合后的εs和f_relax更适合作为HFSS仿真模型的输入。拟合时要排除频带两端各3个点,因为那些点受数值噪声影响最大。
4.4 对厚度和参考面误差的敏感性
反演公式中厚度d出现在γ的分母,所以d的误差直接影响折射率。厚度误差1%,折射率实部大约也偏差1%,但介电常数通过n^2形式影响时会放大到2%左右。所以样品厚度需要用千分尺测量,而不是依赖标称值。参考面误差会让S21相位偏离理想线性,表现为ε虚部出现与频率相关的斜率。检查方法:先看折射率实部是否平滑,再看虚部是否有明显的线性趋势。如果线性趋势与频率强相关,则大概率是deembed距离不准,而不是材料本身损耗。
顺便说一句,hfss中场计算器计算电压的用途在这里帮不上忙,反演不需要电场积分,老老实实用S参数最省事。
5. 工程验证与几个实用坑
最后的落地环节,重点讨论如何确认反演结果不是“算对了但数据错”。这套方法最容易被质疑的地方是:仿真S参数来自HFSS,反演脚本又来自MATLAB,两者单独看不出错,合在一起必须用一个已知材料闭环。
5.1 已知材料自校验流程
先在HFSS中建立PTFE介质模型,把介电常数设为2.08,损耗正切设为0.001,跑相同的扫频和导出流程,再调用第四章脚本反演。如果反演结果落在2.05-2.11之间,说明整个链路可信。我还习惯在HFSS里同时扫一个空气腔模型,理论上反演ε应为1.0。若空气腔结果偏离明显,多半是波端口deembed设置问题。
5.2 与网络分析仪实测S参数对比
网络分析仪测量差分线s参数时,需要用四端口校准或外接balun,过程比仿真麻烦得多。但实测数据反而更容易暴露夹具问题。实测S参数中包含接头、焊盘、过渡段的寄生网络,直接反演会得到明显偏大的损耗。我一般会先做TRL校准,再用去嵌入方法把参考面移到介质段两端。如果实测与仿真的S21相位在2GHz处偏差超过5度,反演出来的介电常数就不具备参考价值。
5.3 反演结果异常的排查
如果ε实部小于1或虚部为负,可按以下顺序检查:
| 现象 | 排查步骤 |
|---|---|
| ε实部小于1 | 检查S11是否被限幅过度,检查Z0分支符号 |
| 虚部随频率线性增大 | deembed距离设置偏大或偏小 |
| 曲线抖动剧烈 | 扫频点数太少,分支选择miss |
| 高频端发散 | 样品厚度接近多个半波长,缩小频率范围 |
| 与已知值偏移固定比例 | 厚度尺寸输入错误,单位换算问题 |
最后一个有效技巧是:在反演前先对S21做群延迟检查。群延迟为相位对频率的导数,如果群延迟在带内出现剧烈波动,说明HFSS扫频步长太大或部分频点求解未收敛。此时直接反演会发现折射率虚部出现尖刺。先把扫频点数加密,再做反演,会比任何数学平滑都有效。这样处理后的结果,基本可以直接用于HFSS材料库更新,不需要额外修正。
本文还有配套的精品资源,点击获取