资讯动态

4QAM/16QAM调制解调MATLAB仿真:星座图与误码率曲线对账

发布时间:2026/10/13 8:23:34 来源:尧图企业网站定制
简介4QAM与16QAM调制解调仿真电路是一份面向通信原理课程设计、数字通信实验与MATLAB仿真的源码资源覆盖两种调制方式的调制、解调、星座图观察和误码率曲线分析等完整环节适合课程设计、实验报告撰写与复习参考。压缩包共16个文件全部为.m源码文件整体约11KB包含仿真主程序、调制解调函数、AWGN加噪、升余弦滤波、误码率统计以及波形与星座图绘制等模块模块边界清楚便于逐段阅读、修改参数与二次开发。这份资源已有5232人学习。使用者可以获得完整的4QAM/16QAM仿真链路与配套绘图分析代码对照系统框图和公式描述逐段理解两种调制方式在加性高斯白噪声信道下的星座图分布与误码性能差异并可结合各点波形判断调制解调过程正误为课程实验报告中的结果因果分析提供直接参考。1. 4QAM/16QAM 调制解调仿真这两张图到底在验证什么很多人拿到 4QAM、16QAM 调制与解调的 MATLAB 仿真源码第一反应是跑出星座图和误码率曲线看到图就交差。但这两张图的真正价值不是交差而是帮你定判决边界、定发射功率、找出链路里多余的损耗。标题里的“仿真电路”在 MATLAB 语境下严格说是一条仿真链路比特流经过符号映射、成型滤波、AWGN 信道、匹配滤波、判决最后统计误码率。这篇文章就把 4QAM 和 16QAM 两种调制阶数的链路实现方式、参数选择、星座图读法和误码率对账方法一次讲透目标是让通信原理课程设计或数字调制笔试面试准备者拿到框架后能直接复现、能调参、能自检。2. 调制与解调原理从 4QAM 等价于 QPSK 到 16QAM 格雷映射QAM 仿真里最常翻车的其实不是 MATLAB 语法而是映射表写错、能量没归一化、判决星座和发射星座不是同一份这类概念问题。所以先把原理立住后面代码才有依据。2.1 比特到符号两种星座图的映射表与归一化规则4QAM 每个符号携带 2 bit映射到 4 个星座点。最常见的定义是 00 映射到 (-1,-1)/√201 映射到 (-1,1)/√211 映射到 (1,1)/√210 映射到 (1,-1)/√2。这组坐标本质上就是两路正交 BPSK 的叠加所以 4QAM 和 QPSK 在性能上完全等价。有些教材把星座点放在 0°、90°、180°、270° 四个相位上那只是一种整体旋转误码率曲线与 45° 起点的版本完全一致不用纠结。16QAM 每个符号携带 4 bit16 个星座点排成 4×4 网格坐标取 ±1、±3。把 4 bit 拆成 I 路 2 bit 和 Q 路 2 bit两路分别对应横纵坐标组合起来就是 16 个点。这里最关键的一步是能量归一化4QAM 四个点的平均符号能量是 216QAM 十六个点的平均符号能量是 10如果不除这两个系数后面用 Eb/N0 算噪声功率时就会系统性算错曲线整体平移。我一般会在进信道之前先打印一句 mean(abs(const).^2)确认它等于 1 再往下走。这个习惯能省掉后面一半的排查时间。星座点坐标用 ±1、±3 还是 ±1/√10、±3/√10 只是一个缩放问题理论 BER 不变但一定要保持发射端、接收端、理论公式三者用同一套能量基准。2.2 格雷映射为什么是 16QAM 的默认选择16QAM 有两种常见编码方式自然映射和格雷映射。自然映射下相邻星座点对应的比特组合可能差 2 到 3 个 bit格雷映射保证水平或垂直相邻的两个星座点只差 1 bit。判决器在噪声较大时最容易把符号判到欧氏距离最近的相邻点上也就是只错 1 bit 的方向所以格雷映射能让比特误码率降到最低。如果误用自然映射同样的信道条件下 BER 会明显变差而且曲线在高信噪比段出现一个奇怪的“平台”因为必然有一部分判决错误一次翻多个 bit。4QAM 没有这个选择问题它本身天然就是格雷映射。格雷映射的具体顺序常用 00、01、11、10 表示十进制 0、1、2、3 对应的坐标索引即 0→坐标索引 01→索引 12→索引 33→索引 2。I 路和 Q 路都按这个规律取坐标组合出来的 16 个点就满足“相邻只差 1 bit”。2.3 相干解调与最大似然判决用最小欧氏距离找最近星座点接收端在加性高斯白噪声下做的最优判决是最大似然判决它等价于最小欧氏距离判决把接收符号和所有理想星座点算距离取最近的一个作为估计值。这个思路也是贝叶斯最小错误概率准则在等先验概率、等代价、高斯噪声假设下的特例理解这一点后后面接软判决、LLR 计算时逻辑能顺下来。课程设计仿真里通常假设理想载波同步也就是接收端已知频率和相位匹配滤波后直接下采样即可。实际系统里还需要载波恢复和定时恢复那是另一个层面的问题。如果后续要接 LDPC 或 Turbo 译码硬判决就不够用了常见做法是保留接收符号到各星座点的距离信息换算成对数似然比再送给译码器。3. MATLAB 实现一条 4QAM/16QAM 链路的最小可复现代码这套链路的主体是 16QAM4QAM 只需要改两个参数和映射模板其余框架完全复用。代码只用了基础 MATLAB 和通信工具箱里的 rcosdesign没有依赖其他第三方脚本。3.1 参数表调制阶数、过采样率、滚降系数怎么定参数默认值说明M16调制阶数改成 4 就是 4QAMnSym2e4每帧符号数想观察 1e-4 以下误码要加到 1e5sps8每符号采样点数小于 4 时星座图拖尾明显rolloff0.35根升余弦滚降系数取值范围 0.2 到 0.5 均可span6成型滤波器截断的符号数EbNoDb0:2:14扫信噪比范围低信噪比端可以加密rng42固定种子让曲线可复现这里重点说三个参数。sps 决定波形的时间分辨率取值太小成型滤波后的波形不光滑星座图看起来有拖尾取值太大仿真时长成倍增加8 是一个平衡点。rolloff 是频谱效率和波形质量的折中滚降系数越小带宽越窄但滤波器脉冲的旁瓣越高对定时误差越敏感。span 是滤波器截断长度太小会破坏升余弦特性引入符号间干扰一般取 6 到 10。3.2 发射端映射、上采样与根升余弦成型滤波% 发射端比特流 - 符号映射 - 上采样 - 根升余弦成型滤波 M 16; % 调制阶数改成 4 即为 4QAM k log2(M); % 每符号比特数 nSym 2e4; % 一帧符号数 sps 8; % 每符号采样点数过采样率 rolloff 0.35; % 成型滤波器滚降系数 span 6; % 滤波器截断符号数 rng(42); % 固定随机种子保证曲线可复现 dataBits randi([0 1], k*nSym, 1); % 随机比特流 dataSym reshape(dataBits, k, []).; % 每行是一个符号的 4 bit % 格雷映射00-01-11-10 对应索引 0-1-3-2 grayMap [0 1 3 2]; % 16QAM 幅度模板未归一化坐标为 ±1、±3 symMap [-3 -1 1 3]; % I 路用每符号前 2 bitQ 路用后 2 bit iBin dataSym(:,1)*2 dataSym(:,2); % 普通二进制索引 0~3 qBin dataSym(:,3)*2 dataSym(:,4); iIdx grayMap(iBin1); % 格雷索引 0~3 qIdx grayMap(qBin1); % 平均符号能量归一化16QAM 的平均能量为 10除 sqrt(10) 后 Es1 normConst sqrt(10); sym (symMap(iIdx1) 1j*symMap(qIdx1)) / normConst; % 上采样后过根升余弦滤波器h 的默认增益使收发级联后符号幅度放大 sps 倍 h rcosdesign(rolloff, span, sps, sqrt); txUpsampled upsample(sym, sps); txSignal filter(h, 1, txUpsampled);这段代码把 16QAM 的映射做成查表形式好处是接收端可以按同一张表反查避免复数比较带来浮点误差。归一化用的是固定值 sqrt(10)而不是对每一帧数据现场算 mean(abs(sym).^2)这样每一帧的符号能量都是确定的 1理论曲线的横坐标才严格可对齐。如果改成 M4把 normConst 改成 sqrt(2)、symMap 改成 [-1 1]其余逻辑不变就是完整的 4QAM 链路。rcosdesign 返回的滤波器系数是根升余弦脉冲发射端和接收端各用一个级联后等效为一个升余弦滤波器采样点处无符号间干扰。我一般会检查一下 sum(h) 和 sps 的关系两个根升余弦级联的直流增益约等于 sps所以接收端下采样后要把幅度除以 sps 才能回到符号级这个细节放到 3.4 节一起说。3.3 AWGN 信道Eb/N0 到噪声方差的换算公式% 信道按 Eb/N0 换算噪声功率 EbNoDb 0:2:14; berSim zeros(size(EbNoDb)); for idx 1:numel(EbNoDb) % Es k * Eb所以 Es/N0(dB) Eb/N0(dB) 10*log10(k) EsNoDb EbNoDb(idx) 10*log10(k); Es 1; % 发射端已归一化Es 恒等于 1 noiseVar Es / (10^(EsNoDb/10)); % 复高斯噪声实部虚部各占一半功率 noise sqrt(noiseVar/2) * (randn(size(txSignal)) ... 1j*randn(size(txSignal))); rxSignal txSignal noise; % 接收端处理见 3.4 节 end这段的关键是 Eb/N0 和 Es/N0 的换算。16QAM 每符号 4 bit10log10(4)≈6dB4QAM 每符号 2 bit10log10(2)≈3dB。如果忘记加这个偏移直接把 Eb/N0 当 Es/N0 用16QAM 的曲线会整体右移 6dB4QAM 右移 3dB这个现象在调试时非常典型。复噪声的功率分配也是个高频错误点噪声的实部和虚部方差各为 noiseVar/2合起来才是 noiseVar。如果写成 randn 1j*randn 之后不除根号 2噪声功率翻倍曲线整体平移约 3dB而且形状不变极其隐蔽。3.4 接收端匹配滤波、群延迟补偿与硬判决% 匹配滤波与发射端相同的根升余弦使 SNR 最大化 rxFiltered filter(h, 1, rxSignal); % 群延迟补偿h 长度 49峰值在第 25 个点去掉前 24 点 groupDelay (numel(h)-1)/2; rxSync rxFiltered(groupDelay1:end); % 下采样到符号率并补偿两个根升余弦级联带来的 sps 倍增益 rxSym rxSync(1:sps:end) / sps; rxSym rxSym(1:nSym); % 截掉滤波器瞬态段 % 最大似然判决找最小欧氏距离的星座点 [~, hardIdx] min(abs(rxSym - const.).^2, [], 2); % 格雷逆映射把星座索引还原成 4 bit invGray zeros(1,4); for g 1:4 invGray(grayMap(g)1) g-1; end rxIBin invGray(floor((hardIdx-1)/4)1); rxQBin invGray(mod(hardIdx-1,4)1); rxBits [floor(rxIBin/2) mod(rxIBin,2) ... floor(rxQBin/2) mod(rxQBin,2)]; % 比特级误码率统计 errBits sum(sum(rxBits ~ dataSym)); berSim(idx) errBits / (k*nSym); end接收端的三个细节直接决定能不能跑出正确曲线。第一是群延迟补偿滤波器长度为 span*sps149信号经过 filter 后峰值位置偏移了 (49-1)/224 个采样点不补偿直接下采样采样点落在符号过渡区星座图会糊成一团。第二是除以 sps发射和接收两个根升余弦级联后理想无噪声时下采样点的幅度是原符号幅度的 sps 倍不除回来判决距离完全错位。第三是截掉滤波器瞬态upsample 后面补了零filter 输出尾部有衰减段必须截到 nSym 个符号再统计。判决这里没有直接比较符号值而是比较星座索引再用逆格雷表把索引还原成比特。这样和发射端 dataSym 对比时格雷映射和逆映射完全对称不会出现“曲线低端对得上、高端偏几个点”这种奇怪问题。3.5 跑通后立刻做的两件事画星座图、画 BER 曲线% 在指定 Eb/N0 下观察星座图例如 EbNoDb 8 scatter(real(rxSym), imag(rxSym), 6, filled); hold on; scatter(real(const), imag(const), 40, rx, LineWidth, 1.5); axis equal; grid on; xlabel(I 路); ylabel(Q 路); title(16QAM 接收星座图Eb/N08dB); % 仿真与理论 BER 对照 berTheory 3/4 * qfunc(sqrt(4*10.^(EbNoDb/10)/5)); % 16QAM 近似 figure; semilogy(EbNoDb, berSim, o-); hold on; semilogy(EbNoDb, berTheory, x-); grid on; xlabel(Eb/N0 (dB)); ylabel(BER); legend(仿真, 理论近似);星座图一定要画接收端经过完整链路的点才能看到噪声云的真实形状。理论曲线 16QAM 用格雷映射的近似公式4QAM 直接改一行 qfunc(sqrt(210.^(EbNoDb/10))) 即可。如果你的 MATLAB 没有 qfunc把 Q(x) 换成 0.5erfc(x/sqrt(2))结果完全一致。4. 观察与分析星座图的病相和误码率曲线的对账仿真跑通只是第一步读懂这两张图才是这套源码真正值钱的地方。正常链路下星座图是一团围绕理想点的圆形散点云误码率曲线和理论线基本贴着走。偏离这个形态时每张图都指向一个明确的链路缺陷。4.1 星座图怎么看散点云、旋转、拖尾分别说明什么16QAM 在 Eb/N08dB 时16 个点云的边界开始可以分辨到 12dB 时内外圈清晰分离。4QAM 在 8dB 时四团已经很干净。这是观察的基线低于这个清晰度链路一定有问题。云团被拉长成椭圆而不是圆形说明接收端采样时刻没有对准存在残余符号间干扰。整体旋转一个固定角度说明链路里有固定相位偏移常见于没有补偿滤波器相位或者载波相位假设不一致。云团弥散成一个环或者一大片通常不是信道噪声太大而是噪声功率给错或者判决星座和发射星座不是同一套归一化基准。还有一种情况是星座点数量不对16QAM 只看到 4 团或 8 团要么是 I/Q 映射时两个 bit 组用了同一个索引要么是格雷映射表写错导致多组坐标重叠。这类问题在星座图上一眼就能看出来所以我会先看星座图再跑全段 BER 曲线而不是反过来。4.2 误码率曲线的三个验收标准斜率、绝对位置、调制间距第一个标准是曲线斜率。仿真曲线和理论曲线在低信噪比端应该几乎重合在中段必须有同样的陡峭下降。如果斜率比理论缓链路里有符号间干扰优先查群延迟和滤波器截断长度。第二个标准是绝对位置。在 BER1e-3 附近仿真和理论的偏差应该在 0.5dB 以内。偏差 1dB 以上基本是噪声换算或能量归一化问题。第三个标准是 4QAM 和 16QAM 的间距。相同误码率目标下16QAM 比 4QAM 大约差 4dB这是 4QAM 与 16QAM 在功率效率上的固有差距。如果两条曲线纠缠在一起横坐标大概率用错了。Eb/N0 (dB)4QAM 理论 BER16QAM 理论 BER格雷近似62.4e-32.8e-281.9e-49.2e-3103.9e-61.8e-3129.0e-91.4e-4这几个量级可以直接拿来做对账。如果 8dB 时 4QAM 仿真算出来是 1e-2基本可以断定噪声放大了如果 16QAM 在 10dB 时低于 1e-3可能是把归一化系数乘重了。4.3 对账流程从低信噪比端往高信噪比端逐段检查先看低信噪比端也就是 0 到 4dB。这个区间误码率在 1e-1 量级统计得很稳仿真和理论如果在这里就不重合说明映射或噪声功率有硬错误不要往下看。再看中段 8 到 10dB。这一段的曲线斜率最能暴露符号间干扰斜率不够陡就是成型滤波或者下采样时刻有问题。最后看高信噪比端。12dB 以上误码数变少曲线抖动是正常的但如果出现明显的平底平台说明有一个固定错误概率存在比如映射表中某个星座点的判决域不对。两条曲线同图对比时确认它们在中段的间距。如果 4QAM 和 16QAM 的曲线间距不是 4dB 左右其中一个调制阶数的映射大概率写错了。5. QAM 仿真避坑手记5 个让我翻过车的细节问题下面是 QAM 仿真里最容易翻车的 5 个问题每一条我都踩过写出来帮你省下半天调试时间。5.1 曲线高信噪比端出现平台下不去现象BER 降到 1e-4 附近就不再下降加大仿真时长也只是让曲线更密集底部依然有个平台。原因最常见是误码数太少高信噪比段一帧 2e4 个符号只产生几个误码统计误差极大另一种可能是映射表存在固定错误某个判决域内的符号被判到相距多个 bit 的星座点。解决先把 nSym 加到 1e5 以上再看平台是否消失。如果平台还在逐点检查发射端相邻星座点的 bit 差确认所有水平垂直相邻点都只差 1 bit。只要有一个相邻点差了 2 bit就会形成一个固定错误底。5.2 仿真曲线整体右移 2dB 以上先查噪声换算现象仿真曲线和理论曲线形状一模一样整体平行右移 2 到 6dB两个调制阶数同时偏移。原因把 Eb/N0 当 Es/N0 用了或者没有做能量归一化再或者判决时用的星座点和发射端不是同一份。16QAM 右移约 6dB4QAM 右移约 3dB看到这个数量的平移优先查这两处。解决改成 EsNoDb EbNoDb 10*log10(k)发射星座除以 sqrt(10) 和 sqrt(2) 后再进链路接收端判决用的 const 也必须用归一化后的那组点。建议在噪声那一行前打印 mean(abs(sym).^2)确认是 1。5.3 16QAM 星座图只有 4 团或 8 团现象星座图点数明显不够 16 团有的点云位置上重叠合并。原因I 路和 Q 路映射时用了同一个索引而没有分成低 2 bit 和高 2 bit或者格雷表让多组比特组合指向了同一个坐标本质是映射表写错。解决在发射端加一行 disp([iIdx(1:8), qIdx(1:8)])手算前 8 个符号的 I/Q 索引和比特组合对不对得上。16QAM 的 16 个组合必须覆盖全部 2 bit×2 bit 的笛卡尔积任一坐标重复都是映射表的锅与信道无关。5.4 星座图是一团烟雾成型滤波群延迟没补偿现象星座点不是清晰的云团而是连成线的拖尾像一坨烟雾而且信噪比提高后改善有限。原因接收端 filter 之后没有去掉群延迟直接下采样采样点落在符号的过渡区域造成规律性偏差。这个问题看起来像玄学实测链路检查后会确认就是延迟补偿这一行少了。解决groupDelay (numel(h)-1)/2rxSync rxFiltered(groupDelay1:end)然后再做 1:sps:end 下采样。同时记得把下采样结果除以 sps 补偿滤波器增益两个问题经常同时出现。5.5 两条曲线画在同一张图上却纠缠不清现象4QAM 和 16QAM 的 BER 曲线画在一张图里几乎重合甚至交叉完全看不出性能差异。原因横坐标用了 SNR 而不是 Eb/N0并且两个调制阶数的平均符号能量没有归一化到同一个基准。这样不同调制阶数的每比特能量不同曲线自然错位。解决统一改用 Eb/N0 作为横坐标发射星座按平均能量归一化让 Es 等于 1。修正后 4QAM 与 16QAM 在中段应保持约 4dB 的间距这是最直观的验收信号。6. 进阶技巧用 BER 曲线反推链路等效噪声再决定要不要继续调6.1 损耗估算一个公式定位 0.2dB 还是 1dB调试时最需要的是一个快速判定当前链路是健康还是有隐藏 bug。我一般用“等效损耗”来量化找到仿真 BER 恰好等于 1e-3 时的 Eb/N0减去理论曲线的 Eb/N0。以 4QAM 为例目标 BER1e-3 的理论 Eb/N0 约为 6.8dB16QAM 约为 10.5dB。如果损耗小于 0.2dB链路质量很好剩下的是统计波动0.5 到 1dB 之间去查滤波器截断长度、群延迟补偿和定时偏移超过 1dB基本不是参数问题而是映射表或噪声换算有硬 bug。这个公式比肉眼比曲线靠谱得多因为曲线在 1e-2 到 1e-4 之间肉眼很难分辨 0.3dB 的差异。6.2 让蒙特卡洛平均更可信的三个习惯第一个习惯每个 Eb/N0 点重新随机比如 rng(idx)不要用同一个固定种子贯穿全部信噪比点否则各点噪声序列相同曲线过度平滑掩盖统计波动。第二个习惯统计误码时累加多个独立帧的误码数再除以总比特数而不是对每帧 BER 做算术平均。第三个习惯某点误码数为 0 时不要硬画直接标“无误码”同时加 nSym让曲线往下延伸。我自己的调试习惯是每改一个参数都先看 8dB 附近的星座图再跑全段曲线因为这一点对链路状态最敏感一眼能看出是噪声问题还是符号间干扰问题。这套框架改 M、sps 和 rolloff 就能快速扩展到 32QAM、64QAM 甚至更高阶希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑