
毕业设计或者课程设计里做到“Turbo码 调制方式”这类题目的人很多但真正把Turbo码和GMSK放在一条链路上跑通、再给出可复现Matlab代码的资料确实不算多。BPSK和Turbo码的组合门槛低、结果直观GMSK就麻烦不少——它本质上是带记忆的连续相位调制匹配解调要在相位树里做最大似然序列估计复杂度直接上了一个台阶。这篇文章就围绕一个很经典的做法展开发射端用Turbo码做信道编码调制端分别在BPSK和GMSK两条链路上发送接收端对GMSK用二比特差分解调提取软信息再交给log-MAP迭代译码器。整个方案用Matlab实现既能快速复现误码率曲线又能比较两种调制方式在编码增益上的差异。我最近把这条链路完整拉了一遍从相位成形到差分解调、再到Turbo译码的软信息对接踩了不少坑。下面按工程实现的顺序把每一步的设计思路、Matlab实现细节和实测中要注意的点都写出来。1. 链路怎么搭把Turbo码与两种调制方式揉进同一条仿真管线先看整体结构。既然要对比turboBPSK和turboGMSK就不应该各自写一套互不相关的代码。正确做法是搭一条统一管线Turbo编码器输出编码比特经过相同的随机交织和码率匹配后进入调制模块调制模块做成可切换的BPSK直接符号映射GMSK走相位成形接收端根据调制方式选择对应的解调器输出软比特LLR送到同一个Turbo迭代译码器。这个设计的好处很明显——编码增益的差异完全由调制和解调方式决定排除了其他变量。链路各模块的职责划分见下表。模块实现要点输出Turbo编码器两个RSC分量码 随机交织器可配置码率1/2或1/3编码比特流信道交织/随机化打散突发错误与Turbo内交织区分交织后比特流BPSK调制0/1映射为±1归一化符号能量基带符号序列GMSK/MSK调制高斯滤波 相位积分恒定包络复数基带波形AWGN信道按Eb/N0折算噪声方差接收波形二比特差分解调延迟2T共轭相乘计算软量每符号软比特Turbo迭代译码Max-Log-MAP迭代8次信息比特硬判决仿真时我建议先把BPSK链路跑通把Turbo译码器验证无误后再切换到GMSK链路。这样排错范围清晰GMSK链路出问题问题几乎一定出在调制或差分解调侧而不是Turbo译码器本身。一个容易被忽略的细节是编码后比特与调制符号的映射关系。Turbo码内部交织器的索引、以及交织后比特进入调制器的顺序都会影响差分解调性能。GMSK本身具有相位记忆相邻比特的相位增量互相影响如果交织器设计不合理会把这种记忆性打散导致差分解调的软信息质量下降。实测中普通随机交织基本够用交织深度取信息块长度量级即可。2. MSK与GMSK的相位成形逻辑从相位树到高斯脉冲限带MSK和GMSK经常放在一起讲因为GMSK就是MSK的“限带版本”。MSK的基本思想很简单载波相位在每个比特持续时间内线性增加或减少π/2所以调制指数h0.5相位路径是一棵连续的分支树——每个比特都让相位沿顺时针或逆时针方向转折90度。这种相位连续特性使MSK的频谱旁瓣比BPSK低很多但主瓣宽度仍然偏大频谱效率不够理想。GMSK在MSK的基础上增加了一个前置高斯低通滤波器对输入的矩形脉冲先做平滑再用平滑后的波形控制相位变化速率。这样相位路径不再是一条条直线段首尾相接而是被修圆了高频分量被明显抑制带外辐射更小。通常用BT乘积描述这个高斯滤波器的带宽BT0.3是工程上最常见的取值GSM系统就是用它。BT∞时高斯滤波器退化为全通GMSK直接变成MSK所以MSK可以看作GMSK的一个特例。Matlab里生成GMSK基带波形核心就三步% 参数设置 h 0.5; % 调制指数 BT 0.3; % 高斯滤波器带宽-时间乘积 Nsamp 8; % 每符号采样点数 Rb 1; % 符号速率归一化 % 1. 信息比特映射为±1 a 2 * bits - 1; % bits为0/1序列 % 2. 高斯脉冲成形 % 对矩形NRZ波形做高斯滤波等效于把冲激响应用高斯脉冲近似 [phase_inc, q] gmsk_phase_pulse(a, Nsamp, BT, h); % 3. 相位积分得到复数基带信号 phi cumsum(phase_inc) * pi * h; s exp(1j * phi);这里的高斯脉冲q(t)可以查标准定义它是高斯函数对时间的积分决定了单个比特相位贡献的时域窗口。BT越小q(t)拖得越长理想情况下相位脉冲会跨越多个符号周期这就是MSK/GMSK“带记忆”的来源。从工程角度理解GMSK的相位成形可以看成发射端对原始比特流做了一次非线性变换。比特不再是直接反映在幅度或相位跳变上而是反映在跨符号的相位增量上。这个特点决定了接收端不能用BPSK那种逐符号匹配判别的思路必须考虑相位积累过程。频谱效率方面BPSK理想频谱无限宽实际通过升余弦滤波器限带GMSK靠相位平滑本身就限带。实测中BT0.3的GMSK在归一化频率1.5附近频谱衰减能达到-60dB以下占用带宽比BPSK小一倍左右。这是GMSK在工程上最大的价值——在带宽受限信道里能塞进更多用户或更高数据率。3. 二比特差分解调不看绝对相位只看相位增量GMSK接收端的经典做法是最大似然序列估计可以用维特比算法在相位状态格上做。但序列检测复杂度高工程上更常见的简化方案是差分检测。一比特差分检测简单、复杂度低但信噪比损失较大二比特差分检测在复杂度和性能之间取了一个很好的平衡点而且对载波初始相位不敏感非常适合突发通信和简化接收机。二比特差分解调的原理要从相位增量说起。以MSK为例若信息比特a(k)∈{±1}则第k个符号的相位增量近似为a(k)·π/2跨两个符号周期的累计相位差为[a(k-1)a(k)]·π/2。当相邻比特相同时这个相位差收敛到±π相邻比特不同时相位差趋近于0。也就是说二比特差分检测真正检到的是相邻两个比特的乘积a(k-1)·a(k)而不是单个比特本身。如果发射端预先做了差分编码b(k)a(k)·b(k-1)接收端就能从二比特差分结果中直接恢复b(k)对应的信息序列。实际操作中直接计算接收信号的延迟共轭乘积更加简单% rx为接收基带波形Nsamp为每符号采样数 z rx(2*Nsamp1 : end) .* conj(rx(1 : end-2*Nsamp)); % 或者逐符号采样后计算 % 取z的虚部或实部作为判决量具体取哪个取决于映射约定 soft imag(z); % 或real(z)极性需与差分编码映射对应为什么不取一比特差分因为GMSK的相位脉冲跨符号延伸一比特差分区间内相位增量受相邻码间干扰影响很大判决裕量不足取两比特间隔后发生在中间的那个比特的影响被对称抵消判决统计量的稳定性明显改善。BT越小这个优势越明显。当然二比特差分也有代价等效噪声功率翻倍信噪比损失大约比一比特差分少一些但相比理想相干检测通常有3dB左右的代价。得到soft量之后不能直接硬判决Turbo译码需要的是对数似然比LLR。工程上最简单的做法是直接按噪声方差归一化% 差分噪声方差近似为原信道噪声方差的两倍 sigma2_diff 2 * sigma2_n; LLR soft / sigma2_diff;这个近似虽然粗糙但对Turbo迭代译码完全够用——log-MAP译码器对LLR的绝对尺度并不敏感只要极性正确、相对幅度合理迭代依然能收敛到接近理想的性能。如果你希望在实验室误差范围内精确一点可以先把difference软量的经验方差统计出来再按比例归一化。4. Turbo码编译码实现迭代译码里的外信息闭环Turbo码本质上是两个递归系统卷积码RSC通过交织器并行级联接收端用两个软输入软输出译码器迭代交换“外信息”逼近最大似然译码性能。这里每个术语都有具体含义RSC分量码必须带反馈结构只有递归结构才能在低信噪比下形成有效的“香农逼近”效果。我用的生成多项式是[7 5]八进制对应反馈多项式101、前向多项式111。交织器把同一段信息比特打乱顺序后送给第二个编码器让两个分量译码器看到的错误图案尽量不相关。交织深度直接影响迭代增益。迭代译码分量译码器1解出信息比特的软信息减去它自己的先验输入和外加信道信息得到“外信息”交给译码器2译码器2同样计算外信息反馈给译码器1。如此反复两个译码器互相纠偏误码率逐步下降。Max-Log-MAP是我在Matlab里最常用的译码算法。它的核心是各路度量比较不是完整BCJR的对数折算。为了保持迭代中的数值稳定性需要处理全部路径度量的归一化防止溢出。关键是外信息提取这一步。分量译码器输出的是后验LLR外信息定义为L_ext L_posterior - L_a - L_c;其中L_a是来自另一个译码器的先验信息L_c是信道对系统比特提供的软信息。BPSK链路里L_c通常就是2y/σ²GMSK差分链路里则取第3节算出的soft归一化量。每次迭代填充L_a后译码器更新L_posterior再剪出新的L_ext给另一半。我第一次实现时栽在了一个问题上增益收敛不了误码率曲线平到像是没有编码。后来单独检查每个模块的软信息输出发现分量译码器1和2之间外信息的符号约定不统一。L_a加错了符号两个译码器实际上在“反着推”迭代当然越推越差。所以在调试阶段建议做一个无信道噪声的“完美接收”验证把解调软信息直接替成理想映射值如果Turbo译码器不能收敛到零误码说明外信息符号或交织器索引有误。迭代次数方面实测Max-Log-MAP在4到6次迭代后性能曲线就基本重合8次是性价比很高的选择。继续增加到十几轮收益微乎其微但运行时间线性上升交织规模大时尤其明显。仿真里可以写个循环绘制不同迭代次数下的BER曲线直观展示迭代收敛过程。5. 仿真链路搭建与关键结果误码性能究竟差在哪现在把各模块串起来给出完整的仿真参数。我用的配置如下参数取值信息比特长度1024Turbo码率1/3交织器随机交织固定随机种子分量编码器多项式[7 5]八进制RSC译码算法Max-Log-MAP迭代8次调制方式BPSK / GMSKBT0.3 / MSK差分检测二比特差分GMSK/MSK过采样倍数8符号/采样信道AWGNEb/N0范围-0.5 ~ 4 dB链路主循环流程如下生成随机信息比特送入Turbo编码器编码输出按码率打孔后调制叠加噪声解调LLR归一化后送入Turbo译码器统计误码率。蒙特卡洛仿真中每个信噪比点至少要跑到出现50个以上错误比特曲线才平滑否则高信噪比区域波动很大看不出趋势。跑出来的典型结果趋势如下AWGN信道1024信息比特方案达到BER1e-3所需的Eb/N0无编码GMSK二比特差分约10dBTurboMSK二比特差分约6.5dBTurboGMSK二比特差分约7dBTurboBPSK相干解调约5.5dB这个表不是精确标定不同交织器长度和迭代次数会有差别但相对趋势是稳定的Turbo码给差分检测链路带来了约3dB以上的编码增益代价是要用迭代译码换BPSK链路因为相干解调软信息质量好增益最高GMSK由于频谱效率优势和包络恒定特性在带宽受限场景下更有吸引力。如果拿MSK和GMSK对比MSK差分检测的软信息更干净性能略好GMSK带宽效率更优因此按频谱效率归一化后GMSK的净优势还是明显的。仿真过程中最容易搞错的Eb/N0标定我单独强调一下。GMSK是恒包络信号功率归一化后每符号能量Es、每比特能量Eb和码率R的折算关系是Eb/N0 Es/N0 - 10log10(R)同时要把差分检测带来的噪声放大也算进去。最稳妥的验证方法在BPSK链路上做一次无编码误码率测试确认仿真曲线与理论曲线重合再用同样的噪声口径切换到GMSK链路上。如果BPSK链路标定都偏了GMSK差分链路的绝对信噪比就完全不可信。6. 实测踩坑记录软信息极性、相位展开、信噪比标定这一段是实际操作中真正容易卡住的地方我把踩过的坑按优先级列出来。**软信息极性。**这是最隐蔽也最致命的问题。差分解调输出的软量极性如果和Turbo译码器的信息比特约定相反高信噪比下依然可能接近50%误码。排查手段很直接先给发射端一个已知序列手动过一遍差分解调观察软量符号与比特映射是否一致。不要只在译码端找问题问题往往出在调制端映射约定和解调端判决方向两边的符号配合上。**相位展开跳变。**计算相位差之前如果直接用angle()取瞬时相位会在±π边界产生跳变导致差分软量出现毛刺。正确做法是对瞬时相位序列先做unwrap处理再逐点求差。示例代码phi unwrap(angle(rx)); delta_phi phi(2*taps1 : end) - phi(1 : end-2*taps); soft sin(delta_phi); % 或cos按调制约定unwrap的引入可能会让初学的人一头雾水但只要画一下相位曲线就会看到未展开的相位在边界处会有2π的跳变这个跳变经过差分运算后会直接变成一个虚假的强“旋转”完全掩盖真实的相位增量。**差分噪声方差。**用2倍原噪声方差做归一化是工程近似但如果信噪比走高后BER曲线出现异常上翘不要急着怀疑Turbo译码器先用差分解调的原始BER测试确认差分链路本身正确。差分检测的噪声样本实际上不是严格白噪声相邻时刻存在相关性所以在精确仿真里可以统计软量方差后一次性归一。**交替验证Turbo码本身。**GMSK链路跑不通时回到BPSK链路用同一套Turbo编译码器测试是最快的排错手段。反过来BPSK链路能跑到接近理论极限也说明你手上的Turbo译码器实现是过关的后面GMSK链路的性能差异都归因于调制解调方式而不是编码器本身。**迭代收敛与误差平台。**Max-Log-MAP在低信噪比时迭代增益明显但高信噪比下误码率曲线可能出现误差平台这时候增加迭代次数没有帮助问题更可能在交织器长度或分量码的选择。适当增大交织长度、或改用完整log-MAP可以推低误差平台。GMSK与Turbo码的组合最终要比的不只是编码增益而是“带宽效率×功率效率”的综合收益。BPSKTurbo很容易拿到好看的误码率曲线但频谱代价高GMSKTurbo让发射机可以用非线性功放、频谱占用更省同时靠Turbo的迭代增益补偿差分检测的损失——这在工程上的价值比单纯追求曲线更低误码率更实在。如果你只是做课设验证建议先跑通TurboBPSK再用相同的译码器切换到GMSK差分链路这种逐层替换的方式能在最短时间内帮你理清调制、编码、解调三者各自的贡献也最容易写出让人信服的实验报告。