mcpField
M
matlab-generate-ble-waveform

matlab-generate-ble-waveform

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

关于 matlab-generate-ble-waveform

这项 MATLAB 技能用于生成、仿真和分析 Bluetooth Low Energy PHY 波形,面向开展 BLE 物理层工作的用户。它提供 PHY 模式选择指引,并涵盖测向、合规测试、接收机仿真、共存分析和发射机测量流程。

主要功能

  1. 01生成四种 BLE PHY 模式波形
  2. 02构建多数据包突发和 PDU 波形
  3. 03支持 CTE 与测向流程
  4. 04指导 BER 和受损接收机仿真
  5. 05涵盖 RF-PHY 测试与发射测量

适用场景

  1. 01比较 BLE PHY 模式
  2. 02测试基于 CTE 的角度估计
  3. 03测量带宽、PAPR 或信号功率
  4. 04仿真噪声或 WLAN 干扰下的 BER

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-generate-ble-waveform

安装后在 Claude Code 中输入/matlab-generate-ble-waveform确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

manifest.yaml
references/
cte-direction-finding.md
data-whitening.md
direction-finding.md
functionalAPI.md
phy-modes-and-timing.md
practical-receiver-simulation.md
rfphy-compliance-testing.md
rssi-localization.md
transmitter-measurements.md
wlan-coexistence.md

详细介绍

BLE 波形生成

路由

意图线索模式
基本生成“generate”、“waveform”单模式
比较模式“compare”、“all modes”全模式
测向“CTE”、“AoA”、“AoD”CTE
RF-PHY 合规性“compliance”、“RF-PHY”RF-PHY 测试
共存“WLAN”、“interference”WLAN 共存
TX 测量“PAPR”、“OBW”、“power”TX 测量
定位“RSSI”、“beacon”、“distance”RSSI 定位
BER/接收器“BER”、“noise”、“sensitivity”BER 仿真
多数据包“burst”、“IFS”多数据包
频谱“spectrum”、“spectral mask”频谱分析
白化“whitening”、“scrambling”白化对比
损伤“CFO”、“practical”、“realistic”端到端

默认值(请求不明确时):LE1M、37 字节载荷、信道 37。

适用场景

当用户要求生成、仿真或分析 BLE PHY 层波形时,请使用此技能——包括模式比较、CTE/测向、RF-PHY 合规性测试、BER 仿真、TX 测量、WLAN 共存或 RSSI 定位。适用于涉及 bleWaveformGenerator、bleIdealReceiver、bleCTEIQSample、bleAngleEstimate 或 bluetoothTestWaveform 的任何任务。

不适用场景

  • BR/EDR(经典 Bluetooth)→ 使用 bluetoothWaveformGenerator(由单独的 BR/EDR 技能介绍)
  • Channel Sounding(CS)→ 使用 bleCSWaveform(bleCSConfig)(R2024b+);CS 有自己的测距/距离测量流程,不属于 PHY 波形生成
  • 网络级仿真 → 使用 bluetoothLENode 进行链路层/网络建模
  • 路径损耗建模 → 使用 bluetoothPathLoss 进行传播/信道建模

PHY 模式

模式symbolRate数据速率编码时长(37 B)
"LE1M"1e61 Mbps无~336 us
"LE2M"2e62 Mbps无~172 us
"LE500K"1e6500 kbpsFEC S=2~974 us
"LE125K"1e6125 kbpsFEC S=8~2768 us

参考资料

如需了解此文件之外的详细指南,请参阅:

参数(bleWaveformGenerator)

参数默认值范围
Mode"LE1M"LE1M、LE2M、LE500K、LE125K
ChannelIndex370-39
SamplesPerSymbol8>=1(绘图时建议使用 >=4)
WhitenStatus"On"On、Off
DFPacketType"Disabled"Disabled、ConnectionCTE、ConnectionlessCTE
AccessAddressadv default32 位二进制列向量
ModulationIndex0.5[0.45, 0.55]
PulseLength1[1, 4]

核心示例

messageBits = randi([0 1], payloadLenBytes*8, 1);
waveform = bleWaveformGenerator(messageBits, ...
    Mode=phyMode, SamplesPerSymbol=sps, ...
    ChannelIndex=ch, WhitenStatus="On");
symbolRate = 1e6 + 1e6*(phyMode=="LE2M");
fs = symbolRate * sps;

模式

全模式对比
phyModes = ["LE1M","LE2M","LE500K","LE125K"];
sps = 8;
messageBits = randi([0 1], 37*8, 1);
figure; tl = tiledlayout(4,2,TileSpacing="compact",Padding="compact");
title(tl,"BLE - All PHY Modes")
for idx = 1:4
    wf = bleWaveformGenerator(messageBits, ...
        Mode=phyModes(idx), SamplesPerSymbol=sps, ChannelIndex=37, WhitenStatus="On");
    sr = 1e6 + 1e6*(phyModes(idx)=="LE2M");
    fs = sr*sps; t = (0:length(wf)-1)/fs*1e6;
    nexttile; plot(t,real(wf),t,imag(wf))
    xlabel("Time (\mus)"); ylabel("Amplitude"); title(phyModes(idx)+" - IQ")
    legend("I","Q"); grid on; xlim([0 min(80,t(end))])
    nexttile; N=length(wf); f=(-N/2:N/2-1)*(fs/N)/1e6;
    plot(f, 20*log10(abs(fftshift(fft(wf)))/N+eps))
    xlabel("Frequency (MHz)"); ylabel("dB"); title(phyModes(idx)+" - Spectrum")
    grid on; xlim([-3 3]); ylim([-80 0])
end
多数据包突发(T_IFS = 150 us)
sps = 8; fs = 1e6*sps;
messageBits = randi([0 1], 37*8, 1);
ifsGap = complex(zeros(round(150e-6*fs), 1));
burst = complex(zeros(0,1));
for pkt = 1:3
    wf = bleWaveformGenerator(messageBits, Mode="LE1M", SamplesPerSymbol=sps, ChannelIndex=37);
    burst = [burst; wf; ifsGap]; %#ok<AGROW>
end
往返解码
messageBits = randi([0 1], 37*8, 1); sps = 8;
wf = bleWaveformGenerator(messageBits, Mode="LE1M", SamplesPerSymbol=sps, ChannelIndex=37, WhitenStatus="On");
rxBits = bleIdealReceiver(wf, Mode="LE1M", SamplesPerSymbol=sps, ChannelIndex=37, WhitenStatus="On");
assert(isequal(rxBits, messageBits))
数据信道 + 自定义接入地址
accessAddr = randi([0 1], 32, 1);
wf = bleWaveformGenerator(randi([0 1],27*8,1), ...
    Mode="LE2M", SamplesPerSymbol=8, ChannelIndex=9, ...
    AccessAddress=accessAddr, WhitenStatus="On");
fs = 2e6 * 8;
CTE 生成
messageBits = randi([0 1], 20*8, 1); sps = 8; fs = 1e6*sps;
wf_noCTE = bleWaveformGenerator(messageBits, Mode="LE1M", ...
    SamplesPerSymbol=sps, ChannelIndex=10, WhitenStatus="On");
wf_conn = bleWaveformGenerator(messageBits, Mode="LE1M", ...
    SamplesPerSymbol=sps, ChannelIndex=10, WhitenStatus="On", DFPacketType="ConnectionCTE");
wf_cless = bleWaveformGenerator(messageBits, Mode="LE1M", ...
    SamplesPerSymbol=sps, ChannelIndex=10, WhitenStatus="On", DFPacketType="ConnectionlessCTE");

% CTE appends unmodulated constant tone for antenna switching (typ. 72-216 us)
cteDelta_conn_us = (length(wf_conn) - length(wf_noCTE)) / fs * 1e6;
cteDelta_cless_us = (length(wf_cless) - length(wf_noCTE)) / fs * 1e6;
CTE 全流程(Tx → Rx → Angle)
pduHex = '02049B03270102030405';  % 10-byte PDU (>=6 bytes needed for >=11 IQ samples)
pdu = int2bit(hex2dec(reshape(pduHex, 2, [])'), 8, false);
pdu = pdu(:);
cfgCRC = crcConfig(Polynomial="z^24+z^10+z^9+z^6+z^4+z^3+z+1", ...
    InitialConditions=int2bit(hex2dec('555551'),24), DirectMethod=true);
pduCRC = crcGenerate(pdu, cfgCRC);
txWf = bleWaveformGenerator(pduCRC, ChannelIndex=36, DFPacketType="ConnectionlessCTE");
[~, ~, iqSamples] = bleIdealReceiver(txWf, ChannelIndex=36, ...
    DFPacketType="ConnectionlessCTE", SlotDuration=2);
cfgAngle = bleAngleEstimateConfig;
cfgAngle.ArraySize = 4; cfgAngle.SlotDuration = 2; cfgAngle.SwitchingPattern = [1 2 3 4];
angle = bleAngleEstimate(iqSamples, cfgAngle);

替代方式(R2022a+):iqSamples = bleCTEIQSample(cteSamples, Mode="LE1M", SlotDuration=2);

BER 仿真
messageBits = randi([0 1], 100*8, 1); sps = 8; phyMode = "LE1M";
snrValues = 0:4:20; berResults = zeros(size(snrValues));
for idx = 1:length(snrValues)
    wf = bleWaveformGenerator(messageBits, Mode=phyMode, SamplesPerSymbol=sps, ChannelIndex=5, WhitenStatus="On");
    sigPower = mean(abs(wf).^2);
    rxWf = awgn(wf, snrValues(idx), 10*log10(sigPower));
    rxBits = bleIdealReceiver(rxWf, Mode=phyMode, SamplesPerSymbol=sps, ChannelIndex=5, WhitenStatus="On");
    n = min(length(messageBits), length(rxBits));
    berResults(idx) = sum(messageBits(1:n) ~= double(rxBits(1:n))) / n;
end
semilogy(snrValues, berResults, "-o"); xlabel("SNR (dB)"); ylabel("BER"); grid on

bleIdealReceiver 返回 int8,请使用 double() 转换。Eb/No 转换方式:snr = convertSNR(EbNo,"ebno","snr",SamplesPerSymbol=sps)。

RF-PHY 测试波形
cfg = bluetoothTestWaveformConfig;
cfg.Mode = "LE1M"; cfg.PayloadLength = 37;
cfg.PacketType = "Disabled"; cfg.ModulationIndex = 0.5;
testWf = bluetoothTestWaveform(cfg);

rfCfg = bluetoothRFPHYTestConfig;
rfCfg.Test = "Output power"; rfCfg.Mode = "LE1M";
rfCfg.PayloadLength = 37; rfCfg.OutputPower = 0; rfCfg.CenterFrequency = "Mid";
WLAN 共存
sps = 8; fs = 1e6*sps;
bleWf = bleWaveformGenerator(randi([0 1],37*8,1), Mode="LE1M", SamplesPerSymbol=sps, ChannelIndex=37, WhitenStatus="On");
t = (0:length(bleWf)-1)'/fs;
wlanInterferer = 0.1*complex(randn(length(bleWf),1),randn(length(bleWf),1)) .* exp(1j*2*pi*3e6*t);
combined = bleWf + wlanInterferer;
CIR_dB = 10*log10(mean(abs(bleWf).^2) / mean(abs(wlanInterferer).^2));
TX 测量(功率、OBW、PAPR)
sps = 8; wf = bleWaveformGenerator(randi([0 1],255*8,1), Mode="LE1M", ...
    SamplesPerSymbol=sps, ChannelIndex=37, WhitenStatus="On", ModulationIndex=0.5);
fs = 1e6*sps; N = length(wf);
avgPower_dBm = 10*log10(mean(abs(wf).^2)) + 30;
spec = abs(fftshift(fft(wf))).^2; cumP = cumsum(spec)/sum(spec);
f = (-N/2:N/2-1)*(fs/N);
occBW_MHz = (f(find(cumP>=0.995,1)) - f(find(cumP>=0.005,1))) / 1e6;
papr_dB = 10*log10(max(abs(wf).^2) / mean(abs(wf).^2));
白化比较
bits = randi([0 1], 37*8, 1); sps = 8;
wfOn  = bleWaveformGenerator(bits, Mode="LE1M", SamplesPerSymbol=sps, ChannelIndex=37, WhitenStatus="On");
wfOff = bleWaveformGenerator(bits, Mode="LE1M", SamplesPerSymbol=sps, ChannelIndex=37, WhitenStatus="Off");
广播 PDU(ADV_IND)
cfgAdv = bleLLAdvertisingChannelPDUConfig;
cfgAdv.PDUType = "Advertising indication";
cfgAdv.AdvertiserAddress = "A1B2C3D4E5F6";
cfgAdv.AdvertiserAddressType = "Random";
cfgAdv.AdvertisingData = "0201060709546573744245020A00";
pduBits = bleLLAdvertisingChannelPDU(cfgAdv);
wf = bleWaveformGenerator(pduBits, Mode="LE1M", SamplesPerSymbol=8, ChannelIndex=37);

PDUType 的值:"Advertising indication"、"Scan request"、"Scan response"、"Connection indication"、"Advertising direct indication"、"Advertising non connectable indication"。 地址:12 个字符的十六进制字符串(不含冒号)。AdvertisingData:十六进制字符串(长度-类型-值 AD 结构)。

数据信道 PDU
cfgData = bleLLDataChannelPDUConfig;
cfgData.LLID = "Data (start fragment/complete)";
cfgData.SequenceNumber = 1;
cfgData.NESN = 0;
cfgData.MoreData = false;
payload = dec2hex(randi([0 255], 50, 1))';  % 50-byte hex payload
payload = reshape(payload', 1, []);
pduBits = bleLLDataChannelPDU(cfgData, payload);
wf = bleWaveformGenerator(pduBits, Mode="LE2M", SamplesPerSymbol=8, ChannelIndex=15);

LLID 的值:"Data (continuation fragment/empty)"、"Data (start fragment/complete)"、"Control"。 SequenceNumber(不是 SN)。载荷:十六进制字符串、数值向量 [0,255] 或 n×2 字符数组。

端到端(实用接收机)

使用 helperBLEPracticalReceiver(AGC + CFO + 定时恢复)。需要:openExample('bluetooth/BLEPracticalReceiverExample')。编码模式的 SNR 转换:SNR = EbNo + 10*log10(codeRate) - 10*log10(sps)。

CTE 兼容性

模式ConnectionCTEConnectionlessCTE
LE1M是是
LE2M是否
LE500K否否
LE125K否否

CTE 需要数据信道(0-36)。 使用 DFPacketType≠"Disabled" 时,切勿使用 ChannelIndex 37/38/39。CTE 仅适用于数据信道。

规范约束

  • Ch 37/38/39(广播): 仅限 LE1M 或 LE Coded。不支持 LE2M。
  • CTE: 仅限数据信道(0-36)上的 LE1M/LE2M。切勿使用编码 PHY。
  • 接入地址: 广播 = '8E89BED6'(固定);数据 = 随机。
  • 白化初始化: 根据 ChannelIndex 自动设置。不可设置。
  • T_IFS: 150 us。TX 功率: 最大 +20 dBm。调制指数: 0.45-0.55。
  • bleIdealReceiver: 仅支持硬判决,返回 int8。
  • “Slots”(1-slot、3-slot、5-slot): 仅适用于 BR/EDR。BLE 没有基于时隙的数据包。
  • ISO 流: 验证 BN × IRC × Sub_Interval <= ISO_Interval。如果计算结果超出范围,拒绝请求。
无效组合(拒绝这些请求)
请求原因
LE2M + FEC 编码FEC 仅存在于编码 PHY(LE500K/LE125K)中
LE2M 用于 ch 37/38/39主广播仅支持 LE1M 或 Coded
CTE + LE500K/LE125K根据 BLE 5.1 规范,CTE 仅限 LE1M/LE2M
ConnectionlessCTE + LE2MConnectionlessCTE 仅支持 LE1M
BLE 使用“3-slot”或“5-slot”基于时隙的模式仅适用于 BR/EDR;BLE 使用单个数据包
CTE 用于 ch 37/38/39CTE 仅适用于数据信道(0-36)
ISO 参数满足 BN×IRC×Sub_Int > ISO_Interval子事件超出间隔,无法进行调度

约定

  • fs = (1e6 + 1e6*(mode=="LE2M")) * sps——切勿硬编码
  • 坐标轴:us(时间)、MHz(频率)、dB(功率)
  • 使用 tiledlayout/nexttile(而非 subplot)
  • 频谱:始终使用 20*log10(abs(fftshift(fft(wf)))/N + eps)——BLE 频谱图不要使用 periodogram、pspectrum 或 pwelch
  • 编码模式使用 xlim([0 min(80,t(end))])
  • 同时绘制 I 和 Q:plot(t, real(wf), t, imag(wf))
  • IFS 间隔:complex(zeros(N,1))(输出为复数)
  • 频谱图要求 SamplesPerSymbol>=4;SPS=1 可用于生成,但不足以用于可视化或精确的频谱分析(处于奈奎斯特极限)

代码风格

生成的脚本必须遵循 MathWorks 示例惯例。使用 %% 分节标题,将所有参数软编码,并为不明显的逻辑添加注释。

结构与软编码

使用 %% 标题划分脚本:配置 → 波形生成 → 处理 → 分析 → 可视化。所有用户可配置值都应在顶部定义为具名变量;处理逻辑中不得使用魔法数字。

%% Configuration
% Specify BLE waveform generation parameters.

phyMode = "LE1M";                               % PHY transmission mode
payloadLength = 37;                             % Payload length in bytes
sps = 8;                                        % Samples per symbol
channelIndex = 37;                              % BLE channel index (0-39)

% Derived parameters
symbolRate = 1e6 + 1e6*(phyMode=="LE2M");       % 2 Msym/s for LE2M, 1 Msym/s otherwise
fs = sps * symbolRate;                          % Sample rate in Hz
numBits = payloadLength * 8;                    % Payload length in bits

%% Waveform Generation
% Generate BLE waveform from random payload bits.

messageBits = randi([0 1], numBits, 1);
waveform = bleWaveformGenerator(messageBits, ...
    Mode=phyMode, SamplesPerSymbol=sps, ChannelIndex=channelIndex);
注释
  • 行内(右对齐):单位、范围或简要用途 — % Eb/No in dB
  • 块注释(上方 2-5 行):意图或原因 — % IFS gap must be complex (bleWaveformGenerator output is complex)
  • 约束:规范引用 — % LE2M uses 2 Msym/s (only mode with 2x symbol rate)
  • 不要注释显而易见的行、机械地注释每一行或注释结束的 end 语句
命名
  • camelCase:messageBits、txWaveform、symbolRate、channelIndex
  • 描述性循环计数器:countMode、pktIdx(而非 i、j)
  • 命名常量:bitsPerByte = 8、tIFS = 150e-6
  • 多重初始化:[numErrors, perCount] = deal(0, 0)

易错点

错误修正
bleWaveformConfig(...)不存在。直接使用 bleWaveformGenerator(bits, NV...)
将 bluetoothWaveformGenerator 用于 BLE仅适用于 BR/EDR。请使用 bleWaveformGenerator
comm.BLEReceiver不存在。请使用 bleIdealReceiver
LE2M 使用 symbolRate=1e6LE2M = 2e6
将 'PHYMode' 用作参数名请使用 'Mode'
将 'LECODED' 用作模式请使用 "LE500K" 或 "LE125K"
配置对象作为第 1 个参数必须是二进制列向量 randi([0 1],N,1)
空 [] 比特至少需要 1 字节
IFS 使用实数 zeros()请使用 complex(zeros(N,1))
CTE + 编码模式CTE 仅适用于 LE1M/LE2M
ConnectionlessCTE + LE2M仅适用于 LE1M
在信道 37/38/39 上使用 LE2M违反规范。请使用 LE1M 或 Coded
将 CTELength/CTEType 用作 NV 参数无效。请使用 DFPacketType
bleAngleEstimate(wf, NV...)请使用 bleAngleEstimate(iqSamples, bleAngleEstimateConfig)
将 bleWaveformGenerator 用于 RF-PHY请使用 bluetoothTestWaveformConfig + bluetoothTestWaveform
AWGN 未进行过采样校正请使用 convertSNR(EbNo,"ebno","snr",SamplesPerSymbol=sps);向 awgn 传入显式功率(绝不使用 "measured")
在存在损伤时使用 bleIdealReceiver请使用 helperBLEPracticalReceiver
编码模式的 Eb/No 未考虑码率SNR = EbNo + 10*log10(codeRate) - 10*log10(sps)
使用 SPS=1 却未警告SPS=1 处于奈奎斯特极限——提醒用户:无法进行频谱分析,解码性能可能不稳定
定时 ppm 偏移未使用 resample通过 resample(wf, 1e6+ppm, 1e6) 或分数延迟滤波器施加时钟漂移
一致性 Df1/Df2 未使用 PRBS9对 TP/TRM/CA/BV-05-C 使用 comm.PNSequence (z^9+z^5+1);将稳定比特 (Df1) 与交替比特 (Df2) 模式分开
使用 periodogram/pwelch 计算 BLE 频谱使用手动 fftshift(fft(wf))——技能规范
将 SN 用作属性名在 bleLLDataChannelPDUConfig 上使用 SequenceNumber
地址使用带冒号的 "A1:B2:..."使用不带冒号的 12 字符十六进制字符串:"A1B2C3D4E5F6"
PDUType="ADV_IND"使用完整字符串:"Advertising indication"
将二进制向量用作 AdvertisingData使用十六进制字符串:"0201060709..."(长度-类型-值)

版权所有 2026 The MathWorks, Inc.

评论

支持 Markdown