
简介这份MATLAB资源包聚焦数字通信中的调制解调核心环节面向通信工程专业学生、算法验证人员及系统设计者提供二进制相移键控、正交相移键控、十六阶正交幅度调制和六十四阶正交幅度调制四种典型数字调制方式的实现与仿真入口。压缩包内共三个文件包含两个脚本源文件与一个文本说明文档整体仅约四KB轻量便携可直接运行验证。两个脚本协同工作可实现从二进制数据流到复数基带信号、叠加高斯白噪声信道、再到解调判决的完整链路并支持误码率或符号错误率等指标统计方便对比不同调制方式在不同信噪比条件下的传输性能。该资源上线以来已有三百五十二人学习适合作为通信原理课程配套仿真工具也可作为调制解调算法的入门样例。通过阅读和调试代码学习者还能进一步理解相位键控与正交幅度调制的星座图映射、判决门限设计等细节为后续搭建完整通信系统模型打下基础。1. 看懂 modulation.m 和 demodulation.m等于看懂了四种调制解调之间的边界mod-demod.rar 里只有两个 MATLAB 文件却把 BPSK、QPSK、16QAM、64QAM 的调制解调链路完整串了起来符号映射、AWGN 加噪、判决解调、误码率统计。这套代码在通信仿真老资料里流传很广常见用途是课程作业、FPGA 浮点仿真的参照实现以及给 OFDM 或 AD9361 这类射频项目做基带符号级验证。它最值得看的地方不是哪个函数能跑出图而是四种调制方式共用了同一套 I/Q 符号接口改一个参数就能观察不同带宽效率和抗噪能力的取舍。适合两类读者一是刚接触调制解调、想弄明白星座图和判决边界的初学者二是做实际链路、需要快速评估 64QAM 信号在特定信噪比下表现的在职人员。2. 符号映射与能量归一化modulation.m 里从 BPSK 到 64QAM 的编码骨架2.1 四种调制的本质差异每符号比特数与星座点数量调制与解调在链路里的作用是把二进制比特流映射成复基带符号。BPSK 每符号携带 1 比特星座点 2 个只有相位 0 和 π 两种状态QPSK 每符号 2 比特星座点 4 个通过 I/Q 两路相位组合区分 00、01、11、1016QAM 每符号 4 比特星座点 16 个同时用幅度和相位承载信息64QAM 每符号 6 比特星座点 64 个I/Q 平面上的点更密集带宽效率最高但对噪声最敏感。调制方式每符号比特数 k星座点数 M频谱效率相对BPSK主要代价BPSK121x吞吐最低QPSK242x相位判决精度要求提高16QAM4164x幅度相位联合判决抗噪下降64QAM6646x判决区域小需要较好SNR在 demodulation.m 里你只会看到一串 switch 语句但真正决定性能的是星座点怎么排、判决边界画在哪。QPSK 可以看成两个正交 BPSK 的叠加I 路和 Q 路各自做二电平判决16QAM 是两个 4PAM 的叠加I/Q 分别是四电平判决64QAM 是两个 8PAM 的叠加。这个观察很重要解调端的复杂度基本由单路电平数决定而不是直接看总的星座点数量。2.2 格雷映射为什么能降低 64QAM 信号的误比特率星座图上相邻符号错判的概率最高如果相邻符号对应的比特组合只有一个比特不同一个符号错误就只产生一个比特错误这就是格雷映射。QPSK 的四个相位点按顺时针排列16QAM 的 16 个点在行列方向上相邻只差 1 个比特位。modulation.m 里常见的写法是直接调 MATLAB 内建函数而不是手工建表function sym modulation(bits, M, modType) % M 取值 2/4/16/64对应 BPSK/QPSK/16QAM/64QAM k log2(M); % 按每个符号的比特数切块每行是一个符号的比特组合 bitGroups reshape(bits, k, []).; % 把比特组按二进制权重转成 0 ~ M-1 的索引 idx bi2de(bitGroups, left-msb); if strcmp(modType, qam) % 平均功率归一化为 1这样不同阶数之间可直接比较 BER constellation qammod(0:M-1, M, gray, UnitAveragePower, true); else constellation pskmod(0:M-1, M, 0, gray); end sym constellation(idx 1).; end这里的逻辑是先把比特流按 log2(M) 分块再用 bi2de 把每块二进制数转成星座点索引最后按索引从星座图里取符号。left-msb表示块内左侧比特是高位这和星座图的行列编号约定保持一致gray开启格雷映射UnitAveragePower让星座点平均能量固定为 1这一步省掉后面 AWGN 仿真里一大半的功率换算问题。BPSK 可以直接复用 pskmod 的 M2 分支QPSK 就是 M4 的 PSK。2.3 归一化系数对判决边界的决定性影响为什么强调UnitAveragePower因为解调端的判决边界是基于归一化星座写的。16QAM 归一化后的星座点坐标是 ±1/√10、±3/√10判决边界在 0 和 ±2/√10 附近如果不归一化星座点坐标直接取 1、3、-1、-3判决边界变成 0 和 ±2。两种坐标系的错误率完全相同但混用就会出问题。常见做法是发送端不用内建函数手工写指数映射和幅度缩放这时更容易漏掉能量归一化导致调制输出的平均功率与理论值差一个常数倍。检查方法很简单对 modulation.m 输出取mean(abs(sym).^2)BPSK 和 QPSK 应该是 116QAM 和 64QAM 在UnitAveragePower下也应该是 1如果不是解调端的边界必须成比例放大否则高信噪比下会看到误码率平台。提示MATLAB 的 qammod 有两种归一化模式UnitAveragePower是工程仿真最常用的省略它时输出星座点最小距离为 2平均功率不为 1两种模式下的判决边界完全不同。3. AWGN 信道建模与信噪比换算modulation.m 和 demodulation.m 之间那层噪声3.1 Eb/N0、Es/N0 与符号能量三者的换算关系在通信仿真里横坐标一般用 Eb/N0 而不是直接用 SNR。Eb 是每比特能量N0 是噪声功率谱密度它排除带宽和符号速率的影响方便比较不同调制方式的性能。Es/N0 Eb/N0 10·log10(k)k 是每符号比特数。仿真生成符号后再加噪要先算 Es/N0再换算成噪声方差加进复信号。这里的 k 在 QPSK 是 2在 16QAM 是 4在 64QAM 是 6这也是四种调制方式曲线位置不同的根本原因。调制方式k要达到 BER1e-4 的典型 Eb/N0经验值BPSK1约 8.4 dBQPSK2约 8.4 dB16QAM4约 12.2 dB64QAM6约 16.5 dBBPSK 和 QPSK 的 Eb/N0 性能相同因为 QPSK 是两个并行 BPSK只是带宽效率翻倍16QAM 相比 QPSK 在相同误码率下要多付出约 4 dB 的功率代价64QAM 又要再贵 4 dB 左右。这个表格里的经验值可以用作 demodulation.m 调试的粗标尺如果仿真曲线偏离超过 0.5 dB先检查归一化和噪声方差。3.2 复高斯白噪声的生成方式与方差确认function y add_awgn(sym, EsN0dB, k) % sym 是归一化基带符号k log2(M) EsN0_lin 10^(EsN0dB/10); % 噪声单边功率谱密度 N0 N0 1 / EsN0_lin; % 复噪声的实部虚部方差都是 N0/2合成功率才是 N0 noise sqrt(N0/2) * (randn(size(sym)) 1j*randn(size(sym))); y sym noise; end这里最容易错的是噪声功率的分配。复基带信号由 I/Q 两路组成总噪声功率 N0 均分到实部和虚部所以每一路的标准差是 sqrt(N0/2)而不是 sqrt(N0)。同理如果先画了脉冲成型滤波器、对符号过采样还要再乘一个与过采样率相关的系数但在这份 modulation.m/demodulation.m 的符号级仿真里不需要。验证噪声功率对不对可以直接var(noise)结果应该等于 N0。3.3 为什么这份代码不包含信道编码却不影响比较调制方式mod-demod.rar 的定位是未编码 AWGN 链路没有 LDPC 或 Turbo 编码器。很多人在这个阶段会纠结没有编码算不算完整系统其实未编码 BER 曲线正是评估调制方式本身的基线。LDPC/BCH 等编译码介入后曲线会在某个 Eb/N0 附近出现瀑布式下降那个转折点称为编码门限但门限的相对顺序仍由调制方式决定。4. 解调判决边界与误码率统计demodulation.m 里 16QAM/64QAM 的矩形判决4.1 最大似然判决退化为欧氏距离最小化解调端面对的是加噪后的符号目标是从 M 个候选星座点里挑出最可能的发送点。AWGN 信道下噪声服从复高斯分布各星座点等概率发送时最大似然判决等价于找欧氏距离最近的星座点argmin |y - x_i|²。对 QPSK 这种纯相位调制判决区域是四个象限对 16QAM 和 64QAM判决区域是矩形格子的集合。4.2 手工判决与 qamdemod 的对照实现function bits_est demodulation(y, M, modType) % 先用内建函数做硬判决得到星座点索引 if strcmp(modType, qam) idx qamdemod(y, M, gray, UnitAveragePower, true); else idx pskdemod(y, M, 0, gray); end % 索引转回比特流与 modulation.m 的 bi2de 互逆 bits_est de2bi(idx, log2(M), left-msb).; bits_est bits_est(:).; end如果只看结果这两行就能完成解调。但在 FPGA 或 C 语言实现里没有现成的 qamdemod必须把判决逻辑展开成 I/Q 两路独立比较。16QAM 归一化星座的判决边界是 I 轴和 Q 轴上的 ±2/√10、064QAM 的边界是 0、±2/√10、±4/√10、±6/√10对应 8PAM 的七条边界。QPSK 更简单只看实部和虚部的符号位大于 0 判为 1小于 0 判为 0。手工判决的价值在于边界可以参数化后续加幅度缩放、I/Q 失配补偿时可以直接改边界向量。4.3 BER 仿真主循环与理论曲线对齐EbN0dB 0:2:20; for snrIdx 1:numel(EbN0dB) bits randi([0 1], 1e6, 1); % 100 万比特保证 BER 统计到 1e-4 sym modulation(bits, M, 16qam); y add_awgn(sym, EbN0dB(snrIdx) 10*log10(log2(M)), log2(M)); be demodulation(y, M, 16qam); berArray(snrIdx) mean(bits ~ be); end semilogy(EbN0dB, berArray, o-); hold on; % 16QAM 理论近似0.75*erfc(sqrt(0.4*EbN0_lin)) EbN0lin 10.^(EbN0dB/10); berTheory 0.75 * erfc(sqrt(0.4 * EbN0lin)); semilogy(EbN0dB, berTheory, -);主循环里的关键是EbN0dB 10*log10(k)的换算它在 add_awgn 内部再转回 Es/N0100 万比特保证在 1e-4 误码率附近仍有足够错误样本数。理论公式 0.75·erfc(√(0.4·Eb/N0)) 是 16QAM 在高斯信道下的经典近似QPSK 用 0.5·erfc(√(Eb/N0))64QAM 用 0.583·erfc(√(0.111·Eb/N0))。仿真点和理论线偏差小于 0.3 dB 就说明 modulation.m 和 demodulation.m 的行为正确。4.4 判决边界与归一化不匹配的典型故障现象解调端最常见的 bug 是发送端归一化改了、判决边界没跟着改。表现是低信噪比段曲线和理论基本重合高信噪比段掉不下去BER 停在某个平台。原因是符号幅度偏大或偏小后判决边界相对星座点发生了平移部分点被挤到错误格子里且这种错误不随噪声减小而消失。我在调试时一般先固定无噪声条件跑一次正确解调后误码率必须为 0再逐步加噪声这样能快速区分是边界问题还是噪声方差问题。5. 参数化改造把 BPSK、QPSK、16QAM、64QAM 跑成一个可调的仿真器5.1 同一份骨架循环四种调制方式modulation.m 和 demodulation.m 都带着 modType 参数最简单的改造就是在外层套一个循环把四种方式跑完直接画一张对比图。这样做的工程价值不只是好看而是让 64QAM 信号相比 QPSK 的功率代价在同一张图里直接读数。modList {bpsk, qpsk, 16qam, 64qam}; for mIdx 1:numel(modList) M 2^(mIdx); % 2, 4, 16, 64 berPerMod{mIdx} run_ber_sweep(M, modList{mIdx}); endrun_ber_sweep 就是把上一章的循环封装成函数内部不变。跑完后可以用legend标注四种调制方式横轴统一用 Eb/N0。4 条曲线的间隔大约就是每提升一阶调制付出的功率代价这也是选型时最直接的一张图。5.2 四个必须在改参数前确认的工程参数参数设置建议检查方法仿真比特数BER 目标 1e-4 时至少 1e6sum(bits~be)错误样本数大于 50随机数种子固定rng(42)重新运行曲线抖动小于 0.1 dB符号延时滤波器和信道可能引入群延时无噪下跑一次误码必须为 0归一化开关modulation 和 demodulation 共用同一套星座mean(abs(sym).^2)恒为 1工程人员拿到这类仿真代码第一步不是跑图而是先确认这四项。固定随机种子让调试可复现错误样本数不足会导致高分贝点曲线跳动剧烈无噪测试通过后再加噪声可以保证问题出在信噪比换算而不是解调逻辑。5.3 向 GMSK、OFDM 和 AD9361 方向扩展的落点mod-demod.rar 本身不做 GMSK但理解 GMSK 调制解调原理时核心仍然是相位路径约束和差分解调和这套 BPSK/QPSK 判决器可以共用一个复基带接口。Simulink 中 OFDM 调制解调的示例同样是每子载波选一种调制阶数再交给 IFFT所以这套 modulation.m 的符号映射部分可以直接拆出来做成 OFDM 的子载波调制器模块。AD9361 这类射频收发芯片在 BPSK 模式下DAC 前端要的是基准增益校准后的 I/Q 数据UnitAveragePower 归一化后的符号幅度正好对应芯片数字增益参数的换算基础把归一化系数换算成 API 里的增益缩放就可以对接。5.4 用一段断言把四种调制方式的正确性锁住assert(all(abs(mean(abs(sym).^2) - 1) 1e-10), average power must be 1); assert(sum(bits ~ be) 0, zero-noise demodulation must be error-free);这两行断言写进仿真主循环前会在每次改动参数后自动检查最容易被破坏的两个前提发送功率归一化和解调端正确性。之后再改符号数、换调制阶数、加脉冲成型都不用重新人工核对边界。跑仿真的人只需要盯住曲线是否符合理论公式眼前这份调制解调代码就可以当作基线继续迭代。本文还有配套的精品资源点击获取