(15,11)汉明码误码率仿真:BSC与AWGN链路MATLAB实现 简介本资源面向通信原理、信道编码课程的学习者与仿真实践者围绕1511汉明码在BSC与AWGN两类信道下的误码率性能展开提供可直接运行的MATLAB完整代码。包内共12个文件以6个m脚本为核心配套2张jpg结果图、2份docx说明文档、1个txt关键词文件及1个asv备份文件压缩包约219KB体积轻便、结构清晰。仿真分两条链路一是发送数据经15-11-4汉明编码后通过BSC信道再经汉明译码并统计BER二是编码后经BSSK调制、AWGN信道、BPSK解调与汉明译码最终计算误码率。运行脚本即可直接出图便于对照两种信道下的性能差异。目前已有581人学习下载适合需要快速复现汉明码编译码流程、理解信道噪声对误码率影响、完成课程设计或实验报告的读者参考借鉴。1. 拆开这个1511汉明码误码率仿真包它到底能帮你验证什么如果你正在做信道编码的课程设计或者要在一篇小论文里放一张「汉明码在 BSC 与 AWGN 下的 BER 对比曲线」那这个压缩包大概率能省掉你两三天时间。它做的事情很具体把1511汉明码的编码、译码分别接到 BSC 信道和「BPSK 调制 AWGN 信道」两条链路上跑完蒙特卡洛仿真直接出误码率曲线图。也就是说你不需要从零推导生成矩阵、校验矩阵也不用纠结译码时伴随式怎么查表代码里已经把这套流程串好了MATLAB 里点运行就能看到图。它适合三类人一是刚接触信道编码、想先看到「编码到底降了多少误码」的本科生二是要快速复现一组基线数据、再拿去做对比实验的研究生三是需要一份能改参数、能换码长、能加信道的可复用脚本的工程师。包里除了代码还有 BSC 和 AWGN 两张结果图以及一份说明文档等于把「跑出来长什么样」也提前给你看了。下面我按「先讲清原理和选型再落到怎么跑、怎么改、哪里会翻车」的顺序拆一遍。2. 先把1511汉明码的编码译码链路讲透为什么是它而不是随便一个分组码2.1 1511汉明码的参数含义与纠错边界1511汉明码属于线性分组码记作nk1511其中 n15 是码字总长度k11 是信息位长度校验位 mn-k4。它的最小汉明距离 d_min3这个数字直接决定了它的能力能纠正 1 位错误或者检测 2 位错误但两者不能同时保证。换句话说一个 15 位的码字里只要错不超过 1 位译码后能还原错 2 位译码器可能纠错失败甚至越纠越错。为什么课程设计和入门仿真偏爱它因为 4 个校验位刚好能构造出 2^4-115 个非零伴随式正好一一对应 15 个可能的单比特错误位置这是汉明码「完美码」的性质。参数不大矩阵规模小MATLAB 里手算生成矩阵、校验矩阵都不费劲跑蒙特卡洛也快。常见做法是先用它把「编码增益」这个概念跑出来再换更复杂的 BCH 或卷积码。2.2 生成矩阵与校验矩阵的构造逻辑标准1511汉明码通常写成系统码形式码字前 11 位是信息位后 4 位是校验位。生成矩阵 G 是 11×15校验矩阵 H 是 4×15满足 G·H^T0。构造时先定 H 的列4 位二进制表示 1 到 15 的所有非零向量按某种顺序排列再通过 H[P^T | I] 的形式反推出 G[I | P]。代码里一般不会让你手填矩阵而是用循环或预置常量生成。你要关注的是H 的列顺序决定了伴随式到错误位置的映射表如果列顺序和译码查表不一致纠错就会错位。这是后面避坑章节要重点说的一个点。2.3 伴随式译码从接收码字到纠错输出译码的核心是算伴随式 S r·H^Tr 是接收到的 15 位码字。如果 S 为零向量说明没有检测到错误直接取前 11 位作为信息输出如果 S 非零就去查「伴随式-错误图样」表找到对应的错误位置把该位翻转再取信息位。这个表在1511码里就是 15 个非零伴随式对应 15 个单比特错误位置。仿真里通常用查表法而不是解方程因为 15 个条目很小查表更快也更直观。你要检查代码里这张表是不是和 H 的列一一对应很多跑出来 BER 异常高的脚本问题就出在这张表对不上。2.4 两条链路的差异BSC 直接翻位AWGN 要先过 BPSKBSC 信道是离散无记忆信道模型很简单每个比特以概率 p 独立翻转0 变 1、1 变 0。仿真时就是生成一个 0/1 随机序列和发送码字逐位异或。它的好处是直接对应「误码率 p」这个参数曲线横轴就是 p物理意义清晰。AWGN 链路多了一步编码后的比特要先做 BPSK 调制把 0 映射成 -1、1 映射成 1然后叠加高斯白噪声接收端再解调回 0/1最后送进汉明译码。这里的关键参数是信噪比 Eb/N0它和 BSC 的翻转概率 p 之间可以通过理论公式换算但仿真里一般分别扫各自的横轴。两条链路的 BER 曲线形状不同BSC 下汉明码的 BER 随 p 下降得比较平缓AWGN 下则会看到明显的「瀑布」下降因为软判决信息被硬判决丢掉了但编码增益依然存在。3. 在 MATLAB 里跑通两条仿真链路从参数设置到出图3.1 运行前的环境确认与文件结构拿到压缩包后先解压确认目录里有代码文件夹、两张结果图BSC信道.jpg、AWGN.jpg和说明文档。MATLAB 版本没有硬性要求R2016a 之后的版本基本都能跑因为用到的都是基础函数randi、xor、reshape、awgn需要 Communications Toolbox或者自己写高斯噪声。如果你没有 Communications Toolbox代码里如果调用了 awgn 函数会报错这时可以自己用 randn 生成噪声替代后面会给替代写法。运行前建议先清空工作区和命令窗口避免旧变量干扰clear; clc; close all;这一步不是形式主义仿真脚本里经常用同名变量不清空容易读到上一轮残留的 BER 数组导致曲线对不上。3.2 BSC 链路编码、翻位、译码、统计 BERBSC 链路的流程是生成随机信息比特 → 汉明编码 → 按概率 p 翻转 → 汉明译码 → 统计误码。核心代码结构大致如下% 参数设置 k 11; n 15; % (15,11) 汉明码 N 1e5; % 仿真信息比特数 p_list 0:0.01:0.1; % BSC 翻转概率扫描 BER zeros(size(p_list)); for idx 1:length(p_list) p p_list(idx); msg randi([0 1], 1, N); % 生成信息比特 code hamming_encoder(msg); % 汉明编码输出 15 位码字序列 rx bsc_channel(code, p); % BSC 翻位 dec hamming_decoder(rx); % 汉明译码 BER(idx) sum(dec ~ msg) / N; % 统计误码率 end semilogy(p_list, BER, o-); xlabel(BSC 翻转概率 p); ylabel(BER); grid on;逻辑说明hamming_encoder 和 hamming_decoder 需要你自己实现或从包里调用编码时把每 11 位信息映射成 15 位码字译码时按伴随式查表纠错。bsc_channel 就是生成同长度的随机数小于 p 的位置翻转。参数 N 控制仿真精度N 越大曲线越平滑但耗时线性增长p_list 是横轴扫描点一般从 0 扫到 0.1 足够看出趋势因为 p 再大汉明码基本失效。3.3 AWGN 链路BPSK 调制、噪声叠加与硬判决解调AWGN 链路多了调制解调代码结构如下% 参数设置 EbN0_dB 0:1:10; % 信噪比扫描范围 BER_awgn zeros(size(EbN0_dB)); for idx 1:length(EbN0_dB) EbN0 10^(EbN0_dB(idx)/10); msg randi([0 1], 1, N); code hamming_encoder(msg); tx 2*code - 1; % BPSK 映射0--1, 1-1 % 噪声标准差考虑码率 k/n sigma sqrt(1/(2*EbN0*(k/n))); noise sigma * randn(1, length(tx)); rx_sym tx noise; % AWGN 叠加 rx_bit rx_sym 0; % 硬判决解调 dec hamming_decoder(double(rx_bit)); BER_awgn(idx) sum(dec ~ msg) / N; end semilogy(EbN0_dB, BER_awgn, s-); xlabel(Eb/N0 (dB)); ylabel(BER); grid on;逻辑说明BPSK 映射后每个符号能量为 1噪声方差要根据 Eb/N0 和码率换算这里 sigma 的公式里乘了 (k/n) 是因为 Eb 是信息比特能量而每个码字符号承载的是编码后的比特。硬判决用 rx_sym 0 把符号判回 0/1再送汉明译码。如果你没有 awgn 函数用 randn 乘 sigma 手动叠加即可效果一样。3.4 参数怎么改码长、信噪比范围与仿真点数想换码长比如改成74汉明码需要同步改三处k 和 n 的值、生成矩阵和校验矩阵的构造、伴随式查表。代码里如果矩阵是写死的就得重新生成。想扫更大信噪比范围把 EbN0_dB 改成 0:0.5:12曲线会更细但高信噪比下 BER 可能低到 1e-5 以下N1e5 就不够用了需要加到 1e6 甚至 1e7 才能看到有效点。这是蒙特卡洛仿真的固有代价越往低 BER 走需要的样本越多。BSC 那边同理p 小于 0.001 以后N1e5 可能一个错误都统计不到BER 直接是 0曲线断掉。常见做法是在低 p 区域单独加大 N或者用理论值补点。4. 避坑与排查跑不出图、BER 异常、曲线对不上时先查这几条4.1 现象BER 曲线几乎不下降和理论差距很大原因最常见的是伴随式查表和校验矩阵 H 的列顺序不一致。编码用的 H 和译码查表用的 H 如果列排列不同纠错就会翻错位导致译码后错误率反而升高。另一个可能是 BPSK 映射写反了0 映射成 1、1 映射成 -1解调判决阈值没跟着改。解决打印出 H 矩阵确认每一列对应的十进制值再对照译码查表里的错误位置。BPSK 映射统一用 2*code-1解调用 rx_sym0两边保持一致。4.2 现象AWGN 链路报错「Undefined function awgn」原因MATLAB 没装 Communications Toolboxawgn 函数不可用。解决不用 awgn手动写噪声叠加。把rx_sym awgn(tx, EbN0_dB(idx), measured)换成sigma sqrt(1/(2*EbN0*(k/n))); rx_sym tx sigma*randn(size(tx));。注意 sigma 的换算要和 Eb/N0 定义一致否则横轴对不上。4.3 现象低信噪比或低 p 区域 BER 为 0曲线断掉原因仿真点数 N 不够错误事件没被采样到。BER 是错误数除以总比特数如果 N1e5 而真实 BER 是 1e-6期望错误数只有 0.1 个大概率统计到 0。解决在低 BER 区域把 N 提高到 1e6 或 1e7或者对每个信噪比点动态增加仿真次数直到错误数达到某个阈值比如 100 个错误。后者更高效但代码要多写一层循环。4.4 现象BSC 和 AWGN 两条曲线画在同一张图上时横轴无法对齐原因BSC 横轴是翻转概率 pAWGN 横轴是 Eb/N0dB两者物理量不同直接画在一起没有可比性。解决要么分开两张图要么把 p 换算成等效的 Eb/N0 再画。换算关系是 p Q(sqrt(2Eb/N0(k/n)))其中 Q 是高斯尾概率函数。换算后两条曲线可以放在同一坐标系下对比但要注意这是理论换算仿真里直接用各自的横轴更直观。4.5 现象译码后信息位顺序错乱BER 始终在 0.5 左右原因编码时信息位和校验位的排列顺序与译码时取前 11 位的假设不一致。系统码要求信息位在前但如果生成矩阵构造时把校验位放在了前面译码取前 11 位就全错了。解决确认生成矩阵是 [I | P] 形式码字前 11 位是信息位。如果不是要么调整矩阵要么在译码后按正确位置提取信息位。5. 进阶用法把两条链路封装成函数批量扫参数并验证编码增益跑通单次仿真之后更有价值的做法是把 BSC 和 AWGN 两条链路各封装成一个函数输入参数N、p 或 EbN0、码长输出 BER然后在外层批量扫描。这样你可以一次性对比不同码长、不同译码方式硬判决 vs 软判决的曲线。我一般会写一个run_sim.m主脚本里面用循环调两个函数最后把结果存成 mat 文件避免每次重新跑。验证编码增益是否合理有个简单办法把未编码的 BPSK 在 AWGN 下的理论 BER 曲线画在同一张图上对比汉明码曲线。在 BER1e-3 附近1511汉明码的编码增益大约在 1 到 2 dB 之间如果你跑出来增益超过 3 dB 或者为负基本可以判定译码或噪声换算有问题。这个量级判断能帮你快速定位玄学 bug。还有一个实用技巧在 AWGN 链路里把硬判决改成软判决译码也就是不急着把符号判成 0/1而是把符号值直接送进译码器做最小欧氏距离译码。对于1511汉明码软判决能多拿大约 1 dB 增益。代码改动不大但需要你把伴随式查表换成计算 15 个合法码字与接收符号序列的欧氏距离取最近的。这个改动值得试一次能直观感受到「硬判决丢了多少信息」。从那以后我每次跑信道编码仿真都强制先跑一遍未编码基线确认噪声换算和判决逻辑没问题再上编码链路。这个习惯帮我省掉了无数次「曲线看起来对但数值全错」的返工。希望帮到你。本文还有配套的精品资源点击获取