资讯动态

基于FFT的ADC/DAC动态性能指标SNR/ENOB Matlab计算程序

发布时间:2026/10/26 18:56:01 来源:尧图企业网站定制
简介这份 MATLAB 计算程序面向信号处理、ADC 测试与数字通信方向的学习者和工程师围绕 SNR、SNDR、THD、ENOB、SFDR 五项常用指标提供可运行的评估示例适合课程实验、器件性能对比和算法验证。压缩包共 2 个文件含 1 个 m 脚本与 1 个 txt 数据文件大小约 4KB脚本负责频谱分析与指标计算txt 提供待处理样本便于替换实测数据后复现结果。已有 4558 人学习下载说明其在相关指标计算场景中具有一定参考价值。读者可借此理解五项指标的定义、功率比关系及频域分析思路并对照脚本梳理从时域数据到 FFT、谐波与杂散提取再到结果输出的完整计算链路为信号链性能评估和结果复核提供可直接参考的模板。1. 从一张频谱截图说起这套 SNR matlab 计算程序到底算什么有人拿着一张某数据采集板的频谱截图问这块板子到底几 bit 有效。截图上有底噪、有谐波、有杂散但谁也说不清该读哪根线。这套 SNR matlab 计算程序处理的就是这件事把一段 ADC/DAC 输出码值丢进去它按 FFT 法算出 SNR、SNDR、THD、ENOB、SFDR 五个指标直接给出可以写进测试报告的数值。适合三类人做数据采集、音频、射频前端需要验收 ADC 指标的硬件工程师写完 RTL 要做行为级验证的数字设计以及拿实测数据回推系统性能的算法同学。不需要装任何工具箱核心就一个主函数加一个窗函数纯 MATLAB 基础语法跑起来门槛很低。2. 指标口径先对齐五个数字背后的功率归属算法写错十行不如口径错一个字。同样一段数据SNR 差 1.5 dB、ENOB 差 0.3 bit八成是哪部分功率算噪声、哪部分算谐波没谈拢。先把账算清楚代码才站得住。2.1 SNR、SNDR、THD、SFDR 各自把谁扣掉把这几个指标拆开看本质是对同一份频谱做不同的功率归集。信号功率记作 Ps谐波总功率 Ph其余噪声含杂散功率 Pn指标定义式通俗说法SNR10·log10(Ps / Pn)只扣谐波和 DC剩下的都算噪声SNDRSINAD10·log10(Ps / (Pn Ph))噪声和谐波一起扣最悲观THD10·log10(Ph / Ps)谐波占总信号的比例负值SFDR10·log10(Ps / Pmax_spur)最大那根杂散离信号多远含谐波ENOB(SNDR − 1.76) / 6.02把 SNDR 折算成等效位数有一处容易被忽略SNR 的定义里谐波是不计入噪声的所以理想正弦输入下 SNR 永远优于 SNDR。SFDR 里的杂散通常包含谐波因为最坏情况下最大的那根毛刺往往就是二次或三次谐波。如果只统计非谐波杂散得出的 SFDR 会虚高好几 dB这在验收场合会被质疑。ENOB 的 1.76 和 6.02 不是拍脑袋来的理想量化器的量化噪声均匀分布在 ±0.5 LSB 内功率为 q²/12正弦满量程输入功率为 (2^(N−1)·q)²/2两者一比再取对数就得到 6.02N 1.76。所以 12 bit 理想 ADC 的 SNR 上限是 74.0 dBENOB 上限就是 12。实际芯片能到 11.2 bit 已经算做得不错了。2.2 相干采样与窗函数直接 fft 会翻车的原因FFT 只对周期延拓的信号成立。如果采样长度 N 里装的不是整数个输入周期首尾接不上频谱就会漏能量从信号 bin 向两侧扩散本来干净的底噪抬起来SNR 直接虚低好几个 dB。这就是非相干采样的经典问题。工程上有两条路。第一条是相干采样让输入频率精确落在 FFT 的 bin 上N 8192; % 采样点数取 2 的整数次幂 fs 100e6; % 采样率 M 37; % 窗内周期数取奇数 while gcd(M, N) ~ 1 % 必须与 N 互质否则某些谐波会落到同一 bin M M 2; end fin M * fs / N; % 相干采样下的输入频率窗内正好 M 个整周期这里 M 与 N 互质是关键。如果 M 和 N 有公因数比如 M 64、N 8192那么第 128 次谐波会精确折回信号 bin 上谐波和信号混在一起THD 彻底失真。取奇数且互质能让所有谐波都落在不同于信号的 bin 上。第二条路是加窗。实测时信号源和被采系统往往不同源很难做到严格相干这时候必须加窗压制旁瓣泄漏。代价是主瓣变宽且噪声功率被窗放大了需要按等效噪声带宽ENBW修正回来窗类型相干增益ENBWbin主瓣宽度bin最高旁瓣dB矩形 rect1.0001.002−13汉宁 hann0.5001.504−31汉明 hamming0.5401.364−43四项布莱克曼-哈里斯0.3592.008−92汉宁窗的 ENBW 是 1.5意味着加窗后噪声功率被放大了 1.5 倍换算成 dB 就是 1.76 dB。如果不做修正同一段 12 bit 数据算出来的 SNR 会从 74 dB 掉到 72.2 dB 左右ENOB 少 0.3 bit。这个偏差稳定复现、非常迷惑人属于典型的踩坑点。窗的选择按场景定做研发验证、追求 THD 精度用四项布莱克曼-哈里斯旁瓣压到 −92 dB代价是主瓣宽、bin 分辨率下降做产线快速验收汉宁窗够用相干采样且信号源质量好的时候直接用矩形窗省掉所有修正。2.3 谐波折叠与 bin 定位THD 最容易算错的一步谐波不是想出现就出现的。二次谐波频率 2·fin 一旦超过 fs/2就会被采样定理折叠回低半频。比如 fin 0.4·fs二次谐波 0.8·fs 折回 0.2·fs三次谐波 1.2·fs 折回 0.2·fs1.2 − 1.0二次和三次谐波撞在同一个 bin 上。正确的做法是在 bin 域上算不要用频率域算k0 k0_rel 1; % 信号所在 bin1 基 kh mod(h * (k0 - 1), N); % 第 h 次谐波的 bin 号按整数倍扩展 if kh N / 2 kh N - kh; % 超过 Nyquist 折回低半频 end这条mod再折叠的两行是整个程序里最少写、也最容易出错的逻辑。漏掉折叠高次谐波会被算到不存在的频点上THD 偏低折叠方向搞反谐波 bin 可能落到 DC 附近被当成噪声扣掉THD 同样失真。还有一个边界情况当 fin 接近 fs/2 时二次谐波会折回并紧贴信号主瓣甚至落进主瓣范围内。此时谐波 bin 和信号 bin 重叠程序必须把它从谐波列表里剔除否则会把信号能量重复扣一次SNDR 虚低。这属于极端工况代码里要显式判断不能假设谐波一定远离信号。3. 目录与核心函数拆解一次 FFT 怎么把五个指标算出来整个包结构相当扁平没有依赖没有工具箱两个文件撑起全部计算外加一个演示脚本。这种结构对二次开发很友好也方便直接拷进别的工程里。3.1 文件清单与调用关系文件职责关键输入adc_dynamic.m主入口完成 FFT、功率归集、指标计算码值向量、fs、finlocal_window.m生成窗序列并返回相干增益、ENBW窗名、点数 Ndemo_ideal_adc.m用理想量化器造已知答案的数据自测无调用链路只有一层演示脚本造数据主函数调用窗函数取窗参数然后一路算到底返回一个结构体。之所以不做成类是因为这类计算通常是批量脚本里的一环函数式调用写起来更顺手parfor并行也简单。主函数前几行是参数声明用inputParser做名称-值传参。这样调用方可以只写关心的参数其余走默认值function res adc_dynamic(code, fs, fin, varargin) %ADC_DYNAMIC FFT 法计算 ADC/DAC 的 SNR、SNDR、THD、SFDR、ENOB % code : 输出码值列向量已去掉上电建立段长度建议为 2 的整数次幂 % fs : 采样率单位 Hz % fin : 输入正弦频率单位 Hz相干采样时应满足 fin M*fs/N % 名称-值参数 % Bits 量化位数默认 12 % FullScale 满量程码值默认 2^(Bits-1) % Window 窗函数默认 hann % Harmonics 统计到第几次谐波默认 5 % SigBinSpan 信号主瓣单侧 bin 数默认 1 p inputParser; p.addParameter(Bits, 12); p.addParameter(FullScale, []); p.addParameter(Window, hann); p.addParameter(Harmonics, 5); p.addParameter(SigBinSpan, 1); p.parse(varargin{:}); opt p.Results; if isempty(opt.FullScale) opt.FullScale 2^(opt.Bits - 1); end x double(code(:)) / opt.FullScale; % 归一化到满量程功率即 dBFS 口径 N numel(x); if 2^nextpow2(N) ~ N warning(点数 %d 不是 2 的幂存在栅栏效应建议重采或截断, N); end % ---- 1. 去直流 加窗 ---- [xw, cg, enbw] local_window(x, opt.Window); xw (xw - mean(xw)) .* local_win_seq(opt.Window, N); % ---- 2. 单边幅度谱 ---- X fft(xw) / N; P abs(X(1:N/21)); P(2:end-1) 2 * P(2:end-1); % 单边谱补偿DC 与 Nyquist 不乘 2 P P / cg; % 相干增益修正恢复真实幅度 % ---- 3. 定位信号 bin ---- [~, k0] max(P(2:end)); % 跳过 DC bin 找峰值 k0 k0 1; sigIdx max(2, k0-opt.SigBinSpan) : min(N/21, k0opt.SigBinSpan); % ---- 4. 定位谐波 bin含折叠---- hIdx []; for h 2:opt.Harmonics kh mod(h * (k0-1), N); if kh N/2 kh N - kh; % 超过 Nyquist 的谐波折回低半频 end if kh 2 || kh N/21 continue; end hIdx [hIdx, max(2, kh-opt.SigBinSpan) : min(N/21, khopt.SigBinSpan)]; %#okAGROW end hIdx setdiff(unique(hIdx), sigIdx); % 谐波与信号重叠时剔除 % ---- 5. 功率归集 ---- P2 P.^2; Ps sum(P2(sigIdx)); Ph sum(P2(hIdx)) / enbw; % 谐波是谱线这里保持与噪声同口径 mask true(size(P2)); mask(1:3) false; % 跳过 DC 及其泄漏 mask(sigIdx) false; mask(hIdx) false; Pn sum(P2(mask)) / enbw; % 宽带噪声要按 ENBW 修正 % ---- 6. 指标计算 ---- res.SNR 10*log10(Ps / Pn); res.SNDR 10*log10(Ps / (Pn Ph)); res.THD 10*log10(Ph / Ps); spur P2; spur(sigIdx) 0; spur(1:3) 0; res.SFDR 10*log10(Ps / max(spur)); res.ENOB (res.SNDR - 1.76) / 6.02; res.Ps Ps; res.Pn Pn; res.Ph Ph; res.f (0:N/2) * fs / N; res.PdB 20*log10(P / max(P)); res.fin_meas (k0 - 1) * fs / N; res.ENBW enbw; end逐段说清几个关键决策。归一化放在最前面。x / opt.FullScale之后所有功率都是相对满量程的比例算出来的 Ps 直接就是 dBFS 口径。如果跳过这一步Ps 是绝对码值平方数量级和理论值对不上ENOB 会差好几个 bit 且没有任何报错提示属于血泪经验。单边谱补偿的边界处理。P(2:end-1) 2*P(2:end-1)把负频率能量折到正频率但 DC 和 Nyquist 这两个 bin 是自共轭的不能乘 2。写成2*P全乘一遍DC 会翻倍低频杂散全被抬高SFDR 直接崩。SigBinSpan决定了信号主瓣吃掉几个 bin。相干采样 矩形窗时取 0 也行信号能量全在单 bin非相干采样 汉宁窗时主瓣有 4 个 bin 宽取 1 到 2 才不漏能量。取少了信号功率被低估SNR 虚高看起来性能很好实际是把信号能量算进了噪声。这个参数必须和窗类型绑死不能一套值走天下。谐波功率除以 ENBW 这一行不同人的口径不一样。严格讲谐波是确定性谱线加窗后被相干增益修正即可不需要 ENBW 修正噪声是宽带的必须除。但工程实现里图和噪声保持同一量纲很多代码统一除以 ENBW好处是 THD 和 SNDR 的一致性更好坏处是 THD 会系统性偏 1.76 dB。两种都能自洽关键是同一批报告里只能用一种口径别换人换算法。SFDR 的spur里保留了谐波位置因为 SFDR 定义里最大杂散通常就是谐波。如果只看非谐波杂散那是另一个指标不要混叫 SFDR。3.2 窗函数模块三个返回值一个都不能少function [w, cg, enbw] local_window(name, N) % 返回窗序列 w、相干增益 cg、等效噪声带宽 enbw单位bin n (0:N-1); switch lower(name) case rect w ones(N,1); case hann w 0.5 - 0.5*cos(2*pi*n/N); % periodic 形式适合 FFT case hamming w 0.54 - 0.46*cos(2*pi*n/N); case blackmanharris a [0.35875 0.48829 0.14128 0.01168]; w a(1) - a(2)*cos(2*pi*n/N) ... a(3)*cos(4*pi*n/N) - a(4)*cos(6*pi*n/N); otherwise error(未知窗函数: %s, name); end cg sum(w) / N; % 相干增益信号幅度被压低的倍数 enbw N * sum(w.^2) / sum(w)^2; % 等效噪声带宽单位 bin end窗序列用的是2*pi*n/N的 periodic 形式而不是2*pi*n/(N-1)的 symmetric 形式。做 FFT 必须用 periodic否则窗在首尾不连续泄漏压不下去等于白加。这个细节在造窗函数时差一个分母频谱上就能看出旁瓣抬高十几 dB。cg和enbw是这套程序能用对的前提。信号幅度除以 cg 恢复真值噪声功率除以 enbw 恢复真实噪底两个修正对象不同、方向不同少一个都会让结果偏。4. 跑通流程先造已知答案的数据再换实测码值上手最快的办法不是拿实测数据硬跑而是先用理想量化器造一段答案已知的数据把链路跑通、把偏差范围摸清再去接真实采集文件。这样出问题时能立刻判断是算法错还是数据脏。4.1 用理想 ADC 自测验证算法链路理想 12 bit 量化器在相干采样下SNR 理论值 74.0 dBENOB 理论值 12。用它做基线能一眼看出代码有没有系统性偏差%% demo_ideal_adc.m fs 100e6; N 8192; bits 12; M 37; % 与 N 互质保证相干采样 fin M * fs / N; t (0:N-1) / fs; amp 0.5; % 相对满量程 -6 dBFS留足裕量 vin amp * sin(2*pi*fin*t); code round(vin * 2^(bits-1)); % 量化得到理想 ADC 输出码 code max(min(code, 2^(bits-1)-1), -2^(bits-1)); % 饱和截断 res adc_dynamic(code, fs, fin, Bits, bits, Window, hann); fprintf(SNR%6.2f dB SNDR%6.2f dB THD%7.2f dBc SFDR%6.2f dBc ENOB%5.2f bit\n, ... res.SNR, res.SNDR, res.THD, res.SFDR, res.ENOB);跑完对着下面这张表核一遍落在区间内就说明链路是干净的指标理论 / 参考值合理区间超出说明什么SNR74.0 dB73.0 ~ 74.0低于 73 查 ENBW 修正和主瓣 bin 数SNDR73.8 dB72.8 ~ 74.0明显低于 SNR 说明谐波没找准THD−85 dBc 以下−90 ~ −78高到 −60 查谐波折叠SFDR接近 SNDR72 ~ 78掉到 60 以下查 DC 附近杂散ENOB12.00 bit11.8 ~ 12.0低于 11.5 基本是先修噪声幅度取 0.5 满量程而不是 0.99是有意的。接近满量程时量化噪声和信号的相关性增强谐波会抬高同时也预留了实测系统增益误差的裕量避免输入稍大就削顶。做验收时如果要测满量程附近的性能再单独扫一遍幅度。4.2 接实测码值从二进制流到有符号向量实测数据一般是逻辑分析仪或 FPGA 抓的并行码流格式可能是十六进制文本也可能是打包的二进制。第一步永远是转成有符号十进制码值并做补码转换%% load_capture.m —— 读取十六进制码流并转有符号码值 bits 14; fid fopen(adc_capture.txt, r); raw textscan(fid, %s); fclose(fid); hexs raw{1}; n numel(hexs); code zeros(n, 1); for i 1:n v hex2dec(hexs{i}); % 按无符号解析 if v 2^(bits-1) % 最高位为 1说明是负数 v v - 2^bits; % 补码转有符号 end code(i) v; end code code(1025:end); % 丢掉前 1024 点避开上电建立段 code code(1:2^floor(log2(numel(code)))); % 截断到 2 的整数次幂这段里有三个动作每个都不能省。补码转换漏了负半周会被当成接近满量程的正数波形看起来像被整流过频谱上二次谐波暴涨THD 直接到 −20 dBc一看就知道数据脏了。丢掉前 1024 点是避开建立段。ADC 上电或量程切换后前几百个采样往往还没稳定混进来会让低频段出现鼓包SFDR 被一个假的近 DC 杂散决定。丢多少看具体器件一般抓 1/8 到 1/4 的长度就够。截断到 2 的幂是为了避免栅栏效应。点数不是 2 的幂时FFT 的 bin 宽度不均匀谱线落在两个 bin 之间会被劈成两半信号功率和噪声功率都算不准每次跑的结果还会抖。宁可贵一点重采也别拿非 2 的幂硬算。加载完之后把fin换成实测信号源的输出频率Bits和FullScale换成实际器件的参数直接调主函数即可。如果信号源和被采系统不同源、做不了相干采样把Window换成blackmanharrisSigBinSpan调到 3用宽主瓣换干净的底噪。4.3 出问题前的自检三个必看量跑完先别急着信数字扫一眼三样东西。码值范围。min(code)和max(code)应该落在 ±2^(bits−1) 内且没有长期贴着边界。贴着边界说明削顶了这时候算出来的 THD 是削顶失真不是器件本身的谐波。直方图。histogram(code, 64)看一眼正常正弦输入应该呈现两头高、中间低的反正弦分布对称且平滑。如果出现明显的双峰缺失或者单边堆积说明码值转换错了位或者有位线接反这类问题在频谱上表现为莫名其妙的杂散。频谱图。plot(res.f/1e6, res.PdB)把前几个大分量标出来确认信号峰、二次谐波、三次谐波的位置符合预期。如果看到一系列等间距的杂散多半是电源干扰或时钟馈通不是量化噪声这时候算出的 SNR 再准也没意义得先治板子。5. 避坑与排查让 ENOB 凭空少两三个 bit 的细节这套算法的坑集中在看起来对、其实偏了的地方。偏差往往不大1 到 3 dB但足以让验收结论反转。下面五条都是实际跑数据时反复遇到的按现象、原因、解决三步记。现象一同一批数据两个人算出的 ENOB 差 0.3 bit 以上。原因窗类型和信号主瓣 bin 数不一致。甲用汉宁窗取 ±1 bin乙用四项布莱克曼-哈里斯取 ±3 bin两者对信号功率的归集范围不同噪声底也差 1.76 dB 以上指标自然对不上。 解决把窗类型、SigBinSpan、Harmonics三个参数写进报告头和指标一起存档。更彻底的做法是在主函数里建立窗与主瓣宽度的映射表SigBinSpan不传时按窗自动取默认值杜绝人工不一致。现象二实测 SNR 比手册低 1.5 到 2 dB反复换数据都一样。原因加窗后没做 ENBW 修正。汉宁窗 ENBW 1.5噪声功率被放大 1.5 倍换算成 dB 正好 1.76。这个偏差稳定、可复现、不随数据变化非常像器件就是这个水平。 解决确认噪声求和那一步除以了enbw。可以把Window换成rect做对照实验矩形窗 ENBW 1如果两种窗算出的 SNR 差 1.7 dB 左右就是修正漏了。现象三THD 好到 −100 dBc 以下好得不像真的。原因谐波 bin 没做 Nyquist 折叠。mod(h*(k0-1), N)得到的是 0 到 N−1 的 bin 号大于 N/2 的部分必须折回否则会被当作不存在的频点直接跳过hIdx变成空数组Ph 0THD 趋近负无穷。 解决在谐波循环后加一句断言if isempty(hIdx), warning(未找到任何谐波 bin检查折叠逻辑); end。另外把hIdx对应的频点打印出来人工核一遍是否符合mod(h*fin, fs)的预期。现象四SFDR 被一根贴着 DC 的杂散决定频率只有零点几 MHz。原因DC 泄漏没清干净。直接fft不去均值DC bin 会溢出到邻近几个 bin即使去了均值加窗后 DC 的旁瓣仍会污染前几个 bin。程序里mask(1:3) false只跳过了 3 个 bin用四项布莱克曼-哈里斯窗时主瓣有 8 个 bin 宽3 个不够。 解决跳过 bin 的数量跟着窗走矩形窗跳 2、汉宁窗跳 4、四项窗跳 8。更稳妥的做法是在 FFT 之前先做一次一阶差分或者多项式去趋势把低频漂移压掉再进频谱。现象五仿真数据算出 11.5 bit实测数据只有 8 bit差得离谱。原因十有八九是数据加载环节。补码没转、满量程参数给错、前段建立点没去这三个里必中一个。曾经遇到过把FullScale设成 2^bits 而不是 2^(bits−1) 的情况所有功率都小了 6 dBSNR 看起来没变但 SFDR 和绝对幅度全错。 解决加载完先跑三行自检fprintf(min%d max%d mean%.2f\n, min(code), max(code), mean(code))。理想正弦输入下mean应该接近 0min和max绝对值接近但不相等。这一步花十秒能省掉半天。提示这套程序默认输入是干净的量化噪声场景。如果数据里混了电源干扰、时钟馈通、或者参考电压抖动算出来的 SNR 是系统 SNR而不是ADC SNR写报告时要注明测试条件别把板子的问题算到芯片头上。6. 二次开发把单次计算扩成扫频与双音测试单点计算只是起点。真正做器件评估要的是 SNDR 随输入频率的曲线、ENOB 随幅度的曲线、以及双音互调。这些都能在现有主函数上套一层循环不用改动核心计算。扫频是最常用的一层。关键是每个频点都要重新选相干频率不能直接拿目标频率硬算%% sweep_fin.m —— 扫输入频率画 SNDR 曲线 fs 100e6; N 8192; bits 12; Ms [37 101 251 509 997 2003 3001]; % 全部与 N 互质 sndr zeros(size(Ms)); enob sndr; for i 1:numel(Ms) fin Ms(i) * fs / N; % 就近取相干频点 t (0:N-1)/fs; code round(0.5 * 2^(bits-1) * sin(2*pi*fin*t)); r adc_dynamic(code, fs, fin, Bits, bits, ... Window, hann, SigBinSpan, 1); sndr(i) r.SNDR; enob(i) r.ENOB; end plot(Ms*fs/N/1e6, sndr, o-); grid on; xlabel(fin / MHz); ylabel(SNDR / dB);这里有一处取舍目标频率和相干频率之间会有偏差低频段相对偏差大高频段小。做曲线时要在报告里注明测试频率为就近相干频点否则别人复现时对不上数。如果非要用精确频率就得改用加窗 插值校正把SigBinSpan放大到 3代价是底噪抬高、动态范围压缩。双音互调是另一个常见需求用于评估 IMD3。做法是把两路正弦叠加后送进同一个量化器然后修改谐波统计逻辑——不再是h*fin的整数倍而是2*f1-f2、2*f2-f1这些互调分量。这块建议单独写一个calc_imd.m不要塞进主函数里加if分支否则主函数会越来越难读。互调分量的 bin 定位公式和折叠逻辑与谐波完全一致可以直接复用那段mod加折返的代码。再上一层是批量文件的批处理。实测往往一次抓几十个文件对应不同频率、不同幅度、不同温度。这时候把主函数改成静默模式去掉warning用parfor并行跑结果汇总成一张表导出到 Excel 或者 CSV。我在做这类批处理时习惯把每个文件的原始参数文件名、fs、fin、bits、窗类型和五个指标放同一行一旦某一行数据异常能立刻回查到具体是哪个文件出了问题不用重跑。最后一个技巧和验证有关。改完代码之后不要只拿实测数据看指标合不合理——实测数据没有标准答案改了也看不出来对不对。每次改完都拿理想量化器那组数据重跑一遍确认 SNR 还在 73 到 74 dB 之间、ENOB 还在 11.8 以上。这组数据是唯一能当后悔药用的基线。从那以后我每次动主函数都强制先走一遍理想数据自测再碰真实采集文件。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑