基于MATLAB的AM调制在AWGN与瑞利信道下的性能仿真分析

发布时间:2026/9/18 21:15:42
基于MATLAB的AM调制在AWGN与瑞利信道下的性能仿真分析 简介一份面向通信工程、电子信息类学生的课程设计报告聚焦AM振幅调制系统在两种典型信道下的性能对比与MATLAB仿真。报告以沈阳理工大学课程设计为背景详细阐述了AM调制解调的基本原理涵盖普通调幅、DSB、SSB等调制方式以及包络检波和同步检波的适用场景。在高斯白噪声信道与瑞利衰落信道的建模过程中给出了信噪比、频谱特性、解调恢复等仿真分析步骤并得出相同信噪比下AM在高斯信道性能更优的结论。资源为单个docx文档约1.02MB包含课程设计目的、要求、相关知识、仿真过程及结果分析等完整模块便于读者直接参考或修改复用。目前已有185人学习适合需要完成相似课程设计或希望加深对调制解调与信道影响理解的读者。1. 通信系统课程设计里AM性能分析翻车点不在代码通信系统课程设计里AM性能分析是最高频题目之一。很多人把精力耗在MATLAB语句上真写完才发现AWGN和瑞利衰落两条曲线差异很大却说不清差异来自信道模型还是仿真bug。常见误区是把输入信噪比与输出信噪比混在一个口径里或者把瑞利衰落系数直接乘上去却不做功率归一化。这篇文章按课程设计最常要求的“两种信道下AM解调性能对比”来展开把参数设置、仿真代码、结果判定和报告画图一次讲透——新手能照着跑熟手可以直接拿走参数表和排错清单。2. AM信号模型与两种信道差异先落在数学上2.1 双边带AM与包络检波课程设计为什么选这个组合AM的时域表达式很简洁s(t) Ac * (1 m(t)) * cos(2*pi*fc*t)其中m(t)是归一化消息峰值绝对值不大于1Ac是载波幅度。课程设计里最常用的消息是单音m(t) mu * cos(2*pi*fm*t)mu就是调制指数。这个模型选双边带AM而不是DSB-SC核心原因是解调端可以用包络检波——接收机不需要恢复相干载波这正好暴露AM的代价大部分发射功率浪费在载波分量上。包络检波在MATLAB里写成abs(hilbert(r))就能拿到解析包络省去锁相环设计的复杂度。这也是课程设计选它入门的理由用最简单的信源和最简单的接收机专门观察信道对性能的影响。需要注意mu 1时包络会过零检波输出在低谷处失真仿真曲线上表现为整体掉头这不是信道问题而是选参问题。2.2 AWGN与瑞利平坦衰落的复基带写法两种信道的差异从接收信号表达式就能看出来。AWGN信道是r(t) s(t) n(t)乘性因子恒为1瑞利平坦衰落信道是r(t) h(t) * s(t) n(t)h(t)的幅度服从瑞利分布、相位服从均匀分布。这里的“平坦”意味着信号带宽远小于信道相干带宽衰落对信号内所有频率分量施加同样的增益所以仿真时可以简化为一个乘性系数不需要构造多径抽头延迟线。对比维度AWGN信道瑞利平坦衰落信道信道作用仅叠加高斯白噪声先乘复增益再叠加高斯噪声乘性因子恒为1幅度服从瑞利分布仿真写法r s nr abs(h) * s n性能曲线形态输出信噪比近似随输入线性增长深衰落点拉低均值高信噪比区出现平台参数风险噪声功率算错衰落系数未归一化导致输入信噪比失去参照课程设计把这两种信道放在一起对比本质是看同一个调制方式在“只加噪声”和“先乘性衰减再加噪声”时的性能差异。瑞利信道下瞬时信噪比是随机变量所以最终曲线统计的是平均行为不是某一次传输的结果。2.3 输入SNR、输出SNR与解调增益的换算口径性能分析绕不开三个量输入信噪比SNR_in、输出信噪比SNR_out、解调增益G SNR_out / SNR_in。课程设计里最容易翻车的是把仿真用的snr_dB直接当成输入SNR却忽略了噪声是在整个采样带宽内叠加的。单音AM的总功率是P_total Ac^2/2 Ac^2 * mu^2 / 4其中第一项是载波功率第二项是上下边带携带的信息功率。调制效率eta mu^2 / (2 mu^2)在mu 1时也只有1/3意味着三分之二的发射功率在接收端被当作直流成分滤掉了。2.3.1 AM信号生成的MATLAB函数function [s, t, carrier] am_modulate(m, Ac, fc, fs) % 生成双边带AM信号 s(t) Ac * (1 m(t)) .* cos(2*pi*fc*t) % 输入说明 % m : 归一化消息序列必须满足 max(abs(m)) 1 % Ac : 载波幅度单位与消息一致建议取 1 % fc : 载波频率单位 Hz需小于 fs/2 % fs : 采样率单位 Hz建议取 fc 的 10 倍以上 % 输出说明 % s : AM调制信号长度为 length(m) % t : 与 s 对应的时间轴 % carrier: 纯载波序列用于相干解调对照实验 N length(m); t (0:N-1) / fs; carrier cos(2 * pi * fc * t); s Ac * (1 m) .* carrier; end这段代码的关键点在于m必须事先归一化。如果消息里有直流偏置调制指数就会偏离设计值后续计算调制效率会出错如果消息峰值超过1过调制失真会被误判成信道衰落。fc取fs/20到fs/10之间比较稳太低会和消息频谱混叠太高对包络检波的采样要求更苛刻。3. MATLAB蒙特卡洛仿真参数、代码与信噪比口径3.1 先把仿真参数表定死再写循环蒙特卡洛仿真的收敛性取决于参数配置。以下参数表是课程设计场景下经过验证的一组取值直接照抄可以跑通改的时候要遵循“载波远高于消息频率、采样率远高于载波”的原则。参数名符号建议取值选择依据消息频率fm1 kHz便于观察频谱边带避免与载波混叠采样率fs200 kHz载波的10倍包络检波无压力载波频率fc20 kHz满足带通采样留足频谱间隔调制指数mu0.3 与 0.8 两组对比线性区与深度调制每帧点数N40962的幂次便于后续FFT分析蒙特卡洛帧数K800低于300时输出SNR曲线抖动明显一个常见错误是帧数K取得很大但每帧点数N很小这样每次衰落信道取值都只是“瞬时体验”统计意义上反而不如多帧取平均稳定。我一般固定N为4096K从200开始递增观察输出SNR曲线是否平滑不平滑再加K。3.2 三路解调共用一个主循环的实现clear; clc; % ---------- 参数配置 ---------- fs 200e3; % 采样率 200kHz fc 20e3; % 载波频率 20kHz fm 1e3; % 消息频率 1kHz mu 0.8; % 调制指数 Ac 1; % 载波幅度 N 4096; % 每帧采样点数 K 800; % 蒙特卡洛帧数 snr_dB 0:2:24; % 输入信噪比扫描范围单位dB % 生成单音AM信号 t (0:N-1) / fs; m mu * cos(2 * pi * fm * t); s_total Ac * (1 m) .* cos(2 * pi * fc * t); % 预分配输出信噪比存储 snr_out.raw zeros(length(snr_dB), 1); snr_out.coherent zeros(length(snr_dB), 1); snr_out.rayleigh zeros(length(snr_dB), 1); % 单音信号功率与消息功率 pow_signal mean(s_total.^2); pow_msg mean(m.^2); for k 1:length(snr_dB) % 根据输入SNR反算噪声功率保持信号功率恒定 noise_pow pow_signal / db2pow(snr_dB(k)); acc_env 0; acc_coh 0; acc_ray 0; for frame 1:K % 每个帧重新生成噪声保证统计独立 n sqrt(noise_pow) * randn(N, 1); % ---- AWGN信道 包络检波 ---- r_awgn s_total n; env abs(hilbert(r_awgn)); m_hat_env env - mean(env); % ---- AWGN信道 相干解调 ---- mix 2 * r_awgn .* cos(2 * pi * fc * t); [b, a] butter(6, 2 * fc / fs, low); m_hat_coh filtfilt(b, a, mix); m_hat_coh m_hat_coh - mean(m_hat_coh); % ---- 瑞利平坦慢衰落 包络检波 ---- h_frame (randn 1j * randn) / sqrt(2); r_ray abs(h_frame) * s_total n; env_ray abs(hilbert(r_ray)); m_hat_ray env_ray - mean(env_ray); % 用误差功率比计算输出信噪比线性域 acc_env acc_env pow_msg / mean((m_hat_env - m).^2); acc_coh acc_coh pow_msg / mean((m_hat_coh - m).^2); acc_ray acc_ray pow_msg / mean((m_hat_ray - m).^2); end % 帧平均后转dB snr_out.raw(k) 10 * log10(acc_env / K); snr_out.coherent(k) 10 * log10(acc_coh / K); snr_out.rayleigh(k) 10 * log10(acc_ray / K); end这段代码刻意把输出信噪比的计算放在线性功率域最后才转dB避免先求平均再求对数时负值被吞掉。参数说明如下noise_pow用输入信噪比反推是保证扫描曲线横坐标一致的关键hilbert返回解析信号取模即包络是包络检波最简洁的MATLAB写法filtfilt是零相位滤波不会像filter那样引入群延迟偏移否则消息序列和解调结果会错位一截直接破坏输出信噪比计算。3.3 瑞利衰落系数为什么必须做均方根归一化瑞利信道代码里h_frame (randn 1j * randn) / sqrt(2)构造的是均方值为1的复高斯随机变量。取模后abs(h_frame)的均值约为0.886、均方值为1。这个归一化决定了衰落前后信号平均功率不变叠加的噪声才能按同一个输入SNR口径去比较。如果直接写h_frame randn 1j * randn平均接收功率会翻倍AWGN和瑞利两条曲线的输入信噪比实际上不等价对比结论就是错的。注意做平坦慢衰落时一帧数据只取一个h_frame做快衰落时要每个采样点重新生成衰落系数。课程设计通常选慢衰落模型这样能清晰观察深衰落对整帧的影响。3.4 仿真发散查什么四个高频翻车点曲线发散或抖动不是MATLAB算错了多半是以下四个原因。第一帧数K低于300统计量方差太大曲线呈现毛刺第二噪声功率算错常见于把snr_dB直接代入采样值漏掉了pow_signal / db2pow(snr_dB(k))这一步第三滤波器用成了filter而不是filtfilt相位延迟导致输出信噪比偏低尤其在低信噪比时表现得像发散第四调制指数超过1包络检波在谷值处削波输出SNR曲线提前掉头。排查顺序我一般先跑mu 0.3的低调制指数档确认曲线形态正常再跑高调制指数档这样能把过调制因素和信道因素区分开。4. 两种信道下AM性能曲线对比与门限区定位4.1 输出信噪比曲线绘制与semilogy刻度陷阱输出信噪比在低输入SNR时可能掉到0dB以下直接画线性坐标会失真。课程设计报告里更常见的做法是把输出信噪比转回线性域用semilogy画这样瑞利信道下的“平尾”特征非常明显。figure(Color, w); semilogy(snr_dB, max(db2pow(snr_out.raw), 1e-6), o-, LineWidth, 1.5); hold on; semilogy(snr_dB, max(db2pow(snr_out.coherent), 1e-6), s-); semilogy(snr_dB, max(db2pow(snr_out.rayleigh), 1e-6), ^-); grid on; legend(AWGN包络检波, AWGN相干解调, 瑞利包络检波, Location, northwest); xlabel(输入信噪比 SNR_{in} (dB)); ylabel(输出信噪比 SNR_{out} (线性));max(db2pow(...), 1e-6)是防止输出信噪比为零或负值时对数量级溢出。这样得到的曲线可以直接看出AWGN相干解调斜率最高AWGN包络检波略低瑞利信道在输入SNR超过10dB后增长明显放缓——这不是bug而是瞬时信噪比的指数分布决定了总有样本落在深衰落区。4.2 调制指数mu对AM性能的双向影响调制指数增大时信息边带功率占比提高输出信噪比整体上移但过大的mu逼近过调制边界包络检波在低输入SNR时更容易失真。单音调制下的调制效率eta mu^2 / (2 mu^2)可以直接算出来对比调制指数 mu调制效率 eta输出SNR相对变化风险0.34.3%曲线整体偏低几乎无失真0.615.3%比mu0.3提升约5dB正常使用区间1.033.3%理论最高带外分量小接近过调制边界课程设计里如果只给一组曲线选mu 0.8比较折中效率够高又有安全余量。若要做对比实验把mu 0.3和mu 0.8两组画在同一张图上观众能直接看到“效率提升”的效果。4.3 瑞利信道的深衰落概率与“平尾”解释瑞利信道下瞬时接收功率服从指数分布均值归一化为1后瞬时功率低于阈值th的概率是P 1 - exp(-th)。即使平均输入SNR很高仍有一定比例的数据帧处于深度衰落这些帧的输出误差极大把平均值拉高。这种现象在高信噪比区表现为曲线斜率下降好像有“地板”。用一段小代码可以验证这个概率th 0.1; % 瞬时功率阈值 p_theory 1 - exp(-th); % 用100万个样本验证指数分布深衰落概率 h_test abs(randn(1e6, 1) 1j * randn(1e6, 1)) / sqrt(2); p_sim mean(h_test.^2 th);p_theory约为0.095p_sim会收敛到相近值。仿真里出现这个平尾是数学必然不是随机种子没设好。报告里如果只写“瑞利信道性能变差”会被追问差在哪把这段深衰落概率写上去结论立刻有支撑。4.4 用diff自动标注门限区AM包络检波在低输入SNR区域存在门限效应曲线偏离线性增长、掉头加剧。手动找拐点不可复现我习惯用diff对输出SNR序列做一阶差分找到变化率第一次低于1dB的位置再画一条参考竖线% 找输入SNR序列中输出SNR变化开始放缓的点 idx_th find(diff(snr_out.raw) 1, 1, first); hold on; line([snr_dB(idx_th) snr_dB(idx_th)], ylim, LineStyle, --, Color, k); text(snr_dB(idx_th), 1e-3, 门限区起点, Rotation, 90);diff在这里是后项减前项结果小于1意味着信号输出信噪比在一个2dB步进内只涨了不到1dB。标注出这个点报告里的结论就能落在一个可复现的指标上而不是靠眼睛估。5. AM仿真结果可信度三个能直接抄走的验证手段5.1 线性功率域计算只在出入口做dB换算整个仿真过程里噪声功率、信号功率、误差功率都保持线性域计算db2pow和pow2db只出现在输入输出两端。这样做的好处是避免“先取对数再求平均”和“先求平均再取对数”的统计偏差。如果发现曲线形态对某个随机种子依赖很强优先检查是否在循环内部出现过10*log10若有就改成线性累积。5.2 固定随机种子跑三组帧数曲线重合才算收敛rng(42); % 固定随机种子确保结果可复现 K_list [200, 800, 2000]; for Ki 1:length(K_list) % 把主循环封装成函数 run_am_sim(K_list(Ki))返回snr_out结构体 s_tmp run_am_sim(K_list(Ki)); semilogy(snr_dB, max(db2pow(s_tmp.raw), 1e-6)); hold on; end三组曲线基本重合说明统计量收敛如果K从800加到2000曲线还在明显移动就是某个环节功率不守恒。最常见的是消息功率用了m.^2的均值而实际误差计算时混入了直流分量导致输出信噪比虚高。5.3 把结果缓存为mat画图与仿真解耦课程设计报告反复修改时重跑800帧仿真很浪费时间。把仿真结果和全部参数存成.mat文件之后画图直接读取既保留实验记录也让画图脚本和仿真脚本分离方便局部调整图样式。save(am_performance_summary.mat, snr_dB, snr_out, mu, fs, fc, K, rng_state); result load(am_performance_summary.mat); figure; semilogy(result.snr_dB, db2pow(result.snr_out.raw), o-);把rng_state也存下来评审问起“为什么曲线这么平滑”时可以直接说明随机种子和帧数整个仿真链条完全可追溯。报告里放这个mat文件、画图脚本和主仿真脚本在同一目录重跑和重画都不需要改任何路径。本文还有配套的精品资源点击获取