pi/4-QPSK与Turbo码MATLAB误码率仿真链路详解
发布时间:2026/10/20 14:51:17 锦皓数字建站

简介面向通信工程与电子信息类专业学习者这套Matlab工程实现了基于pi/4-QPSK调制解调与Turbo编译码的完整通信链路可在AWGN信道下统计误码率支持Matlab 2022a直接运行。压缩包共10个文件包含7个.m源码、2个.mat数据及1个txt说明整体约41KB。Turbo编码、译码和MAP译码函数分工清晰三个主程序分阶段完成调制、加噪解调及误码对比.mat文件保存中间变量txt内附操作演示视频地址。仿真流程覆盖随机二进制序列产生、Turbo编码、pi/4-QPSK调制、AWGN信道加噪、解调、Turbo译码和误码比对。程序均带中文注释操作视频可帮助快速上手。目前已有113人学习。通过这套代码读者可清晰理解pi/4-QPSK星座映射、Turbo迭代译码及误码率统计全过程也可在仿真参数和信道条件上二次开发适合作为课程设计与算法验证的基础框架。1. pi/4-QPSK与Turbo编译码通信链路一条误码率曲线背后的工程量拿到“基于pi/4-QPSK调制解调Turbo编译码通信链路matlab误码率仿真”这个标题很多人的第一反应是“跑个蒙特卡洛画条BER曲线”但实际做过的都知道这条曲线是最容易翻车的地方调制端相位跳变、差分检测的噪声乘积项、Turbo译码器的LLR符号约定、EbN0与EsN0的换算任何一环出错曲线就变成一条“有模有样但完全错误”的结果。这篇文章按我实际搭链路的顺序把pi/4-QPSK调制解调、Turbo编译码、误码率统计从原理到MATLAB代码一层层拆开适合正在做物理层算法验证、毕业设计预研或想评估这个链路方案的工程师。你可以直接照着小节抄代码改参数也能在最后一章拿到我调链路时的排查顺序和加速技巧。2. 为什么是pi/4-QPSK配Turbo差分相位调制与迭代译码的合作逻辑2.1 pi/4-QPSK的星座旋转与相位跳变约束从QPSK到pi/4的改动在哪普通QPSK的星座点落在两个正交轴上星座点之间最大相位跳变是180度。当信号经过带限滤波后再进入非线性功放180度相位跳变会让包络瞬间过零产生严重的频谱再生邻道泄漏指标很难压住。pi/4-QPSK的改动核心是每相邻符号之间的相位差被限制在±pi/4和±3pi/4这4个值上最大相位跳变从180度降到135度包络起伏明显变小。这个特性让pi/4-QPSK在功放回退不足的场景下仍然能保持较好的频谱形状也因此大量出现在移动卫星通信和窄带无线系统里。实现上pi/4-QPSK的符号相位不是直接映射而是“累加”出来的。每个符号携带2比特信息这2比特决定当前符号相对上一符号旋转多少相位。由于相位是逐步累加的接收端可以做差分检测不需要恢复绝对载波相位。这个特点在突发通信里很划算——省掉了载波同步的开销代价是AWGN信道下比相干QPSK差2~3dB。差多少取决于信噪比区域后面第3章会给出量化结果。注意这里有个容易混淆的点pi/4-QPSK的星座点交替落在两套星座上。奇数符号落在相位为±pi/4、±3pi/4的4个点上偶数符号落在0、±pi/2、pi的4个点上。如果直接把接收信号按绝对星座判决会看到“星座点在两套星座之间跳来跳去”这不是程序bug是体制本身如此。2.2 Turbo码的分量码与交织器编码增益从哪里来Turbo码的本质是两个递归系统卷积码RSC通过交织器并行级联。编码器把信息比特分成两路一路直接进第一个RSC输出系统比特和校验比特1另一路经过交织器打乱顺序后进第二个RSC输出校验比特2。译码时两个分量译码器交替工作每个译码器把自己对“哪些比特更可能是0或1”的判断外信息传给对方迭代几次后判决输出。这里要理解一个工程关键点Turbo码的增益不是一次性到位的它随迭代次数逐步逼近而且交织器长度直接决定增益上限。在误码率仿真里如果帧长只有几百比特交织器散不开Turbo增益会比理论值差1dB以上。一般仿真里至少取1024比特以上的交织器才看得到明显的瀑布区。另一个关键点是分量码的生成多项式用的较多的是八进制表示下的7,5也就是生成矩阵[1 1 1; 1 0 1]约束长度3这个多项式在中等帧长下性能稳定适合作为仿真基线。Turbo译码需要的是软信息这对调制解调提出了要求解调器最好输出对数似然比LLR而不是硬判决比特。pi/4-QPSK的差分解调恰好能提供这一类软信息——差分解调输出的复数信号实部和虚部本身就携带了“距离判决门限多远”的信息。这就是pi/4-QPSK和Turbo码天然能配合的原因之一。2.3 调制与编码的合作逻辑带宽效率、非线性和迭代增益的折中把pi/4-QPSK和Turbo放在一起并不是随意的。只看调制pi/4-QPSK每符号2比特带宽效率和QPSK相同抗非线性能力更强只看编码Turbo码在低信噪比下能提供5dB以上的编码增益但代价是带宽展宽。二者级联后Turbo码率取1/2时总频谱效率是1bit/s/Hz比未编码8PSK低一些但误码率性能明显更好。这个折中在功率受限、带宽紧张的链路里很常见。实际链路里还要考虑一个被仿真忽视的因素差分检测下的Turbo增益能不能发挥出来。差分检测有一个特点它的等效噪声是两项的叠加——AWGN本身加上相邻符号噪声的乘积项。这个噪声乘积项在高信噪比下不随SNR同步下降导致误码率曲线出现“地板效应”。所以在做这个仿真时我会先把纯pi/4-QPSK差分检测的理论误码率单独跑一条曲线再叠加Turbo码看整体增益两条曲线的差值才是Turbo在差分体制下真实贡献的编码增益。如果不做这一步很容易把差分检测的损耗误判成Turbo没调好。3. 用MATLAB搭建pi/4-QPSK调制解调差分编码、成型滤波与EbN0标定3.1 差分编码与星座映射从比特对到相位增量搭链路的第一步是写调制器。核心逻辑是把每2个比特映射成一个相位增量再累加到当前相位上。下面这段代码可以直接保存成pi4qpsk_mod.m我按可读性优先写的仿真速度也够用function [tx, refSym] pi4qpsk_mod(bits, sps, rolloff, span) % pi/4-QPSK调制 % 输入bits 0/1行向量长度必须为偶数 % sps 每个符号采样点数典型值4 % rolloff 根升余弦滚降系数典型值0.35 % span 滤波器跨符号长度典型值6 % 输出tx 成型滤波后的复基带信号 % refSym 未成型前的复符号用于对比 N length(bits) / 2; bi bits(1:2:end).; % I路比特 bq bits(2:2:end).; % Q路比特 % Gray映射的差分相位增量表 % 00 - pi/4, 01 - 3pi/4, 11 - -3pi/4, 10 - -pi/4 idx bi * 2 bq 1; dphiTable [pi/4; 3*pi/4; -3*pi/4; -pi/4]; % 相位累加初始相位pi/4保证首个符号落在奇星座 phi cumsum([pi/4; dphiTable(idx)]); sym exp(1j * phi(2:end)); % 复符号序列 % 根升余弦成型滤波 rrc rcosdesign(rolloff, span, sps, sqrt); up upsample(sym, sps); tx conv(up, rrc, same); % same截断会引入边界效应见3.3 refSym sym; end这段代码里最容易出错的是差分增量表的顺序。idx bi*2 bq 1这个索引方式把“00”映射到第1个增量pi/4“01”映射到3pi/4这是配合Gray码的邻接约束选的相邻象限只差1个比特。如果你把这个表的顺序写反误码率会立刻恶化大约1dB而且很难排查。成型滤波用的是MATLAB自带的rcosdesign它生成的是根升余弦脉冲注意发送端和接收端各用一次根升余弦合起来才是无码间串扰的升余弦。3.2 根升余弦成型与AWGN信道滚降系数和噪声方差怎么设成型滤波器的参数里滚降系数影响带宽和峰值功率的折中。仿真里取0.35比较常见它对应30%左右的额外带宽如果做带宽受限的链路预算可以取0.2但时域拖尾变长对群延迟补偿的精度要求更高。span取6到8即可再大滤波器的阶数上去卷积计算变慢而误码率性能几乎不变。加噪声的写法是另一个高发错误点。复基带AWGN信道下信号平均功率归一化为1噪声每维方差是N0/2。接收端先匹配滤波再按符号率采样所以噪声方差要在符号能量层面标定。function rx add_awgn(tx, EsN0dB) % 给复基带信号加AWGN % 输入tx 归一化功率信号EsN0dB 符号信噪比dB EsN0 10^(EsN0dB/10); N0 1 / EsN0; % 信号功率为1时N0 1/EsN0 sigma sqrt(N0 / 2); % 每维噪声标准差 rx tx sigma * (randn(size(tx)) 1j * randn(size(tx))); end这段代码里有一个关键换算需要记住因为我们把信号的符号能量Es归一化为1所以N0等于1/EsN0噪声每维方差是N0/2。如果你用awgn(tx, EsN0dB, measured)函数它会自己测量信号功率再按SNR加噪也能用但它默认SNR是信号功率与噪声功率的比不是符号能量与噪声谱密度之比。在通信仿真里建议统一用上面这种显式写法避免awgn函数的测量误差把曲线平移零点几个dB。3.3 相干/差分解调的实现与EbN0的三种换算误区解调端我一般先做匹配滤波和采样再做差分判决。差分检测的原理是把当前符号乘以上一个符号的共轭得到的复数值的相位角就是两个符号之间的相位差。因为发送端相位是累加的这个相位差直接对应原始比特对。代码里必须先补偿匹配滤波器的群延迟否则采样点不在眼图开启时刻星座点会散开。function bitsHat pi4qpsk_demod(rx, sps, rolloff, span) % pi/4-QPSK差分解调 % 输入rx 接收复基带信号 rrc rcosdesign(rolloff, span, sps, sqrt); y conv(rx, rrc); % 完整卷积避免截断 delay span * sps; % 发送接收滤波器总群延迟 y y(delay 1 : sps : end); % 从延迟点开始按符号率抽取 % 差分检测当前符号乘上一符号共轭 dy y(2:end) .* conj(y(1:end-1)); % 按象限判决相位差与调制端Gray表对应 % 象限 [0, pi/2) - 00, [pi/2, pi) - 01, % [-pi, -pi/2) - 11, [-pi/2, 0) - 10 dph angle(dy); bi zeros(size(dph)); bq zeros(size(dph)); bi( dph 0 dph pi/2) 0; bq( dph 0 dph pi/2) 0; bi( dph pi/2) 0; bq( dph pi/2) 1; bi( dph -pi/2) 1; bq( dph -pi/2) 1; bi( dph -pi/2 dph 0) 1; bq( dph -pi/2 dph 0) 0; bitsHat reshape([bi; bq], 1, []); end这里有两个细节。第一匹配滤波用conv而不是conv(...,same)因为same会把输出对齐到输入长度丢失尾部符号并引入开头不完整滤波的瞬态完整卷积后从第delay1个点开始抽取才是正确的符号起点。第二差分解调丢掉了第一个符号的载波相位信息所以有效符号数比发送少1个统计误码率时收发序列要对齐——发送端也丢掉第一个符号再比对。EbN0和EsN0的换算是这个仿真里最容易埋雷的地方。pi/4-QPSK每符号2比特接入码率为R的Turbo编码后每个信息比特对应1/R个信道符号、2/R个信道比特。因此rate 1/3; % Turbo编码率 EbN0dB 2; % 以信息比特为单位的目标信噪比 EbN0 10^(EbN0dB/10); EsN0 EbN0 * 2 * rate; % 每符号能量 每比特能量 * 每符号比特数 * 码率 EsN0dB 10*log10(EsN0);三种常见误区一是直接把EbN0当EsN0加噪曲线整体右移约5dB二是忘了乘码率Turbo增益算出来虚高三是把2*rate写成2/rate方向搞反结果跟理论值对不上。我的习惯是在主循环里把EbN0dB、EsN0dB、噪声方差三个值都打印出来做第一帧之后先肉眼检查2dB的EbN0对应约-1.76dB的EsN01/3码率时噪声方差的量级应该在0.3左右。4. Turbo编译码接入链路分量码多项式、交织器与迭代译码参数4.1 两个RSC分量码与打孔码率怎么从1/3变1/2调制部分跑通并画出无编码误码率曲线后再接入Turbo编译码。RSC编码器是Turbo的基础我给出的实现是约束长度3、7,5多项式的反馈型编码器function [sys, par] rsc_encode(u, g) % RSC递归系统卷积编码器 % 输入u 0/1比特行向量 % g 生成矩阵每行一个多项式如 [1 1 1; 1 0 1] % 输出sys 系统比特等于upar 校验比特 g0 g(1, :); % 反馈多项式 g1 g(2, :); % 前向多项式 M length(g0) - 1; state zeros(1, M); N length(u); par zeros(1, N); for k 1:N fb mod(u(k) sum(state .* g0(2:end)), 2); % 反馈比特 par(k) mod(sum([fb, state] .* g1), 2); state [fb, state(1:end-1)]; % 状态更新 end sys u; end两个RSC编码器共享同一份系统比特只是第二个编码器输入的是交织后的比特。如果直接发两个校验比特码率是1/3如果想让码率升到1/2就做打孔——交替丢弃两个校验比特序列的一部分。仿真里我建议先跑1/3码率验证整条链路正确再改打孔。原因是1/3码率下每个信息比特有两个校验比特兜底Turbo增益更明显链路是否正确更容易判断先把这版跑通打孔只是加几行索引选择代码的事。4.2 交织器设计短帧仿真里决定成败的参数交织器是Turbo码的“第二根支柱”。理论上交织器越随机越好让两个分量译码器拿到的信息尽量不相关。但短帧下伪随机交织器可能随机出局部密集的映射导致低重量码字出现误码率曲线出现地板。常用替代是S随机交织器它约束任意两个距离小于S的输入位置交织后距离也至少为S。S取值一般不超过sqrt(N/2)。function inter s_random_interleaver(N, S) % S随机交织器生成N为交织长度S为最小距离约束 % 注意N较大时暴力搜索很慢工程上常用分层搜索替代 inter zeros(1, N); candidates randperm(N); pos 0; while pos N pos pos 1; for c 1:length(candidates) cand candidates(c); ok true; % 检查已有映射中是否违反S距离约束 for j 1:pos-1 if (abs(pos - j) S abs(cand - inter(j)) S) || ... (abs(pos - j) S abs(cand - inter(j)) 1) ok false; break; end end if ok inter(pos) cand; candidates(c) []; break; end if isempty(candidates) error(搜索失败需增大S或换随机种子); end end end end这段代码在N256以下跑得动N到1024时暴力搜索会卡到无法接受。我实际仿真时N4096用的不是这个暴力版本而是用随机交织器跑多帧取平均——因为长帧下伪随机交织器已经足够接近理想随机没必要为S约束付出几百倍的找交织器时间。这个取舍本身就是仿真和实系统的一个差异实测里交织器是一次性设计好固定下发仿真里可以每帧重生成但每帧重生成会让不同帧的编码增益波动这波动会被平均进误码率里。建议固定一个交织器跑完全部帧单独测试交织器影响时再换。4.3 log-MAP迭代译码与端到端误码率仿真主循环Turbo译码器我采用max-log-MAP近似相比完整log-MAP性能损失约0.1~0.2dB但实现简单、数值稳定。分量译码器内部是标准的BCJR前向后向算法分支度量用接收符号的LLR和先验LLR累加。迭代控制上外信息在迭代后期要乘一个缩放因子我习惯取0.75可以抑制相关性累积带来的性能回退。下面是完整的主循环带Turbo编码、pi/4-QPSK调制解调、迭代译码和误码率统计每个EbN0点统计到指定错误数才停%% 主仿真参数 EbN0dB 0:0.5:4.5; % 扫信噪比范围 N 1024; % 每帧信息比特数也是交织器长度 rate 1/3; % Turbo码率 numIter 6; % 迭代译码次数 maxErr 100; % 每个SNR点至少统计100个错误比特 maxFrames 300; % 单个SNR点最大帧数防死循环 %% 固定交织器与RSC多项式 inter s_random_interleaver(N, round(sqrt(N/2))); g [1 1 1; 1 0 1]; % (7,5) RSC rng(42); % 固定随机种子保证实验可复现 %% 每个SNR点仿真 ber zeros(size(EbN0dB)); for snrIdx 1:length(EbN0dB) EbN0 10^(EbN0dB(snrIdx)/10); EsN0 EbN0 * 2 * rate; sigma sqrt(1/(2*EsN0)); totalErr 0; totalBits 0; for f 1:maxFrames % 信源与Turbo编码 u randi([0 1], 1, N); [~, p1] rsc_encode(u, g); [~, p2] rsc_encode(u(inter), g); coded [u; p1; p2]; % 3行对应1/3码率 % pi/4-QPSK调制 sMod pi4qpsk_mod(coded(:)., 4, 0.35, 6); % AWGN信道 noise sigma * (randn(size(sMod)) 1j*randn(size(sMod))); r sMod noise; % 差分解调输出硬比特软输出见第6章 bitsHat pi4qpsk_demod(r, 4, 0.35, 6); % 解交织送入Turbo译码器按coded的行顺序重排 sysHat bitsHat(1:3:end); % 提取系统比特估计 p1Hat bitsHat(2:3:end); p2Hat bitsHat(3:3:end); uHat turbo_decode(sysHat, p1Hat, p2Hat, inter, g, numIter); % 统计误码 e sum(u ~ uHat(1:N)); totalErr totalErr e; totalBits totalBits N; if totalErr maxErr, break; end end ber(snrIdx) totalErr / totalBits; end这段主循环有两点需要说明。第一coded的行顺序是“系统比特、校验1、校验2”接成串后调制解调端按同样间隔拆回三路。如果打孔改成1/2码率拆回的地方要做对应的索引补偿这是改动时最容易出错的位置。第二turbo_decode需要同时用系统比特和两路校验比特系统比特在所有帧里都存在但校验比特按码率打孔后译码器里对应位置的LLR要置0表示无信息不能直接删掉因为BCJR的分支度量要求每个时刻都有输入。5. 链路联调的5个常见坑从曲线反常到译码不收敛5.1 现象低信噪比下BER反而更低有一次仿真结果里EbN00dB的误码率是3e-22dB反而到了4e-2曲线整体倒挂。排查发现是“每个SNR点固定跑500帧”导致的统计问题低SNR时每帧错误比特多500帧累积了足够样本高SNR时大多数帧零错误仅有的几帧错误撑不起统计精度误码率随SNR波动很大。原因还有一层——高SNR下偶发的突发错误被max-log-MAP近似放大几帧的权重异常拉高均值。解决改成“最少错误数停止准则”每个SNR点至少统计100个错误比特再停。高SNR点如果跑够最大帧数还没到100个错误说明误码率已经低于1e-4量级这个点要么放弃要么接受置信度不足的结果在图上用空心标记区分。另外max-log-MAP译码器外信息加0.75缩放因子可以抑制高SNR下的过估计问题。5.2 现象差分解调比理论QPSK多损耗3dB以为是程序bug这是差分体制的“正常现象”被误诊成bug的典型案例。pi/4-QPSK差分检测有两个损耗来源一是差分检测时当前符号噪声与上一符号噪声相乘产生二阶噪声项二是差分编码本身让每个符号的误判会“传染”给下一符号。合起来在误码率10^-4附近比相干QPSK差约2.2~2.5dB比特信噪比下接近3dB。排查办法先跑一个无Turbo的pi/4-QPSK差分检测误码率曲线跟理论QPSK曲线对比。如果差值是3dB左右且曲线斜率一致说明解调链路正确如果差值更大且随SNR增大差值还在变才需要查EbN0换算。我之前在某个预研项目里就是因为没做这条对照曲线把差分损耗算到了Turbo头上多调了一星期交织器。5.3 现象迭代次数增加误码率不降反升Turbo译码迭代3次时误码率2e-3迭代8次反而到了4e-3。原因有两个叠加一是max-log-MAP的分支度量近似在迭代后期误差累积外信息被反复放大二是迭代次数增加后两个分量译码器的外信息高度相关相关性成了“虚假证据”。解决把迭代次数定为6次这是短帧下增益和稳定性的折中点外信息引入缩放因子第一轮迭代不缩放后续每轮乘0.75。每一轮迭代后可以算一下外信息均值如果连续两轮均值变化小于某个阈值比如1e-3就提前终止。代码里加这个早停逻辑仿真时间能省20%左右而且高SNR点不容易出现迭代振荡。5.4 现象整帧比特全部翻转误码率在0.5附近不动Turbo译码器输出几乎全部取反误码率卡在接近0.5这是LLR符号约定和交织器索引不一致导致的。具体来说可能RSC编码器的反馈多项式方向写反、系统比特的LLR该取负却取了正、交织器用1-based索引但在某个地方按0-based用了三者任一处不对迭代译码就无法收敛。更隐蔽的是pi/4-QPSK差分解调的比特映射跟编码器内部“0对应正LLR还是负LLR”没有约定全反时误码率恰好是0.5看起来像随机输出。解决搭一个“编码-译码回环”的单元测试。不经过调制解调直接把编码比特当BPSK硬判决送进译码器对比输入输出再逐步加入调制、解调、噪声。哪一步开始翻车问题就在哪一步。我一般在主程序里保留这个回环测试函数每次改参数后先跑一遍确认无误再跑蒙特卡洛。5.5 现象星座点拖尾误码率曲线在高信噪比出现地板匹配滤波后的星座图上符号点不是集中在4个相位簇里而是有拖尾、有点分散。高信噪比下误码率不再下降固定在一个平台。原因基本是成型滤波器和匹配滤波器的群延迟没补偿干净采样点落在两个符号的交界处。rcosdesign的根升余弦滤波器群延迟是span*sps/2个采样点发送接收两级级联后总延迟是span*sps个采样点。如果接收端直接沿用same截断波形起点偏移半个符号周期实际采样点就全错了。解决接收端用完整卷积并把起始点放在delay1见3.3节的代码。如果做完补偿还差一点可以做符号级定时调整——在抽取前先对匹配滤波输出插值偏移量在±sps/4范围内扫描取眼图张开度最大的采样点。这个细调能让高信噪比下的误码率地板再降一个量级。6. 误码率曲线的工程判读与仿真加速技巧曲线跑出来后判读顺序比画图本身更重要。第一步看低信噪比起点EbN0在0~1dB时误码率是否在0.05到0.1量级如果偏差超过一个数量级先查EbN0换算公式。第二步看曲线斜率Turbo码下水曲线上段斜率较缓这是迭代译码尚未收敛的区域属于正常现象如果斜率陡峭下降发生在3dB附近说明交织器或分量码设计没问题。第三步看地板高信噪比下误码率是否抬头或走平抬头多为统计样本不足走平则是差分检测噪声乘积项或群延迟残留所致。第四步看Turbo增益把含Turbo与不含Turbo两条曲线放到同一张图上增益应当在4~6dB之间1/3码率、1024帧长偏离这个范围先查打孔和解交织的索引。仿真加速上我有三个固定习惯。第一每个SNR点固定随机种子这样改动一次参数后曲线不会因为换了噪声而抖动定位性能变化时噪声的影响被隔离。第二把无编码曲线和含Turbo曲线分开跑无编码曲线用“至少50个错误”停止准则跑得快含Turbo曲线用“至少100个错误”只在瀑布区误码率10^-3到10^-5之间加密SNR点两头稀疏。第三调试阶段先用N256短帧快速验证整条链路确认无误后再上N4096长帧跑正式曲线。短帧和长帧的绝对误码率不同但链路逻辑一致短帧能暴露90%的代码问题。代码层面还有一个能加速20%的改法差分解调和Turbo译码的输入可以从硬判决比特换成软LLR。做法是把差分解调输出的dy实部虚部直接映射成LLR——对pi/4-QPSK实部虚部的符号决定比特的硬判决幅度决定可靠度幅度越接近0这个比特越不可靠。用这个软LLR替代0/1硬比特送进turbo_decodeTurbo增益能多挤出0.2~0.3dB。代价是译码器的分支度量计算要改成和差分解调噪声特性匹配不能再沿用BPSK下的4*EsN0系数。最后说一个踩出来的经验MATLAB仿真链路做到后面最耗时间的往往不是误码率本身而是“确认这条曲线确实是正确的”。我的习惯是所有结果必须能回答三个问题再画图无编码pi/4-QPSK曲线在10^-4处是不是比相干QPSK理论值差2.5dB内加了Turbo后增益是否在预期范围同一SNR点用不同种子跑两遍误码率波动是否在±30%以内。这三个问题答不上来时曲线画得再漂亮也不能用来出链路预算。希望这个排查习惯帮你在做自己的pi/4-QPSK与Turbo链路仿真时少走几趟弯路。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。