mcpField
M
matlab-transmit-capture-usrp

matlab-transmit-capture-usrp

github.com/matlab其他1.2k39 次安装1 天前更新
代码仓库

关于 matlab-transmit-capture-usrp

matlab-transmit-capture-usrp 是一项 MATLAB 技能,用于通过 NI USRP 无线电生成、发送和捕获 RF 波形。它指导配置无线电对象,支持单向或同时收发,以及前台和后台采集。

主要功能

  1. 01配置 USRP 无线电对象
  2. 02单次或连续发送波形
  3. 03在前台或后台捕获 IQ 样本
  4. 04支持多天线信号
  5. 05将长时间采集保存到文件

适用场景

  1. 01通过无线链路发送测试音
  2. 02执行无线电环回测试
  3. 03捕获 IQ 数据以供后续分析
  4. 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)适用于需要分别通过独立脚本或应用控制单个方向的场景。

不同对象类型的属性命名有所不同:

basebandTransceiverbasebandTransmitter / basebandReceiver
增益TransmitRadioGain、CaptureRadioGainRadioGain
频率TransmitCenterFrequency、CaptureCenterFrequencyCenterFrequency
天线TransmitAntennas、CaptureAntennasAntennas

收发器使用 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 属性一致。前几个采样点可能包含瞬态
timestampdatetime在硬件采集请求发出前立即创建的时间戳
droppedSampleslogical如果发生丢样(网络/主机问题),则为 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));
长时间捕获,数据可存入 RAMcapture(bbtrx, seconds(30), Background=true); 然后调用 captureOutputs
长时间捕获,数据太大,无法存入 RAMcapture(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-series2^29 (~537M)~17.5 s
USRP X300 / X3102^28 (~268M)~8.7 s
USRP X4102^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 端口的名称不同:

设备TransmitAntennasCaptureAntennas
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.


评论

支持 Markdown