news 2026/9/14 8:32:02

MATLAB实现OFDM信道编码:卷积码、Turbo与LDPC完整链路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 / vitdec
Turbo 码1/3、1/2迭代 MAP 译码6 ~ 8 dBcomm.TurboEncoder / comm.TurboDecoder
LDPC 码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-cpLen+1: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(cpLen+1: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 设为 64,Cyclic 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 链路把延迟凑准,再打开多径信道。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 8:29:16

WPS JSA实现Excel多Sheet数据合并与自动化处理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 8:28:15

AI短漫剧全链路云原生流水线实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华