关于 matlab-transmit-capture-usrp
matlab-transmit-capture-usrp 是一项 MATLAB 技能,用于通过 NI USRP 无线电生成、发送和捕获 RF 波形。它指导配置无线电对象,支持单向或同时收发,以及前台和后台采集。
主要功能
- 01配置 USRP 无线电对象
- 02单次或连续发送波形
- 03在前台或后台捕获 IQ 样本
- 04支持多天线信号
- 05将长时间采集保存到文件
适用场景
- 01通过无线链路发送测试音
- 02执行无线电环回测试
- 03捕获 IQ 数据以供后续分析
- 04在长时间测试中采集数据
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-transmit-capture-usrp安装后在 Claude Code 中输入/matlab-transmit-capture-usrp确认已加载。
附带文件manifest.yaml
详细介绍
使用 Wireless Testbench 发送和捕获波形
在 MATLAB 中使用 NI USRP 无线电生成、发送和捕获 RF 波形。
适用场景
- 通过无线方式发送波形(测试音、符合标准的信号、自定义 IQ)
- 捕获某个频段的 IQ 数据
- 环回测试(在同一台无线电设备上发送并捕获)
- 多天线发送或捕获
- 长时间持续发送
- 长时间采集时进行后台捕获
不适用场景
- 首次设置或连接 USRP 无线电设备 — 使用 matlab-set-up-usrp-radio 技能
- FPGA 定向工作流 — 请参阅 Target NI USRP Radios
- 使用前导码/能量检测进行触发式(信号唤醒)捕获 — 使用 matlab-detect-capture-usrp 技能
- 多设备同步 — 请参阅 Radio Management
前提条件
使用任何发送/捕获对象前,必须先存在已保存的无线电配置。列出可用配置,并让用户选择要使用的配置:
configs = radioConfigurations;
disp(configs)
如果存在多个配置,请询问用户想使用哪一个。如果不存在配置,请指导用户先进行设置(请参阅 matlab-set-up-usrp-radio 技能)。
生成代码前,如果用户尚未指定,请确认以下参数:
- 中心频率 — 接受无线电支持范围内的任意数值。不要提供受限的频段列表;让用户输入频率。
- 采样率 — 询问用户需要的采样率。可推荐常用值(30.72 MHz、61.44 MHz、122.88 MHz、245.76 MHz),但应接受任何有效速率。
选择合适的对象
默认使用 basebandTransceiver。 它支持所有工作流 — 仅发送、仅捕获或同时进行两者。除非有特定原因,否则使用它。
| 对象 | 使用场景 |
|---|---|
basebandTransceiver | 默认选择。 发送、捕获或同时进行两者。适用于环回、信号生成、频谱监测和全双工 |
basebandTransmitter | 仅当需要专用的只发送对象时使用(例如,由单独脚本独立控制 TX) |
basebandReceiver | 仅当需要专用的只接收对象时使用(例如,由单独脚本独立控制 RX) |
默认使用 basebandTransceiver 的原因: 单个无线电配置一次只能由一个对象使用。由于 basebandTransceiver 可处理发送、捕获或两者兼有,因此无需切换对象即可满足绝大多数工作流。独立对象(basebandTransmitter、basebandReceiver)适用于需要分别通过独立脚本或应用控制单个方向的场景。
不同对象类型的属性命名有所不同:
| basebandTransceiver | basebandTransmitter / basebandReceiver | |
|---|---|---|
| 增益 | TransmitRadioGain、CaptureRadioGain | RadioGain |
| 频率 | TransmitCenterFrequency、CaptureCenterFrequency | CenterFrequency |
| 天线 | TransmitAntennas、CaptureAntennas | Antennas |
收发器使用 Transmit/Capture 前缀来区分方向。独立对象只处理一个方向,因此无需前缀。
工作流
步骤 1:创建无线电对象
radio = radioConfigurations("MyN310");
bbtrx = basebandTransceiver(radio);
预加载选项: 传入 Preload=true,可在构造对象时加载 FPGA 应用,而不是等到首次使用时再加载。这样可避免首次调用 transmit 或 capture 时出现数秒延迟。
bbtrx = basebandTransceiver(radio, Preload=true);
独立对象(仅在需要独立控制单个方向时使用):
bbtx = basebandTransmitter(radio); % TX only
bbrx = basebandReceiver(radio); % RX only
步骤 2:配置属性
在传输或采集前配置对象。对象创建后设置属性也是有效的,但某些更改会导致重新加载延迟。
bbtrx.SampleRate = 30.72e6;
bbtrx.TransmitCenterFrequency = 3.5e9;
bbtrx.CaptureCenterFrequency = 3.5e9;
bbtrx.TransmitRadioGain = 20;
bbtrx.CaptureRadioGain = 40;
仅设置所需方向的属性。对于仅传输的工作流,跳过 Capture* 属性(反之亦然)。
如果使用独立对象(basebandTransmitter / basebandReceiver),属性不带前缀:
bbtx.SampleRate = 30.72e6;
bbtx.CenterFrequency = 3.5e9; % not TransmitCenterFrequency
bbtx.RadioGain = 20; % not TransmitRadioGain
属性指南:
| 属性 | 指南 |
|---|---|
| SampleRate | 必须与波形带宽匹配。常见值:30.72 MHz(LTE/NR)、61.44 MHz、122.88 MHz、245.76 MHz |
| TransmitRadioGain | 从较低值开始(10–20 dB),以避免削波。逐渐增大,直到信号强度足够 |
| CaptureRadioGain | 从中等值开始(30–40 dB)。过高会使 ADC 削波;过低则会让信号淹没在噪声中 |
| TransmitCenterFrequency / CaptureCenterFrequency | 必须处于无线电设备支持的范围内(取决于设备,通常为 1 MHz–6/8 GHz) |
| DroppedSamplesAction | 开发期间设为 "warning",以便在发生丢样时继续运行;生产环境中使用 "error" |
步骤 3:准备发射波形
波形必须是复数列向量(单天线)或复数矩阵(多天线,每列对应一根天线)。数值必须归一化到 [-1, 1] 范围内。
测试音:
numSamples = 30720;
t = (0:numSamples-1)' / bbtrx.SampleRate;
txWaveform = 0.8 * exp(1j*2*pi*1e6*t);
类 OFDM 随机信号:
numSamples = 30720;
txWaveform = complex(randn(numSamples,1), randn(numSamples,1));
txWaveform = 0.7 * txWaveform / max(abs(txWaveform));
从文件加载预生成的波形:
waveStruct = load("myWaveform.mat");
txWaveform = waveStruct.waveform;
txWaveform = 0.8 * txWaveform / max(abs(txWaveform));
将此模式用于由 5G Toolbox、LTE Toolbox、WLAN Toolbox 或任何自定义信号生成工作流生成的波形。
波形要求:
| 要求 | 详情 |
|---|---|
| 数据类型 | 复数 double、single 或 int16(由 TransmitDataType 控制) |
| 振幅 | 对于 double/single,峰值幅度 ≤ 1.0(大于 1 的值会在 DAC 处削波) |
| 维度 | 列向量(单天线)或 N×M 矩阵(M = TX 天线数) |
| 行数 | 必须是偶数 |
| 最小长度 | 少于 513 个采样点的波形会预留最多 1024 个采样点用于欠载保护 |
使用 Preload=true 时,将 TransmitDataType 传入构造函数:
FPGA 应用会在构造时配置为特定的发射数据类。如果不启用预加载,则会在首次调用 transmit 时根据波形推断数据类。启用预加载后,收发器没有波形可供推断,因此必须显式传入 TransmitDataType,否则 FPGA 会在首次调用 transmit 时重新加载,导致预加载失去意义。
bbtrx = basebandTransceiver(radio, Preload=true, TransmitDataType="double");
% ... configure frequency/gain/sample rate ...
transmit(bbtrx, txWaveform, "continuous"); % waveform class must match TransmitDataType
步骤 4:发射
单次发射 — 将波形准确发射一次:
transmit(bbtrx, txWaveform, "once");
无线电设备发射波形一次后会自动停止。适用于脉冲或单次测试。为提高此模式的可靠性,请在波形末尾添加几个冗余采样点。
连续发射 — 持续重复发射,直到停止:
transmit(bbtrx, txWaveform, "continuous");
波形会在无线电设备上持续循环,直到调用 stopTransmission。适用于:
- 持续干扰或信号生成
- 采集时序与发射时序相互独立的回环测试
- 接收器需要持续信号的空中传输测试
停止连续发射:
stopTransmission(bbtrx);
步骤 5:采集
前台采集(MATLAB 会阻塞,直至采集完成):
[data, timestamp, droppedSamples] = capture(bbtrx, milliseconds(10));
length 参数接受 duration 值(例如 seconds(1)、milliseconds(10))或正整数形式的采样点数。
输出参数:
| 输出 | 类型 | 描述 |
|---|---|---|
data | 复数向量/矩阵 | IQ 采样点 — 行 = 采样点,列 = 天线。数据类型与 CaptureDataType 属性一致。前几个采样点可能包含瞬态 |
timestamp | datetime | 在硬件采集请求发出前立即创建的时间戳 |
droppedSamples | logical | 如果发生丢样(网络/主机问题),则为 true;如果采集正常,则为 false |
CaptureDataType 默认为 int16 — 在执行 FFT、滤波或算术运算前请先转换类型:
捕获的 data 是一个复杂向量/矩阵,其类与 CaptureDataType 匹配。默认值为 "int16"(定点),以尽量减少内存占用。大多数 MATLAB 信号处理函数——包括 fft、abs、filter、bandpass、pwelch 和逐元素数学运算——不接受复数 int16,并会在运行时出错。可通过以下两种方式之一处理:
% Option A — set the property before capture (all downstream code sees double)
bbtrx.CaptureDataType = "double";
[data, ~, dropped] = capture(bbtrx, milliseconds(10));
X = fft(data); % works
% Option B — cast after capture (keep the memory savings during transfer)
[data, ~, dropped] = capture(bbtrx, milliseconds(10));
data = double(data);
X = fft(data); % works
默认使用选项 A。只有在捕获期间内存紧张,并且希望在开始处理前保留紧凑的 int16 载荷时,才优先选择选项 B。
后台捕获(非阻塞):
在以下情况下使用后台捕获:
- 捕获时间较长(超过几秒),且 MATLAB 必须保持响应
- 希望在采集期间进行后处理、更新显示或执行其他工作
- 将捕获与连续发射结合使用,并且需要同时监控两者
在以下情况下使用前台捕获(默认):
- 捕获时间较短,并且下一步需要立即使用数据
- 脚本是线性执行的(不需要并发工作)
选择合适的模式:
| 场景 | 模式 |
|---|---|
| 短时捕获,需要立即获取数据 | [data,~,dropped] = capture(bbtrx, milliseconds(100)); |
| 长时间捕获,数据可存入 RAM | capture(bbtrx, seconds(30), Background=true); 然后调用 captureOutputs |
| 长时间捕获,数据太大,无法存入 RAM | capture(bbtrx, seconds(60), Background=true, SaveLocation="data.mat", UseRadioBuffer=false); |
| 需要在捕获完成时收到通知 | 添加 CompletionFcn=@(data,ts,dropped) myCallback(data) |
使用轮询进行后台捕获:
capture(bbtrx, seconds(30), Background=true);
% Poll until complete
while isCapturing(bbtrx)
pause(1);
end
% Retrieve results
[data, timestamp, droppedSamples] = captureOutputs(bbtrx);
使用回调进行后台捕获(无需轮询):
capture(bbtrx, seconds(30), Background=true, ...
CompletionFcn=@(data, ts, dropped) handleCapture(data, dropped));
将长时间捕获保存到文件(后台 + SaveLocation + 直接传输到主机):
对于超过板载缓冲区或 RAM 容量的捕获,请结合使用以下三个选项:
capture(bbtrx, seconds(60), ...
Background=true, ...
SaveLocation="captured_data.mat", ...
UseRadioBuffer=false);
while isCapturing(bbtrx)
pause(5);
end
filePath = captureOutputs(bbtrx);
fprintf("Saved to: %s\n", filePath);
指定 SaveLocation 时,captureOutputs 会返回文件路径,而不是将数据加载到工作区。
提前停止后台捕获:
stopCapture(bbtrx);
[data, timestamp, droppedSamples] = captureOutputs(bbtrx);
UseRadioBuffer——在无线电缓冲区与直接传输到主机之间进行选择:
UseRadioBuffer 名称-值参数用于控制采集期间捕获样本的存储位置。合适的选择取决于捕获时长、采样率和主机网络性能。
% Radio buffer (default) — data is stored in onboard radio memory, then
% transferred to the host after capture completes. Most reliable option.
[data, ~, dropped] = capture(bbtrx, milliseconds(100));
% Direct-to-host — data streams continuously from radio to host over the
% network during the capture. Required when capture exceeds onboard memory.
[data, ~, dropped] = capture(bbtrx, seconds(30), UseRadioBuffer=false);
在以下情况下使用 UseRadioBuffer=true(默认):
- 捕获长度不超过无线电设备板载内存容量
- 希望获得最可靠的捕获(不依赖主机持续吞吐量)
- 采样率较高,无法容忍任何丢样
在以下情况下使用 UseRadioBuffer=false:
- 捕获长度超过无线电设备的板载缓冲区容量(见下表)
- 使用配备 TwinRX 子板的 USRP X310 捕获超过 2 个天线通道
- 需要任意长时间的捕获(数分钟或数小时的数据)
板载缓冲区容量(决定何时需要直接传输到主机):
| 设备 | 最大样本数 | 30.72 MHz 下的约略时长 |
|---|---|---|
| USRP E320 / N-series | 2^29 (~537M) | ~17.5 s |
| USRP X300 / X310 | 2^28 (~268M) | ~8.7 s |
| USRP X410 | 2^30 (~1.07B) | ~34.8 s |
直接传输到主机的性能注意事项:
直接传输到主机的捕获要求在整个捕获期间保持持续的网络吞吐量。可达到的最高采样率取决于主机和网络配置,并会因系统负载而在不同运行中有所变化。如果出现丢样,请降低采样率、减少天线数量,或运行 radioSetupWizard,以针对你的平台优化主机网络设置。
评估主机性能: 要找到可持续的最高直接传输速率,可逐步降低采样率并重复捕获,同时设置 DroppedSamplesAction="none",直到成功为止:
bbrx.DroppedSamplesAction = "none";
sampleRates = 245.76e6 : -10e6 : 10e6;
for idx = 1:numel(sampleRates)
bbrx.SampleRate = sampleRates(idx);
[~, ~, dropped] = capture(bbrx, 2*2^28, UseRadioBuffer=false);
if ~dropped
fprintf("Max sustained rate: %.1f MHz\n", sampleRates(idx)/1e6);
break
end
end
提前停止后台捕获:
stopCapture(bbtrx);
[data, timestamp, droppedSamples] = captureOutputs(bbtrx);
步骤 6:回环测试(在同一台无线电设备上发射并采集)
回环测试使用 basebandTransceiver 验证完整的 TX/RX 链路。将 TransmitCenterFrequency 和 CaptureCenterFrequency 设为相同的值,使信号在内部耦合。
方法 A:连续发射后采集
开始连续发射,稍作等待,让无线电前端稳定下来,然后进行采集。
radio = radioConfigurations("MyN310");
bbtrx = basebandTransceiver(radio, Preload=true);
bbtrx.SampleRate = 61.44e6;
bbtrx.TransmitCenterFrequency = 2.4e9;
bbtrx.CaptureCenterFrequency = 2.4e9;
bbtrx.TransmitRadioGain = 10;
bbtrx.CaptureRadioGain = 30;
% Generate test tone
numSamples = 61440;
t = (0:numSamples-1)' / bbtrx.SampleRate;
txWaveform = 0.8 * exp(1j*2*pi*1e6*t);
% Transmit continuously, pause for stabilization, then capture
transmit(bbtrx, txWaveform, "continuous");
pause(1);
[rxData, ~, droppedSamples] = capture(bbtrx, milliseconds(10));
stopTransmission(bbtrx);
% Verify
if ~droppedSamples
fprintf("Loopback OK: captured %d samples, no drops.\n", size(rxData,1));
else
warning("Samples were dropped during loopback.");
end
% Visualize
sa = spectrumAnalyzer(SampleRate=bbtrx.SampleRate);
sa(rxData);
步骤 7:多天线配置
对于 MIMO 或多通道运行,将天线属性设为数组,并提供矩阵波形。
radio = radioConfigurations("MyX410");
bbtrx = basebandTransceiver(radio);
bbtrx.SampleRate = 61.44e6;
% Configure 2 TX and 2 RX antennas
bbtrx.TransmitAntennas = ["DB0:RF0:TX/RX0", "DB0:RF1:TX/RX0"];
bbtrx.CaptureAntennas = ["DB0:RF0:RX1", "DB0:RF1:RX1"];
bbtrx.TransmitCenterFrequency = [3.5e9, 3.5e9];
bbtrx.CaptureCenterFrequency = [3.5e9, 3.5e9];
bbtrx.TransmitRadioGain = [15, 15];
bbtrx.CaptureRadioGain = [35, 35];
% Waveform: N×2 matrix (one column per TX antenna)
numSamples = 61440;
t = (0:numSamples-1)' / bbtrx.SampleRate;
tx1 = 0.7 * exp(1j*2*pi*1e6*t);
tx2 = 0.7 * exp(1j*2*pi*2e6*t);
txWaveform = [tx1, tx2];
transmit(bbtrx, txWaveform, "continuous");
[rxData, ~, dropped] = capture(bbtrx, milliseconds(10));
stopTransmission(bbtrx);
% rxData is N×2: one column per RX antenna
fprintf("Captured %d samples on %d antennas.\n", size(rxData,1), size(rxData,2));
天线命名因设备而异——TX 和 RX 端口的名称不同:
| 设备 | TransmitAntennas | CaptureAntennas |
|---|---|---|
| X410 | "DB0:RF0:TX/RX0"、"DB0:RF1:TX/RX0"、"DB1:RF0:TX/RX0"、"DB1:RF1:TX/RX0" | "DB0:RF0:RX1"、"DB0:RF1:RX1"、"DB1:RF0:RX1"、"DB1:RF1:RX1" |
| X310 (UBX) | "RFA:TX/RX"、"RFB:TX/RX" | "RFA:RX2"、"RFB:RX2" |
| N310 | "RF0:TX/RX"、"RF1:TX/RX"、"RF2:TX/RX"、"RF3:TX/RX" | "RF0:RX2"、"RF1:RX2"、"RF2:RX2"、"RF3:RX2" |
| N320/N321 | "RF0:TX/RX"、"RF1:TX/RX" | "RF0:RX2"、"RF1:RX2" |
| E320 | "RFA:TX/RX" | "RFA:RX2"、"RFB:RX2" |
指定无效值,即可查看设备所接受的全部天线名称。
故障排除
| 症状 | 原因 | 解决方法 |
|---|---|---|
| 样本丢失 | 主机/网络无法维持吞吐量 | 运行 radioSetupWizard 优化主机设置,或降低采样率/天线数量 |
| 采集的信号削波 | CaptureRadioGain 过高 | 降低增益,直到峰值幅度 < 0.9 |
| 采集的信号处于噪声底 | CaptureRadioGain 过低 | 逐步提高增益 |
| TX 信号失真 | 波形幅度 > 1.0 | 归一化:waveform = waveform / max(abs(waveform)) |
| 首次调用延迟数秒 | FPGA 应用正在加载 | 在构造时使用 Preload=true |
"Resource not available" 错误 | 另一个对象占用了无线电设备 | 清除现有对象:clear bbtrx |
| 采集长度超过缓冲区 | 板载内存已满 | 长时间采集时使用 UseRadioBuffer=false |
| 后台采集始终无法完成 | 采集仍在运行 | 检查 isCapturing();若卡住,请使用 stopCapture() |
关键函数参考
| 函数/方法 | 用途 |
|---|---|
basebandTransceiver | 创建无线电对象(默认——处理 TX、RX 或两者) |
basebandTransmitter | 创建仅 TX 的无线电对象(仅限独立使用) |
basebandReceiver | 创建仅 RX 的无线电对象(仅限独立使用) |
transmit(obj, waveform, "once") | 单次发射 |
transmit(obj, waveform, "continuous") | 连续发射(循环运行,直到停止) |
stopTransmission(obj) | 停止连续发射 |
capture(obj, length) | 前台采集(阻塞) |
capture(obj, length, Background=true) | 后台采集(非阻塞) |
captureOutputs(obj) | 获取后台采集结果 |
isCapturing(obj) | 检查后台采集是否正在运行 |
stopCapture(obj) | 停止后台采集 |
radioConfigurations | 列出/加载已保存的无线电配置 |
约定
- 默认使用
basebandTransceiver。 发送、捕获或同时进行发送和捕获时,都使用它。只有在单独的脚本需要独立控制单向操作时,才使用basebandTransmitter/basebandReceiver。 - 对波形进行归一化。 始终将峰值幅度缩放至 ≤ 0.8,以留出余量并避免 DAC 削波。
- 从较低增益开始。 TX 增益从 10–20 dB 开始,RX 增益从 30–40 dB 开始;根据观测到的信号电平进行调整。
- 先连续发送,再开始捕获。 对于回环,先启动
transmit(..., "continuous"),再调用capture。这样可确保开始捕获时信号已经存在。 - 始终停止发送。 完成后调用
stopTransmission,以释放无线电资源。 - 检查丢失的样本。 始终检查
capture的第三个输出——它是逻辑值(true= 发生了丢样)。如果为true,请运行radioSetupWizard优化主机设置,或降低采样率。 - 等待输出就绪后再获取。 在
isCapturing返回false或调用stopCapture之前,切勿调用captureOutputs。如果捕获仍在运行时调用它,将会报错。 - 使用时长指定捕获长度。 为了提高可读性并适配不同采样率,优先使用
milliseconds(N)或seconds(N),而不是原始样本数。 - 清理对象。 完成后对无线电对象调用
clear,以便其他应用程序使用硬件。
版权所有 2026 The MathWorks, Inc.