MATLAB+Pluto SDR实现OFDM点对点通信:从IFFT到信道均衡
发布时间:2026/10/13 16:11:22 锦皓数字建站

简介一套基于MATLAB与Pluto SDR的正交频分复用OFDM点对点通信系统完整实现方案面向通信工程、数字信号处理方向的开发者与研究者可用于理解多载波调制在实际射频硬件上的部署流程以及点对点数据链路层的核心设计思路。资源包共含288个文件其中160个m文件构成系统主体代码覆盖信号生成、调制映射、信道估计、同步与解调等模块116个dat文件保存了各测试点及导频波形便于对比分析另有7份PDF原理说明、1份PPT演示文稿、3个文本说明与1张示意图辅助快速上手。压缩包整体大小约124.03MB目录按功能划分检索便捷。目前已有2047人学习下载。通过该资源可完整获取从系统总体架构、串并转换、子载波分配到Pluto SDR收发链路的工程实现还可从实测数据中梳理硬件测试时的参数配置与排错思路适合用于课程设计、毕业设计或软件无线电入门实践。1. 为什么把OFDM搬到Pluto SDR上让通信原理从仿真图变成真实射频链路如果只在MATLAB里做OFDM仿真你看到的是理想信道下的BER曲线看不到真实射频前端带来的频偏、直流偏置和增益抖动。Pluto SDR是一块巴掌大的软件无线电板卡USB供电MATLAB官方支持包可以直接下发IQ波形、读回基带采样。用两块Pluto SDR就能搭出一套matlab实现基于Pluto SDR的OFDM点对点通信系统一端运行发送脚本做QPSK映射、IFFT、加循环前缀另一端运行接收脚本做定时同步、频偏补偿、FFT和信道均衡。整条链路的中间量——时域波形、频谱、星座图——都能实时看到这是纯仿真给不了的直观感。这套方案能解决两个问题一是把OFDM教材里的公式落到真实的电磁波传输上二是给课设、毕设和算法预研提供一个可改参数、可复现场景的实验台。适合正在学OFDM、想验证同步算法、或者想快速上手SDR的从业者。一个反直觉的结论是这套系统里最难的不是OFDM调制解调本身而是射频前端那几个“看不见”的参数——增益、频偏、直流偏置它们才是调试时间的大头。2. 搭好MATLAB与Pluto联调的台子支持包、参数表和频谱自检2.1 支持包安装的三个误区为什么识别不到Pluto很多人装完MATLAB发现sdrrx(Pluto)直接报错第一反应是硬件坏了其实九成是支持包没装全。这个链路依赖通信工具箱Communications Toolbox和对应的Pluto SDR支持包。较新版本中收发对象统一成sdrtx和sdrrx若是较早的版本用的还是plutoradio对象。先确认版本再查代码不然会卡在对象名上。误区一只装了Simulink支持包没装MATLAB脚本调用的支持包。Simulink模块能跑但命令行里创建sdrrx(Pluto)照样失败。装的时候留意支持包列表里“MATLAB”和“Simulink”是两项脚本调试只要前者。误区二固件太旧。某开发者的Pluto放了一年多USB枚举成功但MATLAB一直报通信超时折腾半天是固件没升级。用官方升级工具把固件刷到新版重启后问题消失。注意USB线和接口也有影响有些USB Hub供电不足Pluto会周期性掉线尽量直连主板USB口。误区三Pluto之前被人切到了网络模式。Pluto既支持USB也支持网络传输如果设备被人配置成以太网模式MATLAB支持包走USB枚举会找不到。此时先把Pluto恢复出厂设置或通过官方工具切回USB模式再做连接。连接验证代码不需要复杂关键是把排查顺序固化下来%% 连接自检确认MATLAB能看到Pluto try rx sdrrx(Pluto); % 尝试创建接收对象 fprintf(Pluto连接成功\n); catch ME disp(Pluto 没有被 MATLAB 识别按顺序检查); disp(1. USB线是否直连主板系统能否枚举出 ADALM-Pluto 设备); disp(2. Communications Toolbox Support Package 是否安装); disp(3. 固件是否过旧用官方工具升级后重试); rethrow(ME); end这段代码不是给程序做健壮性兜底是给排查顺序做锚点。报错信息里如果提到“Unable to find radio”优先查USB枚举如果提到“Failed to communicate”优先查固件版本。把“硬件没坏”这件事花五分钟确认后面才不会在射频问题上怀疑错方向。2.2 收发基础参数采样率、中心频率和增益的第一组取值Pluto的射频芯片最高支持20MHz带宽但MATLAB通过USB接口传IQ样本采样率设太高会出现周期性丢块。实测经验是5MHz以下比较稳2.5MHz作为OFDM联调的起点最省心。中心频率选2.4GHz附近要注意WiFi干扰桌面联调时先避开路由器主信道比如用2.42GHz或2.48GHz这种边缘频点。%% 收发端基础参数设置 fs 2.5e6; % 基带采样率 2.5 MHz fc 2.45e9; % 中心频率 2.45 GHz避开WiFi信道1/6/11 tx sdrtx(Pluto); tx.CenterFrequency fc; tx.SampleRate fs; tx.Gain -10; % 发射链路实际是衰减器数值越小输出越接近满功率 rx sdrrx(Pluto); rx.CenterFrequency fc; rx.SampleRate fs; rx.GainSource Manual; % 突发OFDM帧必须手动增益AGC会突变 rx.Gain 30; % 近距离桌面联调从30dB起步 rx.OutputDataType double;这里有个容易翻车的地方Pluto发射端的增益控件本质上是一个衰减器写成tx.Gain -10不是“欠激励”而是让输出更接近满量程。如果按常见的正增益思维设成10波形会被削顶接收端星座图边缘毛刺明显。接收端增益范围是0到70dB左右30dB适合一米以内的桌面联调距离放大到三五米或中间有遮挡时再往上加。手动增益这个选择很关键。OFDM突发帧的瞬时功率是脉动的帧头训练符号功率高、数据符号功率相对低。如果开着AGC接收机会随着帧头拉高增益帧尾符号幅度和噪声底一起涨星座图看起来就是一团忽大忽小的云。突发帧通信里把增益固定在Manual相当于告诉接收机“别自作主张我来管电平”。2.3 上电自检先把噪声底和阻塞看明白调通OFDM之前先做一次纯接收频谱观测。这一步花五分钟能省掉后面两个小时的“为什么星座图散得像星星”式的瞎猜。%% 观察接收频谱确认环境干扰和噪声底 rxSamples rx(); % 读取一段IQ数据 win hann(numel(rxSamples)); % 加窗抑制频谱泄漏 nfft 2^nextpow2(numel(rxSamples)); X fft(rxSamples .* win, nfft); f fs * (-0.5:1/nfft:0.5-1/nfft); % 归一化频率转Hz plot(f, 20*log10(abs(fftshift(X)))); xlabel(频率 (Hz)); ylabel(功率 (dB)); title(Pluto接收频谱);正常情况下应该看到一条平坦噪声底偶尔有几个窄带尖峰那就是周围的路由器、蓝牙或微波炉。如果在2.4GHz附近看到宽达20MHz的大鼓包说明环境干扰很强建议换个频点。这个频谱是后续所有联调的地基OFDM信号带宽只有1.6MHz左右如果它恰好落在一个WiFi信道上接收端的子载波局部会被干扰压垮误码率怎么调都下不来。注意频谱自检时接收天线可以只接一根短线但别让发射端同时工作否则看到的是自己的信号不是环境底噪。3. OFDM链路参数设计子载波、循环前缀和帧结构该取多少3.1 参数表一套现成的OFDM参数和选择理由OFDM参数不是随手拍的它们由采样率、信道环境和硬件精度共同决定。基于2.5MHz采样率我常用的参数组合如下参数取值选择理由采样率 Fs2.5 MHzPluto USB链路稳定FFT点数适中FFT点数 Nfft256Fs/Δf 取整点数少则频域分辨率粗子载波间隔 ΔfFs/Nfft ≈ 9.77 kHz对步行速度的多普勒不敏感对频偏敏感必须做CFO补偿有效子载波 Nused96避开DC和边缘保护带占用带宽约0.94MHz循环前缀长度 Ncp64对应25.6us远大于室内多径时延扩展一个符号总长320采样 128us数据效率 256/320 80%调制方式QPSK起步联调阶段用QPSK定位问题后续换16QAM子载波间隔和循环前缀是互相牵制的。Δf越大符号越短对频偏和多普勒的容忍度越高但对抗多径时需要更长的CP开销占比上升。这里9.77kHz的间隔对两人拿着天线走动完全够用但Pluto的晶振精度在20ppm量级2.45GHz下最大频偏接近49kHz超过4个子载波间隔。所以这套参数能不能跑通核心不在于多径而在于接收端能不能把频偏先压住。3.2 帧结构前导、训练符号和数据符号怎么排单发一个OFDM符号没有意义接收端不知道它什么时候到、从哪个采样点开始是符号头。所以帧结构里必须放前导而且前导的时域波形要设计得“好认”。我用的帧结构如下字段长度用途前导P1个OFDM符号不加CP频域偶数子载波放ZC序列时域形成两个相同半段用于粗定时和频偏估计训练符号T1个OFDM符号加CP频域放已知QPSK用于LS信道估计数据符号8个OFDM符号加CP承载随机比特每符号96个QPSK尾部静默16个零采样防止处理延迟导致下一帧重叠前导P的“两个相同半段”不是巧合。频域上只在偶数子载波放数据、奇数子载波置零IFFT之后时域就会出现前半段等于后半段。接收端拿前半段和后半段做自相关峰值的相位就是频偏信息峰值位置就是帧起始。这是经典的Schmidl-Cox结构好处是接收端不依赖任何本地序列副本只要有自相关性就能找帧。训练符号T负责“校正信道”。OFDM把宽带信道切成96个窄带子信道每个子信道近似平坦衰落所以在频域每个子载波上只需要一个复数乘法就能补偿幅度和相位。这个复数乘法的系数就来自T用接收频域值除以已知发送频域值得到每个子载波的信道估计。3.3 收发信号流从比特到IQ样本的完整链路发送端的信号流是随机比特 → QPSK格雷映射 → 串并转换 → 映射到96个有效子载波 → 补零到256点 → IFFT → 加循环前缀 → 拼接前导P和训练符号T → 时域归一化 → 写入sdrtx。接收端反过来sdrrx读入一段IQ样本 → 前导自相关粗定时 → CFO频偏估计与补偿 → 按帧偏移量切出训练符号和数据符号 → 去CP → FFT → 训练符号处做LS信道估计 → 每个数据符号用同一组信道系数做均衡 → QPSK判决 → 解映射 → 统计误码。这条链路里有个顺序问题值得单独说CFO补偿必须在去CP和FFT之前。因为OFDM对子载波正交性极其敏感频偏会让相邻子载波互相泄漏去CP时已经污染了采样窗口。先补偿时域相位再做FFT星座图才会收敛。3.4 为什么信道估计可以整帧共享一组系数很多人第一次做OFDM接收端会疑惑为什么不像均衡器那样逐符号更新信道因为信道估计的更新频率取决于信道随时间的变化快慢。室内桌面场景下人在天线旁边走动造成的信道变化时间常数在毫秒级以上而我们这一帧总长只有1.3ms左右。一个训练符号估计出的信道整帧内基本没变逐符号重估不仅没有增益反而会把噪声引进来。真正需要逐符号处理的不是信道而是残余频偏和相位噪声。如果做完CFO补偿后星座图还在缓慢旋转通常是整数倍频偏没补干净或者残余频偏超过子载波间隔的百分之一。这时候不要急着改成逐符号信道估计先把频偏精度提上去。4. 用MATLAB实现OFDM收发从IFFT调制到LS信道均衡的完整代码4.1 发送端代码比特映射、IFFT、加CP与组帧发送端的核心是把一帧数据组织成时域IQ样本。下面这段把前面设计的参数全部落成代码%% OFDM发送端构造一帧并送入Pluto Nfft 256; Ncp 64; Nused 96; Ndata 8; M 4; % 有效子载波索引DC(129)留空两侧各48个子载波 usedIdx [61:108, 148:195]; % 1. 随机比特 - QPSK映射格雷编码 bits randi([0 1], Nused*Ndata*log2(M), 1); qpsk (1 - 2*bits(1:2:end))/sqrt(2) ... 1i*(1 - 2*bits(2:2:end))/sqrt(2); % 2. 符号映射到有效子载波DC和边缘置零 gridData zeros(Ndata, Nfft); gridData(:, usedIdx) reshape(qpsk, Nused, Ndata).; % 3. IFFT调制成时域OFDM符号 txSym ifft(gridData, Nfft, 2); % 4. 加循环前缀 txSymCp [txSym(:, Nfft-Ncp1:end), txSym]; % 5. 前导P偶数子载波放ZC序列IFFT后时域前后半段重复 idxEven usedIdx(mod(usedIdx,2) 0); P_freq zeros(1, Nfft); P_freq(idxEven) exp(-1i*pi*(0:numel(idxEven)-1).^2 / numel(idxEven)); preamble_t ifft(P_freq, Nfft); % 6. 训练符号T已知QPSK序列加CP T_freq zeros(1, Nfft); T_freq(usedIdx) (1 - 2*randi([0 1], 1, Nused))/sqrt(2) ... 1i*(1 - 2*randi([0 1], 1, Nused))/sqrt(2); training_t ifft(T_freq, Nfft); training_t [training_t(Nfft-Ncp1:end), training_t]; % 7. 拼接整帧归一化到0.9倍满量程 frame_t [preamble_t, training_t, reshape(txSymCp., 1, [])]; frame_t frame_t / max(abs(frame_t)) * 0.9; % 8. 送入发射对象 tx sdrtx(Pluto); tx.CenterFrequency 2.45e9; tx.SampleRate 2.5e6; tx.Gain -10; tx(frame_t);几个参数说明usedIdx把96个有效子载波分配在DC两侧中间空出129号直流子载波和两侧保护带这是给直流偏置留的退路。gridData是Ndata×Nfft的矩阵每行是一个OFDM符号ifft(..., 2)按行做IFFT得到时域符号矩阵。加CP时取每行末尾64点拼到前面这个操作把符号长度从256扩展到320采样。前导P没有加CP因为它靠时域内部的重复结构做同步加了CP反而破坏“前后半段相同”的特性。tx(frame_t)是一次性把整帧发出去Pluto内部会把它连续循环发射方便接收端反复捕捉。发射增益保持-10dB确保峰值功率接近满量程但不削顶。4.2 接收端代码定时、频偏补偿、FFT与LS均衡接收端是整套系统里最容易写错的部分因为所有处理都必须对齐帧头。这里给出完整流程帧偏移的计算和发射端结构一一对应。%% OFDM接收端帧检测、CFO补偿、信道均衡 rx sdrrx(Pluto); rx.CenterFrequency 2.45e9; rx.SampleRate 2.5e6; rx.GainSource Manual; rx.Gain 30; % 1. 读取足够长的样本覆盖两帧以上 rxData rx(); % 2. 时域减去均值抑制直流偏置 rxData rxData - mean(rxData); % 3. Schmidl-Cox粗定时前导前后半段自相关 D Nfft/2; % 128前半段和后半段的延迟 windowLen numel(rxData) - 2*D; metric zeros(windowLen, 1); for ddx 1:windowLen seg1 rxData(ddx:ddxD-1); seg2 rxData(ddxD:ddx2*D-1); metric(ddx) abs(sum(conj(seg1) .* seg2)); end [~, estStart] max(metric); % 4. 小数倍频偏估计相关峰处相位差 seg1 rxData(estStart:estStartD-1); seg2 rxData(estStartD:estStart2*D-1); phaseDiff angle(sum(conj(seg1) .* seg2)); cfo -phaseDiff / (2*pi*D) * fs; % 5. 时域频偏补偿 tIdx (0:numel(rxData)-1).; rxCfo rxData .* exp(-1i*2*pi*cfo/fs*tIdx); % 6. 切出训练符号并做LS信道估计 trainT rxCfo(estStart Nfft : estStart Nfft Nfft Ncp - 1); trainT trainT(Ncp1:end); % 去CP trainF fft(trainT, Nfft); Hest trainF(usedIdx) ./ T_freq(usedIdx); % 每个子载波一个复系数 % 7. 逐个数据符号解调 rxSym zeros(Ndata, Nused); for k 1:Ndata symStart estStart Nfft k*(NfftNcp); symT rxCfo(symStart : symStart Nfft Ncp - 1); symT symT(Ncp1:end); % 去CP symF fft(symT, Nfft); eqF symF(usedIdx) ./ Hest; % 单抽头均衡 rxSym(k, :) eqF; end这段代码里最值得留意的是索引计算。前导P不占CP所以训练符号从estStartNfft开始数据符号每隔NfftNcp取一个。如果索引偏一个采样星座图会随着子载波频率逐渐相位旋转高频子载波错得比低频厉害——这是定时偏差的典型症状和频偏的表现不一样。LS信道估计是最简单的方式适合联调阶段。训练序列若在某个子载波上恰好幅度很小估计值会被噪声放大实际中可在估计后加一个最小幅度保护比如Hest(abs(Hest)0.1) 0.1;避免除零。4.3 先做内存环回把算法问题和射频问题切开上射频联调之前强烈建议先在MATLAB内存里做环回验证。把发射端生成的frame_t直接当成接收端输入人为加上几百个采样延迟跑完整个接收端流程看BER是否为0。这一步不是为了“仿真通过”而是为了确认OFDM收发算法本身没有索引错位和逻辑错误。%% 内存环回不经过Pluto验证OFDM链路自身正确 rxData frame_t; % 直接赋值 % 人为加入延迟和噪声更接近真实缓冲场景 rxData [zeros(137,1); rxData; zeros(137,1)]; rxData rxData 0.01*randn(size(rxData)); % 低信噪比叠加 % 然后执行4.2中的第3步到第7步统计误码如果内存环回BER不为0别碰无线先在信号处理逻辑里找问题。索引、顺序、共轭方向这些都是高频错点。只有内存环回跑通了再上Pluto此时出现的误码才值得怀疑射频前端。5. Pluto SDR点对点联调避坑五个高频翻车现场与排查顺序5.1 频偏导致星座图旋转先补整数倍还是小数倍现象QPSK星座图的四个点连成一个闭合圆环均衡之后仍然在缓慢旋转BER一直掉不下来。原因收发两端晶振不同源标称20ppm的晶体在2.45GHz上产生约49kHz的频偏而子载波间隔只有9.77kHz。这已经不是“微小偏差”而是跨越了多个子载波。Schmidl-Cox方法利用前导重复结构只能估计±半个子载波间隔的小数倍频偏整数倍频偏会让频域数据整体错位星座图看起来像被“拧”过一圈。解决补偿顺序必须是先整数倍、后小数倍。整数倍频偏用频域互相关搜索在接收FFT结果里平移子载波索引和本地训练序列做相关峰值对应的平移量就是整数倍频偏intRange -5:5; % 覆盖±5个子载波间隔 metric zeros(size(intRange)); for ii 1:numel(intRange) shift intRange(ii); % 把接收训练符号的子载波索引平移shift和本地序列相关 metric(ii) abs(sum(conj(T_freq(usedIdx)) .* ... trainF(usedIdx shift))); end [~, best] max(metric); cfoInt intRange(best); % 整数倍补偿后再做小数倍估计和相位旋转补偿做了整数倍补偿后星座图的“圈”会变成四个靠近原点的点残余的几十赫兹频偏用小数倍补偿压掉。血泪经验是顺序反了会出现小数估计被整数污染补偿完了星座图还是一团糊白调半天。5.2 AGC在突发帧上的玄学为什么突发OFDM必须手动增益现象接收端星座图一会儿爆开一会儿挤在原点BER忽高忽低用连续波测试时信号强度却正常。原因Pluto的AGC按接收功率连续调整增益而OFDM是突发帧前导功率高、数据符号功率低。AGC为了卡前导峰值把增益拉高数据符号到来时噪声和信号一起放大星座图云团半径不断变化。连续波没有这个问题因为它功率恒定AGC稳定后增益不变。解决突发OFDM场景下固定手动增益。一米的桌面联调推荐发射增益-10dB、接收增益25~35dB。用接收样本的RMS检查电平rxLevel rms(real(rx())); disp(20*log10(rxLevel / 0.25)); % 接近-6~-10dB为合理区间判断经验是时域波形最大幅度长期贴着±0.75的量化上限就是增益过高在削顶RMS低于满量程20dB以上就是增益太低噪声占主导。把RMS打出来看一眼比盯着星座图猜高效得多。5.3 直流偏置中心子载波旁边始终解不对现象无论输入功率怎么调FFT结果里DC对应的子载波和它旁边几个子载波的符号错误率特别高均衡也救不回来。原因零中频接收机里本振泄漏经过混频器自混频在基带产生一个直流分量。这个直流在FFT里泄漏到DC及邻近bin。Pluto没有在支持包里做自动直流校准所以它一直存在。解决双管齐下。发送端设计时就把DC和两侧空出来前面代码里用usedIdx避开129号子载波就是这个原因接收端在时域减掉均值rxData rxData - mean(rxData); % 减直流如果减完之后DC附近仍有残余再在频域把DC±2个bin强制置零兜底。注意减均值要在CFO补偿之前做因为频偏补偿是对时域样本旋转相位不会改变直流分量顺序反了影响不大但没有必要。5.4 帧同步翻车自相关峰是平台而不是尖峰现象同步后星座图整体发散但点还“成簇”BER在30%上下浮动偶尔一整段全错。原因Schmidl-Cox自相关函数在循环前缀长度内是一个平台直接取最大值会把定时点定到平台边缘。如果数据符号里恰好有和CP相似的片段峰值还会偏移到符号内部。解决粗定时之后加一步精同步用循环前缀的相关性在粗定位附近搜索searchRange estStart-16 : estStart16; cpMetric zeros(size(searchRange)); for kk 1:numel(searchRange) s0 searchRange(kk); cpMetric(kk) abs(sum(conj(rxCfo(s0:s0Ncp-1)) .* ... rxCfo(s0Nfft:s0NfftNcp-1))); end [~, idx] max(cpMetric); fineStart searchRange(idx);粗同步保证不跑远精同步保证不偏差。两步叠加后残留的定时偏移应小于一个采样点。多径较强的环境里粗同步前可以给度量曲线做一个移动平均平滑防止瞬时噪声把峰位带偏。5.5 MATLAB接收丢样本一帧的后半段全错现象内存环回完全正常空中联调时每帧从前半段某个符号开始整段错码缩短帧长度后问题消失。原因MATLAB脚本在接收循环里做频偏补偿、均衡、星座图绘制这些操作耗时超过Pluto内部缓冲区覆盖的时间硬件只能丢弃后续样本。USB传输本身是突发的接收端隔太久才去读数据就会丢。解决接收端一次读入足够长的样本离线处理不在读取数据的循环里做可变耗时操作rxData rx(); % 一次读入至少两帧长度的数据 % 之后所有同步、均衡、绘图都基于这份离线数据如果必须伪实时连续处理就把显示和统计放到整帧处理完之后并确保每帧之间留出固定间隔。对于链路质量评估离线处理完全够用还避免了实时性带来的各种隐性问题。6. 给链路装上仪表EVM、BER曲线和自适应调制的落地技巧6.1 用EVM把星座图质量变成数字星座图肉眼看个大概不够调参时必须有一个单值指标。RMS EVM是均衡后符号和参考符号之间的误差向量幅度它能反映频偏残余、噪声、非线性失真的综合效果ref (1 - 2*bits(1:2:end))/sqrt(2) ... 1i*(1 - 2*bits(2:2:end))/sqrt(2); % 发送端参考QPSK eqSym rxSym(:); % 所有均衡后符号 EVM sqrt(mean(abs(eqSym - ref).^2) / mean(abs(ref).^2)) * 100;判断经验供参考EVM小于8%链路状态健康8%~15%可用但余量小出现偶发误码超过20%基本无法可靠传输。EVM比BER更灵敏BER要到临界点才突变而EVM从一开就平滑变化适合做参数微调的比较依据。6.2 扫接收增益得到BER曲线把实验设计成控制变量才能定位最优工作点。固定距离1米发射增益-10dB不变接收增益从15dB到45dB每5dB一档每档统计500帧以上的误码接收增益(dB)15202530354045记录时不要只看BER是否为0还要同时记录RMS电平和EVM这样能看出性能拐点是来自噪声还是削顶。BER0时加大统计帧数再确认几百比特的样本量太小说明不了鲁棒性。6.3 自适应调制让链路自己选QPSK还是16QAMOFDM的价值在于可以根据信道质量动态调整调制阶数。一个简单的落地做法是用均衡后的信号功率和误差功率估算SNRsignalPow mean(abs(eqSym).^2); noisePow mean(abs(eqSym - ref).^2); snrEst 10*log10(signalPow / noisePow);然后按阈值切换SNR低于10dB用QPSK10~18dB用16QAM高于18dB用64QAM。把建议调制阶数显示在接收端终端手动改发送端脚本里的M参数这就是一套人工闭环的自适应系统。要全自动也不难用第二块Pluto做反向反馈信道但联调阶段建议一步一步来先人工确认切换逻辑正确再谈自动化。我自己第一次把链路从内存环回搬到两块Pluto之间时连续调了三小时最后发现罪魁祸首是发射增益设成10导致削顶改成-10后星座图立刻收紧。后来养成了习惯每次改完参数先把接收RMS电平打出来看一眼再跑误码统计最后才盯星座图。这套链路真正跑通不难难的是把每个数字变化和射频现象对应起来希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。