MATLAB实现OFDM信道编码:卷积码、Turbo与LDPC完整链路
简介面向通信工程学生与研究人员的OFDM完整MATLAB仿真资源聚焦信道估计、调制与信道编码三大核心模块覆盖正交频分复用系统的关键知识点帮助理解OFDM从发射到接收的完整链路以及不同传输策略对系统性能的影响。压缩包共21个文件以m脚本为主、mat数据文件为辅整体约10KB涵盖OFDM主程序、调制解调、信道建模仿真、比特加载算法、SVD分解信道处理及不同阶数的编码矩阵等子模块结构紧凑便于按模块逐文件阅读与调试。目前已有292人浏览学习。借助该仿真平台读者可自行运行和修改代码观察误码率、符号率变化深入对比不同信道估计、调制阶数与编码策略的差异适用于课程设计、毕业设计和OFDM相关算法预研也可为无线通信系统优化提供参考。1. OFDM 信道编码决定链路误码率下限的环节如果一个 OFDM 仿真只把 IFFT、加 CP、FFT 跑通就结束那它离真实系统还差最重要的一块——信道编码。OFDM 将宽带信道拆成多个窄带子载波后每个子载波上的信道近似平坦但频率选择性衰落仍会让一部分子载波深度衰落甚至完全陷落这些子载波上的比特会成批出错。信道编码的作用就是把这些散落的错误通过编译码恢复回来是整个链路在低信噪比下保持可用、并最终决定系统性能下限的环节。这篇文章会把 MATLAB 里带信道编码的完整 OFDM 链路按选型、收发实现、参数调优和 Simulink 验证四个环节拆开讲适合正在搭物理层仿真、准备把误码率曲线做真实的研究生与通信工程师。2. OFDM 信道编码选型卷积码、Turbo 与 LDPC 在 MATLAB 里怎么落地2.1 为什么 OFDM 链路里必须放一个编码器OFDM 把频率选择性信道分解为若干平坦衰落的窄带子信道这个分解只是让均衡变得简单并没有消除衰落。深衰落子载波上的符号被噪声和衰落共同压制解调后对应比特的错误率远高于其他子载波。如果不做编码系统 BER 等于这些差子载波的错误率加权平均信噪比再高深衰落子载波上的数据也救不回来。信道编码加在比特进入星座映射之前译码放在星座解映射之后。编码引入的冗余让接收端能依靠数据之间的相关性恢复被深衰落破坏的比特。OFDM 通常还会在编码器和调制器之间插入交织器让连续比特分散到不同子载波和不同 OFDM 符号上把深衰落导致的突发错误打散成随机错误卷积码这类纠错码才能真正发挥作用。2.2 三种常用编码方案的选择依据实际工程里OFDM 系统最常用的前向纠错方案是卷积码、Turbo 码和 LDPC 码。卷积码结构简单、译码延迟低适合对功耗和时延敏感的场景Turbo 码和 LDPC 码逼近香农限但译码需要迭代复杂度高。802.11a/g/n、LTE、5G NR 的 OFDM 物理层分别在不同信道上用了这些方案说明不存在绝对优劣只看约束条件。编码方案码率示例译码方式典型编码增益MATLAB 工具箱入口卷积码1/2、2/3Viterbi 译码3 ~ 5 dBconvenc / vitdecTurbo 码1/3、1/2迭代 MAP 译码6 ~ 8 dBcomm.TurboEncoder / comm.TurboDecoderLDPC 码1/2 至 5/6置信传播迭代6 ~ 9 dBcomm.LDPCEncoder / comm.LDPCDecoder对教学验证和毕业设计场景卷积码加 Viterbi 译码是最稳妥的选择工具箱自带函数齐全、参数直观、排错容易。Turbo 和 LDPC 的译码器迭代次数、归一化因子等参数多中途排错更容易出问题。工程验证阶段再换 LDPC 逼近实际标准更合理。2.3 MATLAB 编码器构造与参数解读用一段代码把三种编码器的构造和调用放在一起方便对照参数差异。% 卷积码约束长度 7生成多项式 171 和 133八进制 trellis poly2trellis(7, [171 133]); data randi([0 1], 1000, 1); codedConv convenc(data, trellis); % codedConv 长度是 data 的 2 倍码率 1/2 % Turbo 码使用随机交织器长度必须与帧长一致 turboEnc comm.TurboEncoder(TrellisStructure, trellis, ... InterleaverIndices, randperm(1000)); codedTurbo turboEnc(data); % LDPC 码DVB-S.2 标准校验矩阵码率 3/5 ldpcEnc comm.LDPCEncoder(ParityCheckMatrix, dvbs2ldpc(3/5)); codedLdpc ldpcEnc(data);参数说明poly2trellis 的第一个参数 7 是约束长度第二个参数 [171 133] 是生成多项式的八进制表示对应标准 (2,1,7) 卷积码大量教材里的误码率曲线都基于它。comm.TurboEncoder 内部由两个递归系统卷积码编码器和一个交织器组成InterleaverIndices 必须与译码端完全一致。comm.LDPCEncoder 直接接收稀疏奇偶校验矩阵dvbs2ldpc 是通信工具箱里生成 DVB-S.2 标准矩阵的函数也可以换成其他标准矩阵。提示第一次仿真建议只用卷积码把整条链路调通再替换成 Turbo 或 LDPC。编码器替换只改一行但译码器的参数和输入数据类型检查会消耗大量时间。3. 用 MATLAB 搭一个带信道编码的完整 OFDM 收发链路3.1 系统参数与一帧数据的尺寸对齐搭链路之前先把一帧的长度算清楚。以 64 个子载波、QPSK 调制、1/2 码率卷积码为例每帧原始比特取 64 个编码后变成 128 个比特QPSK 每两个比特映射一个符号正好得到 64 个 QAM 符号对应 64 个子载波即一个 OFDM 符号。这个对齐关系能避免后面 reshape 时出现长度不匹配。N 64; % 子载波数 cpLen 16; % 循环前缀长度 modOrder 4; % QPSK bitsPerSym log2(modOrder); % 2 codeRate 1/2; % 卷积码码率 numFrames 500; % 仿真帧数 snrVec 0:2:14; % 信噪比扫描范围 % 卷积码结构 trellis poly2trellis(7, [171 133]); tracebackLen 32; % Viterbi 译码回溯深度 % 每帧原始比特数 bitsPerFrame N * bitsPerSym * codeRate; % 64参数说明这里把每个 OFDM 符号当作一帧处理bitsPerFrame 计算的是编码前的比特数。如果要模拟多径信道下的实际系统子载波中还需要留出导频位置此时数据子载波数要单独定义不能用 N 直接参与计算。3.2 发射端信源、编码、交织、星座映射与 IFFT发射端代码按信源、卷积编码、交织、QPSK 映射、IFFT 与加 CP 五步组织。交织这一步容易被省略但它对编码增益的影响非常直接。% 预分配 BER 存储 berAll zeros(length(snrVec), 1); for snrIdx 1:length(snrVec) berFrame zeros(numFrames, 1); for f 1:numFrames % 1) 随机信源 txBits randi([0 1], bitsPerFrame, 1); % 2) 卷积编码码率 1/2 codedBits convenc(txBits, trellis); % 3) 交织随机置换接收端必须使用同一组索引 intrlvrIdx randperm(length(codedBits)); intlBits codedBits(intrlvrIdx); % 4) QPSK 映射 txSym qammod(intlBits, modOrder, InputType, bit, ... UnitAveragePower, true); % 5) IFFT 调制加循环前缀 txFreq reshape(txSym, N, []); txTime ifft(txFreq, N); txCP [txTime(end-cpLen1:end, :); txTime]; txSignal txCP(:); % end for f —— 接收端代码见 3.3逻辑说明交织把编码后的相邻比特打散到不同子载波位置。省掉交织时深衰落子载波造成的连续比特错误会超过卷积码的纠错能力加上交织后错误在解交织时变成近似随机分布Viterbi 译码才能有效纠正。intrlvrIdx 必须保存下来接收端做逆置换时要用。qammod 的 InputType 设为 bit 可以直接把比特序列映射为符号。UnitAveragePower 参数保证星座点平均功率归一化为 1这样信噪比扫描时不同调制阶数之间的功率基准一致不会出现 QPSK 和 16QAM 在相同 SNR 设置下实际噪声功率不一致的问题。3.3 接收端同步假设、FFT 解调和译码接收端假设理想符号同步和时间同步。实际系统中 OFDM 同步需要做粗同步和细同步两级这里聚焦信道编码对 BER 的影响把同步部分理想化是仿真验证的常见做法。% 信道AWGN rxSignal awgn(txSignal, snrVec(snrIdx), measured); % 1) 去循环前缀和 FFT假设理想符号同步 rxMatrix reshape(rxSignal, N cpLen, []); rxMatrix rxMatrix(cpLen1:end, :); rxFreq fft(rxMatrix, N); rxSym rxFreq(:); % 2) QPSK 解映射 rxBits qamdemod(rxSym, modOrder, OutputType, bit, ... UnitAveragePower, true); % 3) 解交织利用发射端保存的索引恢复编码顺序 deintlBits zeros(size(rxBits)); deintlBits(intrlvrIdx) rxBits; % 4) Viterbi 译码 rxBitsDec vitdec(deintlBits, trellis, tracebackLen, ... trunc, hard); % 统计误码 errBits sum(rxBitsDec ~ txBits); berFrame(f) errBits / bitsPerFrame; end berAll(snrIdx) mean(berFrame); end逻辑说明awgn 函数第三个参数设为 measured表示按信号实际功率添加噪声这样信噪比定义与星座图上的实际电平对应。vitdec 的 opmode 选择 trunc 是截断模式每一帧独立完成译码不依赖前一帧的译码状态适合按帧组织的仿真。tracebackLen 取 32经验值是约束长度的 5 倍左右过小会损失部分编码增益过大会增加延迟和计算量。提示把多径信道加进来时需要在 FFT 之后补信道估计与均衡。最简单的方式是插入梳状导频在频域对导频位置做线性插值得到所有子载波的信道响应再做单抽头均衡。这一步与信道编码解耦编码和译码部分可以直接复用上面的代码。4. OFDM 信道编码的 3 个必调参数码率、交织深度与 CP 长度4.1 码率与调制阶数的搭配逻辑码率决定冗余量调制阶数决定频谱效率两者必须放一起考虑。保持带宽不变时提高调制阶数或提高码率都能提升数据速率但抗噪声能力随之下降。工程上按信道条件选择信道差就降低码率和调制阶数信道好就上 16QAM 甚至 64QAM 搭配高码率 LDPC。调制方式码率频谱效率bit/s/Hz编码方案典型场景QPSK1/21.0卷积码控制信道、低信噪比链路16QAM1/22.0卷积码 / Turbo中速数据16QAM3/43.0LDPCWiFi 数据信道64QAM3/44.5LDPC短距离高吞吐上表未计入导频和 CP 开销实际有效频谱效率会再低一些。在 MATLAB 里验证调制阶数的作用只需把 3.2 节的 modOrder 改掉。64QAM 时要注意 bitsPerFrame 必须能被 6 整除否则 qammod 会在输入尺寸检查时报错码率改成 2/3 时可以用 poly2trellis 配合删余实现或直接换用 comm.TurboEncoder 得到更灵活的码率配置。4.2 交织深度跨符号交织应对长时间深衰落3.2 节用的随机交织是帧内交织只在单个 OFDM 符号内部打散比特顺序。帧内交织能把同一符号内相邻子载波的错误分散开但面对持续多个符号的深衰落受影响的连续比特可能全部来自同一段编码序列单靠帧内交织无法把这些错误分散到不同的编码约束区间。这时需要在多个 OFDM 符号之间再做一次交织即提高交织深度。% 跨 8 个 OFDM 符号的块交织示意 % codedAll 尺寸为 128×8每列是一个符号的编码比特 codedAll zeros(128, 8); for k 1:8 codedAll(:, k) codedBits; % 示意连续缓存 8 帧 end permSymOrder randperm(8); interleaved codedAll(:, permSymOrder); txSymBlock qammod(interleaved(:), modOrder, InputType, bit, ... UnitAveragePower, true);逻辑说明这里只对符号列做置换把整个符号的数据搬到另一个符号位置属于粗粒度的跨符号交织。交织深度越大对抗长突发错误的能力越强代价是端到端时延线性增加。仿真时可以把 3.2 节的帧内交织替换成这里的跨符号交织观察 BER 曲线变化能直观感受交织深度的影响。4.3 CP 长度与子载波间隔的相互约束CP 长度由信道最大时延扩展决定。OFDM 要求 CP 长度大于最大时延扩展否则前一个符号的尾部会落入后一个符号的 FFT 窗口产生 ISI同时破坏子载波正交性带来 ICI。子载波间隔越大符号周期越短同样时长的 CP 占用的开销比例越高这是 OFDM 参数设计里一对需要权衡的约束。验证 CP 长度影响的做法是构造两径信道把第二条径的时延分别设在 CP 之内和 CP 之外在接收端做理想信道均衡后对比 BER。% 两径信道第二径时延 8 个采样点CP 长度 16 足够 pathGain 0.5; pathDelay 8; % 改成 20 时CP 不再够用 % 理论频响并做功率归一化 hFreq 1 pathGain * exp(-1j * 2 * pi * (0:N-1). * pathDelay / N); hFreq hFreq / (1 pathGain); rxEq rxFreq ./ hFreq; % 理想均衡 rxSym rxEq(:); % 之后照常进行 qamdemod、解交织和 vitdec参数说明hFreq 是两径信道的频域响应exp 项对应第二径时延带来的相位旋转。均衡只能纠正信道的乘性失真无法消除 CP 不足引入的 ICI。把 pathDelay 从 8 改成 20 重跑一次BER 曲线会比之前显著抬高而且无论怎么提高信噪比都不会回到同一水平——这是 CP 不够长的典型症状也是 OFDM 链路设计里最先需要确认的约束。5. 用 Simulink 的 OFDM 调制解调模块快速验证编码增益5.1 把卷积码和 OFDM 模块连成一条可调链路通信工具箱的 Simulink 库里有现成的 OFDM Modulator Baseband 和 OFDM Demodulator Baseband 模块不需要在模型里自己画 IFFT 和循环前缀。搭建带信道编码的验证模型只需五个模块组伯努利二进制信源、卷积编码器、块交织器、OFDM 调制器、AWGN 信道接收端对应解调器和 Viterbi 译码器。连接顺序与 MATLAB 脚本保持一致伯努利二进制信源输出原始比特送入 Convolutional Encoder 块其生成多项式参数与 poly2trellis 的 [171 133] 对应输出接 General Block Interleaver 块再接入 Rectangular QAM Modulator Baseband最后送进 OFDM Modulator Baseband。OFDM 调制模块的 Number of Subcarriers 设为 64Cyclic Prefix Length 设为 16与脚本里的 N 和 cpLen 保持一致。接收端 OFDM Demodulator 的输出经过 QAM 解调、解交织和 Viterbi Decoder接到 Error Rate Calculation 模块统计误码率。5.2 三个立刻能用的验证技巧第一个技巧是设置编码开关。在信号通路上放一个 Manual Switch一条通路接 Convolutional Encoder另一条直连用同一个 OFDM 调制器跑两次仿真对比 Error Rate Calculation 输出的 BER。两次仿真的差值就是编码增益的直观呈现演示时比单独贴一条 BER 曲线更有说服力。第二个技巧是用 Constellation Diagram 模块观察 OFDM 解调后的星座图。编码与否在星座图上看不出明显差别真正值得关注的是均衡前后星座点的收敛情况。如果星座点散成一圈先查 Cyclic Prefix Length 是否大于最大时延扩展而不是先怀疑编码器参数。第三个技巧是用 Spectrum Analyzer 查看 OFDM 发射信号的频谱形状。OFDM 信号的带外泄漏由子载波数量、循环前缀和加窗共同决定。将 Spectrum Analyzer 接在 OFDM Modulator 输出端如果谱形状与理论预期的 sinc 包络不一致优先检查 Sample Time 的设置是否匹配整个链路。提示Simulink 里统计 BER 时Error Rate Calculation 的 Receive delay 必须设置为 Viterbi Decoder 的 Traceback depth 与 OFDM 调制解调延迟的总和否则统计窗口对不准误码率计算结果会比实际偏大。先用纯 AWGN 链路把延迟凑准再打开多径信道。本文还有配套的精品资源点击获取