【射频测试工具】HTOOL-SA8T 手持频谱 & 信号发生器完整测评:硬件参数、操作教程、上位机与 SCPI 通信协议全解析
一、前言
在射频开发、无线模块调试、滤波器 / 天线 / 线缆损耗测试场景中,进口台式频谱仪价格高昂、体积笨重,传统简易手持设备又缺少内置信号源 + S21 网络分析功能,很难满足研发、维修、产线校准轻量化需求。
本文详细拆解一款国产一体化手持射频测试仪HTOOL-SA8T,设备集成频谱分析仪 + 射频信号源 + 简易矢量网络分析(S21),覆盖 13.5MHz~8.2GHz 全频段,支持本地触摸屏操作、PC 上位机远程控制、标准 SCPI 指令集自动化测试,适合射频工程师、硬件维修、物联网无线调试、学生实验使用。
下文分为硬件参数、机身操作、PC 上位机功能、SCPI 通信协议、实测应用场景、使用注意事项六大模块,完整可落地。
二、整机硬件规格与核心优势
2.1 基础概述
HTOOL-SA8T 是一体式手持式射频测试设备,频谱分析 + 信号发生器二合一,内置 S21 传输损耗 / 增益测量功能,金属屏蔽外壳,4 寸高亮 IPS 触摸屏,Type-C 充电 + 数据二合一,便携性极强。
2.2 关键电气参数表
表格
| 参数项 | HTOOL-SA8T 指标 |
|---|---|
| 整机频率覆盖 | 13.5MHz ~ 8.2GHz |
| 最大扫描跨度 | 8186MHz |
| RBW 分辨率带宽 | 2.5KHz / 5KHz / 10KHz / 25KHz / Auto 自动 |
| 极限扫描速度 | 12GHz/s,最快单次扫描 0.75s |
| 频谱底噪 DANL | 极限 - 120dBm,常规 - 100dBm |
| 系统阻抗 | 50Ω 标准射频阻抗 |
| 射频输入衰减 | +15dB / 0dB /-15dB 三档可调 |
| 输入端最大耐受功率 | +10dBm |
| 信号源输出功率 | 13.5MHz~6.4GHz:-11~-29dBm 连续可调6.4GHz~8.2GHz:固定 - 29dBm 输出 |
| 射频接口 | SMA 母座(RF IN 输入 / RF OUT 信号源输出) |
| 通信接口 | USB Type-C 串口通信 |
| 供电续航 | 5000mAh 锂电池,连续工作≥6.5h |
| 机身尺寸 | 125mm × 75mm × 20mm |
| 系统语言 | 中文 / English / Русский 三语言切换 |
2.3 核心亮点
- 一体化集成:无需额外搭配信号源,直接做 S21 插损 / 增益测试;
- 低底噪:-105dBm 极限底噪,弱射频信号捕捉能力强;
- 瀑布图实时监测:可观测信号随时间变化,排查间歇性干扰;
- 多迹线分析:最大值保持、最小值保持、5/10 次平均降噪;
- 自动化友好:标准 SCPI 指令,支持 Python/C# 上位机二次开发;
- 便携耐用:全金属屏蔽外壳,户外强光触摸屏,Type-C 通用充电。
三、下位机本地触摸屏完整操作指南
设备 4 寸电阻触摸屏,全部功能集成内置菜单,无需依赖电脑即可独立完成射频测量。
3.1 主界面核心区域说明
- 暂停按键:一键冻结频谱波形,方便读取标记数值;
- 信号源状态栏
Gene:Off:信号源关闭;Gene:-17dBm 6200.00MHz:点频信号输出,功率 / 频率实时显示;Gene:Tracking:S21 扫频跟踪模式开启;
- 快捷 RBW 滑块:一键切换分辨率带宽,锁定滑动可防止误触拖动波形;
- 四大调节模式切换
- Ampl Mode:纵轴参考幅值缩放(×1/×2/×4/×8/×10);
- Center Mode:中心频率微调步长(1/10/100/1000MHz);
- Span Mode:扫描跨度调节步长;
- Mark Mode:4 组标记点左右移动、切换;
- 主菜单入口:包含扫描、信号源、视图、设备、标记、预设六大功能页;
- 波形滑动:横轴拖动左右平移频谱,纵轴拖动上下调整幅值窗口。
3.2 各功能菜单详细操作
(1)扫描菜单:设置扫频区间
- 中心点、跨度、起始频率、终止频率数值输入;
- RBW 手动切换 / AUTO 自动匹配;
- 大跨度测试推荐 25KHz 提升扫描速度,微弱窄带信号选用 2.5KHz 提升信噪比。
(2)视图菜单:迹线与瀑布图
- 迹线模式:最大保持、最小保持、5 次平均、10 次平均(平均模式可降低噪声底噪);
- 瀑布图开关:时域频谱热力图,用于监测跳频、间歇性干扰;
- 幅值参考刻度、可视窗口分辨率自定义。
(3)标记菜单(4 组 Mark+4 组 Peak 峰值)
支持手动输入指定频率标记,或自动抓取频谱峰值;每组标记独立开关,可同时读取 8 个频点功率数值,适合滤波器多点插损测试。
(4)信号源菜单(核心 S21 功能)
分两种工作模式:
- 点频输出:设置固定频率 + 可调功率,用作信号激励源;
- S21 扫频模式:
- 自定义扫频点数(200/300/400/500 点);
- 直通校准:测试前短接 RF IN 与 RF OUT,消除线缆损耗归一化,提升测量精度;
- 高频段(>6.4GHz)功率锁定 - 29dBm,界面自动限制功率调节。
(5)设备系统设置
- 中英俄三语言切换;
- RF 输入衰减三档调节:强信号选 - 15dB 防饱和,微弱信号选 + 15dB 提升灵敏度;
- 屏幕旋转、亮度百分比调节;
- 设备固件版本、硬件序列号查询。
(6)预设菜单
支持保存多组自定义扫频参数(频率区间、RBW、信号源功率、迹线模式),一键调用,适合产线标准化测试。
四、PC 上位机软件功能详解
配套 Windows 上位机通过 USB 串口与 HTOOL-SA8T 通信,实现远程自动化控制、数据存储、波形可视化,适合长时间无人值守测试。
上位机全部功能模块
- 语言切换:同步设备三语言界面;
- 串口枚举:自动扫描本机所有 COM 串口,一键连接仪器;
- 全局频率配置:起始 / 终止 / 中心 / 跨度统一输入;
- RBW 配置:自动 / 四档带宽手动选择;
- 标记 & 峰值控制:4 组 Mark、4 组 Peak 独立开关,自定义标记频率;
- 信号源控制:启停开关、输出频率、输出幅值滑条调节;
- S21 网络分析:设置扫频点数、直通归一化校准;
- 迹线控制:最大 / 最小 / 5 次平均 / 10 次平均开关;
- 瀑布图可视化:电脑端实时显示时域频谱热力图;
- 数据自动保存:自定义存储路径、定时保存周期,导出幅值 - 频率原始数据,用于 Excel/Matlab 分析。
上位机使用流程
- Type-C 连接设备与电脑,开机;
- 上位机点击「扫描串口」,选中对应 COM 口建立连接;
- 配置扫频范围、RBW、迹线模式;
- 如需 S21 测试:开启信号源→设置点数→点击直通校准;
- 开启标记 / 峰值观测目标频点;
- 开启自动保存,长时间记录射频波形数据。
五、标准 SCPI 通信协议(自动化开发核心)
设备兼容标准 SCPI 指令,基于 USB 串口 ASCII 传输,可使用 Python、C#、LabVIEW、Matlab 开发自动化测试工装,适合产线批量检测。
Python 控制 HTOOL-SA8T 完整实操 Demo(CSDN 文章可直接复制)
前置说明
- 依赖库:
pyserial串口通信,二进制解析波形数据 - 通信方式:USB 转虚拟串口,SCPI ASCII 指令下发,二进制帧回传频谱数据
- 功能实现:
- 串口自动连接设备
- SCPI 指令配置扫频范围、RBW
- 开关信号源、开启 S21 模式
- 读取一帧完整频谱幅值数据
- 解析 4 组峰值频点 + 功率
- 安装依赖
bash
运行
pip install pyserial完整 Python 源码
python
运行
import serial import serial.tools.list_ports import struct import time class HTOOL_SA8T: def __init__(self): self.ser = None self.port_name = "" # 自动枚举串口,连接仪器 def auto_connect(self): port_list = serial.tools.list_ports.comports() if len(port_list) == 0: print("未检测到串口,请检查Type-C连接线、设备开机") return False # 遍历所有串口尝试连接 for port in port_list: try: self.ser = serial.Serial(port.device, baudrate=115200, timeout=1) self.port_name = port.device print(f"成功连接端口:{self.port_name}") return True except Exception as e: continue print("所有串口均连接失败") return False # 下发SCPI指令并读取返回值 def send_scpi(self, cmd: str) -> str: if self.ser is None or not self.ser.is_open: return "" send_cmd = (cmd + "\r\n").encode("ascii") self.ser.write(send_cmd) time.sleep(0.05) resp = self.ser.read_all().decode("ascii", errors="ignore").strip() return resp # 1. 信号源控制:开关 def set_gen_status(self, status: str): # status: "ON" / "OFF" self.send_scpi(f"GENErator:STATus {status}") # 2. 设置信号源单点频率(MHz) def set_gen_freq(self, freq_mhz: float): self.send_scpi(f"GENErator:FREQuery {freq_mhz:.2f}") # 3. 设置信号源频点+功率 def set_gen_gpwr(self, freq_mhz: float, power: float): self.send_scpi(f"GENErator:GPWR {freq_mhz:.2f},{power:.1f}") # 4. 开启S21扫频模式,设置点数 200/300/400/500 def set_s21(self, point_num: int, status="ON"): self.send_scpi(f"GENErator:S21 {point_num},{status}") # 5. 设置全局扫描参数:起始MHz、终止MHz、数据流开关、RBW索引 # RBW索引:0=Auto,1=2.5K,2=5K,3=10K,4=25K def set_scan_param(self, start_mhz: float, stop_mhz: float, data_stream=1, rbw_idx=0): self.send_scpi(f"FREQuency:SCAN {start_mhz},{stop_mhz},{data_stream},{rbw_idx}") # 6. 读取当前完整频谱二进制帧 def get_curve_data(self): self.send_scpi("DATA:CURRent?") raw_data = self.ser.read(4096) # 缓存足够大接收完整帧 return raw_data # 7. 解析二进制帧,返回 频率列表、幅值列表、峰值列表 def parse_frame(self, raw_data: bytes): if not raw_data.startswith(b"#"): print("帧头校验失败,非有效频谱数据") return [], [], [] ptr = 1 # 读取长度位数D D = int(raw_data[ptr:ptr+1]) ptr += 1 # 读取数据段总长度 data_len = int(raw_data[ptr:ptr+D]) ptr += D head_count = D + 2 # 解析起始、终止频率(MHz) start_freq_khz = struct.unpack("<f", raw_data[head_count+2:head_count+6])[0] stop_freq_khz = struct.unpack("<f", raw_data[head_count+6:head_count+10])[0] start_mhz = start_freq_khz / 1000 stop_mhz = stop_freq_khz / 1000 # 幅值数据起始偏移 ampl_start = head_count + 10 peak_total_len = 4 * 12 # 4组峰值,每组12字节 ampl_bytes_len = len(raw_data) - ampl_start - peak_total_len - 2 # 末尾\r\n point_count = ampl_bytes_len // 2 freq_list = [] ampl_list = [] # 生成每个点对应频率 step_mhz = (stop_mhz - start_mhz) / (point_count - 1) if point_count > 1 else 0 for i in range(point_count): freq = start_mhz + i * step_mhz freq_list.append(round(freq, 3)) # 2字节short,幅值放大100倍 ampl_raw = struct.unpack("<h", raw_data[ampl_start + i*2 : ampl_start + i*2 + 2])[0] ampl_real = ampl_raw / 100.0 ampl_list.append(ampl_real) # 解析4组峰值 peak_list = [] peak_ptr = ampl_start + ampl_bytes_len for _ in range(4): peak_freq_khz = struct.unpack("<f", raw_data[peak_ptr:peak_ptr+4])[0] peak_ampl_raw = struct.unpack("<f", raw_data[peak_ptr+4:peak_ptr+8])[0] peak_idx = struct.unpack("<i", raw_data[peak_ptr+8:peak_ptr+12])[0] peak_ptr += 12 peak_data = { "freq_MHz": peak_freq_khz / 1000, "power_dbm": peak_ampl_raw / 100, "point_index": peak_idx } peak_list.append(peak_data) return freq_list, ampl_list, peak_list # 关闭串口 def close(self): if self.ser is not None and self.ser.is_open: self.set_gen_status("OFF") self.ser.close() print("串口已关闭,信号源关闭") if __name__ == "__main__": sa = HTOOL_SA8T() # 1. 连接设备 if not sa.auto_connect(): exit() # -------------------------- # 示例1:基础频谱扫描配置 # -------------------------- print("=== 配置2.4G WiFi扫频 2300~2500MHz,RBW自动 ===") sa.set_scan_param(start_mhz=2300, stop_mhz=2500, data_stream=1, rbw_idx=0) time.sleep(0.3) # -------------------------- # 示例2:单点信号源输出 2440MHz -17dBm # -------------------------- print("=== 开启信号源 2440MHz -17dBm ===") sa.set_gen_gpwr(2440, -17) sa.set_gen_status("ON") time.sleep(0.5) # -------------------------- # 示例3:读取并解析一帧频谱数据 # -------------------------- raw = sa.get_curve_data() freq_data, ampl_data, peaks = sa.parse_frame(raw) print(f"采样点数:{len(freq_data)}") print(f"起始频率:{freq_data[0]} MHz,终止频率:{freq_data[-1]} MHz") print("前5个频点功率(dBm):", ampl_data[:5]) print("\n==== 4组峰值数据 ====") for idx, p in enumerate(peaks): print(f"峰值{idx+1}:频率{p['freq_MHz']:.2f} MHz,功率{p['power_dbm']:.2f} dBm") # -------------------------- # 示例4:S21传输测量模式(滤波器/线缆测试) # -------------------------- # sa.set_s21(point_num=500, status="ON") # time.sleep(0.3) # 持续读取波形循环演示 try: cnt = 0 while cnt < 3: raw = sa.get_curve_data() _, ampl_data, peaks = sa.parse_frame(raw) max_power = max(ampl_data) if ampl_data else -120 print(f"\n第{cnt+1}帧最大信号功率:{max_power:.2f} dBm") cnt += 1 time.sleep(0.8) except KeyboardInterrupt: print("\n程序手动终止") finally: sa.close()二、代码配套使用说明(粘贴到 CSDN 文中)
2.1 接线操作步骤
- HTOOL-SA8T 开机,Type-C 连接电脑;
- 频谱单点测量:仅接
RF IN输入被测射频信号; - S21 插损测试:
RF OUT→ 被测器件输入端,被测器件输出端 →RF IN,代码执行set_s21()后先做直通校准(上位机 / 设备界面操作)。
2.2 关键函数说明
auto_connect():自动扫描电脑所有 COM 口,无需手动填写串口号,新手友好;set_scan_param():核心扫频配置,RBW 索引对应设备 4 档带宽 + Auto;set_gen_gpwr():设置信号源频点与功率,6.4GHz 以上功率会被硬件锁定 - 29dBm,代码下发无效;parse_frame():内置二进制帧解析逻辑,自动还原真实 dBm 功率、4 组峰值频点;- S21 模式开启后,读取幅值曲线即为器件传输损耗曲线。
2.3 拓展开发方向(可写在文章末尾)
- 结合
matplotlib实时绘制频谱波形图; - 增加数据自动保存 CSV,用于 Excel 分析滤波器插损曲线;
- 封装自动化产线脚本:连续多组频点测试、上下限判定、不良日志输出;
- LabVIEW / C# 对接:复用本文 SCPI 指令集,仅替换串口通信 API。