MATLAB/Simulink通信系统仿真:BPSK与QPSK误码率对比及避坑指南

发布时间:2026/10/23 19:00:18
MATLAB/Simulink通信系统仿真:BPSK与QPSK误码率对比及避坑指南 简介这份课程设计资源面向通信工程、电子信息类专业学生及需要完成MATLAB/Simulink仿真实训的读者围绕AWGN信道下BPSK与QPSK两种数字调制方式展开建模与性能比较。内容涵盖两种调制解调原理推导、需求分析与设计思路、Simulink仿真模型搭建、不同信噪比下误码率曲线记录与对比分析并附有总结、课程感言及问题解决方案可帮助读者理解相干解调、相位模糊等关键概念掌握从建模到结果分析的完整流程。资源包为1个docx文档约551KB结构按引言、正文、总结、课程感言组织目录清晰便于按章节查阅与引用。目前已有4922人学习下载适合作为课程设计参考、仿真入门练手或调制方式对比的案例素材。1. 从一次“跑了一夜还没出图”的课设说起这套 BPSK/QPSK 仿真到底能帮你省多少事如果你做过通信原理课设大概率经历过这种场面Simulink 模型搭好了点下运行进度条像冻住一样一晚上过去误码率曲线还是空的。我当年第一次做 AWGN 信道下 BPSK 与 QPSK 调制比较就栽在仿真时间设成 100000 秒上后来改成 100 秒曲线又抖得没法看。这套基于 MATLAB/Simulink 的通信系统建模与仿真课程设计核心就是解决两件事一是把 BPSK 和 QPSK 在加性高斯白噪声信道下的误码率、频带利用率、复杂度讲清楚二是给出一套能直接跑通、能出对比曲线的模型和脚本。它适合正在做通信课设的学生、需要快速验证调制方案差异的初级工程师以及想从理论公式落到 Simulink 模块级实现的人。你拿到的不只是一份报告而是一个可复现的仿真框架——信源、调制、AWGN、解调、误码率计算每个环节的参数都能改改完立刻能看到曲线变化。2. BPSK 与 QPSK 的调制解调原理从相位映射到相干解调的数学底子2.1 BPSK 的相位映射与“倒相”问题BPSK 的本质是把二进制比特映射到载波的两个相位上通常用 0 和 π 表示“1”和“0”。时域表达式里(a_n) 取 1 或 -1分别对应两个相位。这个映射关系决定了 BPSK 每个符号只携带 1 比特信息符号能量全部用来对抗噪声所以它在低信噪比下比 QPSK 更稳。但 BPSK 有一个经典坑相干解调时本地载波恢复可能存在 180° 相位模糊。也就是说恢复出来的载波可能和发送载波同相也可能反相。一旦反相解调出来的比特会全部翻转“1”变“0”“0”变“1”这就是“倒相”现象。实际系统中常用差分编码来规避但在课设仿真里如果 AWGN 模块的初始相位设置不当或者解调端载波相位没对齐误码率曲线会直接飙到 0.5看起来像模型坏了其实是相位模糊在作怪。理解这一点很关键BPSK 的误码率公式 (P_e \frac{1}{2}\text{erfc}(\sqrt{r})) 是在理想相干解调、无相位模糊的前提下推导的。仿真时如果发现 BPSK 曲线比理论值差很多先检查载波相位再怀疑噪声功率。2.2 QPSK 的正交支路分解与频谱效率QPSK 可以看作两个正交的 BPSK 叠加。基带码元被分成 I、Q 两路I 路取奇数位置码元Q 路取偶数位置码元然后分别与同相载波和正交载波相乘最后相加。这样每个符号携带 2 比特信息在相同带宽下传输速率翻倍频带利用率从 BPSK 的 1 bps/Hz 提升到 2 bps/Hz。解调端采用类似的相干解调两个相互正交的本地载波分别与接收信号相乘经过低通滤波器滤掉高频分量再抽样判决最后并/串变换恢复原始比特流。这里的关键参数是低通滤波器的截止频率和抽样判决的阈值。截止频率设得太高高频噪声滤不干净设得太低有用信号边带被削掉误码率反而上升。我一般会把截止频率设在符号速率的一半到一倍之间具体看滚降系数。QPSK 的误码率公式是 (P_e \frac{1}{2}\text{erfc}(\sqrt{r/2}))注意这里信噪比是 (E_b/N_0)不是 (E_s/N_0)。很多人在仿真里把信噪比单位搞混导致 QPSK 曲线和理论值对不上。记住Simulink 的 AWGN 模块里Eb/No 和 Es/No 差一个 (10\log_{10}(k))k 是每符号比特数。BPSK 的 k1QPSK 的 k2所以同样设置 Eb/No6 dBQPSK 的符号信噪比其实是 9 dB。2.3 为什么同一信道下 BPSK 误码率低于 QPSK从公式就能看出来在相同 (E_b/N_0) 下BPSK 的 erfc 参数是 (\sqrt{r})QPSK 是 (\sqrt{r/2})。erfc 是单调递减函数参数越大值越小所以 BPSK 的误码率确实更低。但注意这里比较的是“相同每比特信噪比”。如果比较相同符号信噪比QPSK 因为每符号能量更高误码率反而可能更低。课设里常见的结论“BPSK 误码率低于 QPSK”是有前提的——相同 Eb/No。这个前提不写清楚答辩时容易被问住。频带利用率则是另一回事QPSK 每个符号 2 比特BPSK 每个符号 1 比特所以在相同带宽下 QPSK 能传更多数据。复杂度上BPSK 只需要一次符号映射QPSK 需要两次接收端判决区域也从两个变成四个硬件资源和算法复杂度都更高。选型时的权衡逻辑很直接信道条件好、追求速率上 QPSK信道条件差、追求可靠性用 BPSK。3. Simulink 模型搭建从模块选型到参数配置的完整链路3.1 核心模块清单与连接顺序这套仿真用到的 Simulink 模块不多但每个都有讲究。下面这张表是我整理的关键模块和参数设置照着填就能跑通。模块名称库位置关键参数作用Random Integer GeneratorCommunications Toolbox / Comm SourcesM2, 采样时间1e-6产生随机二进制序列BPSK Modulator BasebandCommunications Toolbox / Modulation相位偏移0将比特映射到 0/π 相位QPSK Modulator BasebandCommunications Toolbox / Modulation相位偏移π/4将两比特映射到四个相位AWGN ChannelCommunications Toolbox / ChannelsEb/No 模式, 输入信号功率1添加高斯白噪声BPSK Demodulator BasebandCommunications Toolbox / Modulation判决类型硬判决相干解调恢复比特QPSK Demodulator BasebandCommunications Toolbox / Modulation判决类型硬判决相干解调恢复两比特Error Rate CalculationCommunications Toolbox / Comm Sinks接收延迟0, 计算模式整个帧统计误码率To WorkspaceSimulink / Sinks变量名simout01, 保存格式数组导出误码率数据连接顺序是Random Integer Generator → BPSK/QPSK Modulator → AWGN Channel → BPSK/QPSK Demodulator → Error Rate Calculation。Error Rate Calculation 的 Tx 端口接原始比特Rx 端口接解调后比特输出误码率和错误比特数。To Workspace 模块接在 Error Rate Calculation 的输出上把误码率数据导出到 MATLAB 工作区。注意To Workspace 模块的“保存格式”要选“数组”不要选“结构体带时间”。否则脚本里用simout01.signals.values取数据会报错。3.2 用 MATLAB 脚本批量跑信噪比扫描Simulink 模型搭好后手动改一次 Eb/No 跑一次太慢。正确做法是写一个 MATLAB 脚本循环调用sim命令自动扫描信噪比范围把每次的误码率存下来。下面是我常用的脚本框架和原始附件里的思路一致但加了注释和容错。clc; clear all; close all; % 信噪比扫描范围单位 dB ebno 0:0.5:10; snr_linear 10.^(ebno/10); % 换算成线性值 % 预分配数组避免循环中动态扩容 ber_bpsk_sim zeros(1, length(ebno)); ber_qpsk_sim zeros(1, length(ebno)); % 循环调用 Simulink 模型 for i 1:length(ebno) EbNo ebno(i); % 将 EbNo 写入工作区供 AWGN 模块读取 assignin(base, EbNo, EbNo); % 运行模型模型名根据实际文件名修改 sim(BPSK_QPSK.slx); % 从 To Workspace 导出的变量中取最后一个误码率值 % 注意数组长度取决于仿真步数取 end 更稳妥 ber_bpsk_sim(i) simout01.signals.values(end, 1); ber_qpsk_sim(i) simout02.signals.values(end, 1); % 打印进度方便观察卡在哪一步 fprintf(EbNo %.1f dB, BPSK BER %.2e, QPSK BER %.2e\n, ... EbNo, ber_bpsk_sim(i), ber_qpsk_sim(i)); end % 理论误码率计算 ber_bpsk_theory 0.5 * erfc(sqrt(snr_linear)); ber_qpsk_theory 0.5 * erfc(sqrt(snr_linear/2)); % 绘制误码率对比曲线 figure; semilogy(ebno, ber_bpsk_sim, ro-, LineWidth, 1.5); hold on; semilogy(ebno, ber_qpsk_sim, bs--, LineWidth, 1.5); semilogy(ebno, ber_bpsk_theory, r-, LineWidth, 1); semilogy(ebno, ber_qpsk_theory, b--, LineWidth, 1); grid on; legend(BPSK 仿真, QPSK 仿真, BPSK 理论, QPSK 理论, Location, southwest); xlabel(Eb/No (dB)); ylabel(误码率 (BER)); title(AWGN 信道下 BPSK 与 QPSK 误码率对比);这段脚本的逻辑很直白外层循环遍历 Eb/No每次把值写进工作区调用 Simulink 模型从 To Workspace 变量里取误码率。assignin(base, EbNo, EbNo)是关键因为 AWGN 模块的 Eb/No 参数通常填的是变量名EbNo不是固定数字。这样改一次工作区变量模型里的噪声功率就跟着变。参数说明ebno的范围 0 到 10 dB 是课设常用区间步长 0.5 兼顾精度和速度。simout01和simout02对应两个 To Workspace 模块的变量名如果你在模型里改了名字脚本里也要同步改。signals.values(end, 1)取的是最后一次采样点的误码率因为 Error Rate Calculation 模块输出的是累计误码率仿真结束时最后一个值才是最终结果。3.3 频带利用率曲线的绘制误码率曲线只是性能对比的一半频带利用率是另一半。BPSK 和 QPSK 的频带利用率计算方式不同下面这段代码可以直接接在上面的脚本后面。% 频带利用率计算 R 1; % 归一化比特速率单位 bps B 1; % 归一化带宽单位 Hz % BPSK 频带利用率每符号 1 比特带宽效率 1 bps/Hz bpsk_bw_usage R / B * ones(size(ebno)); % QPSK 频带利用率每符号 2 比特带宽效率 2 bps/Hz qpsk_bw_usage 2 * R / B * ones(size(ebno)); figure; plot(ebno, bpsk_bw_usage, r-, LineWidth, 2); hold on; plot(ebno, qpsk_bw_usage, b--, LineWidth, 2); grid on; legend(BPSK 频带利用率, QPSK 频带利用率, Location, east); xlabel(Eb/No (dB)); ylabel(频带利用率 (bps/Hz)); title(BPSK 与 QPSK 频带利用率对比); ylim([0, 2.5]);这里要注意频带利用率和信噪比没有直接关系它只取决于调制阶数。BPSK 是 1 bps/HzQPSK 是 2 bps/Hz画出来是两条水平线。原始附件里的频带利用率公式带了信噪比项那是另一种定义方式把噪声功率折算进带宽了。课设里两种画法都见过关键是图注要写清楚定义不然答辩时容易被追问。4. 避坑与排查仿真跑不通、曲线不对时先查这五条4.1 仿真时间设太大跑一夜没结果现象点运行后进度条几乎不动CPU 占用高但误码率数据一直不更新。 原因Simulink 的仿真时间设成了 100000 秒而采样时间只有 1e-6 秒总步数达到 10^11 量级普通电脑根本跑不完。 解决把仿真时间改成 100 秒到 1000 秒之间同时把 Error Rate Calculation 的“计算模式”设为“整个帧”让它在仿真结束时输出累计误码率。如果担心精度不够可以增加信源采样率而不是拉长仿真时间。4.2 To Workspace 导出数据报“无法解析名称”现象脚本里用simout01.signals.values取数据时MATLAB 报错“无法解析名称 simout01”。 原因Simulink 的“单一仿真输出”选项默认开启所有输出被打包成一个Simulink.SimulationOutput对象而不是独立的变量。 解决在模型配置参数里找到“数据导入/导出”选项卡取消勾选“单一仿真输出”。这样 To Workspace 模块才会把数据以独立变量形式返回到工作区。改完之后simout01和simout02就能正常访问了。4.3 误码率曲线在低信噪比下饱和在 0.5现象Eb/No 从 0 到 4 dB 时误码率一直在 0.5 附近降不下来。 原因要么是 AWGN 模块的 Eb/No 参数没跟着循环更新要么是解调端载波相位和调制端没对齐导致 BPSK 出现“倒相”QPSK 出现 I/Q 支路交换。 解决先检查assignin是否成功把 EbNo 写进工作区可以在循环里加disp(EbNo)确认。再检查调制器和解调器的相位偏移参数是否一致BPSK 都设 0QPSK 都设 π/4。如果用的是差分编码确认编码器和解码器匹配。4.4 QPSK 误码率比 BPSK 还低和理论矛盾现象仿真图上 QPSK 曲线跑到 BPSK 下面去了和公式推导相反。 原因信噪比单位搞混了。AWGN 模块如果设的是 Es/No而理论公式用的是 Eb/NoQPSK 的每符号能量是 BPSK 的两倍换算到 Eb/No 要减 3 dB。看起来 QPSK 更好其实是比较基准不一致。 解决统一用 Eb/No 模式。在 AWGN 模块里把“Eb/No”选上并设置每符号比特数为 1BPSK或 2QPSK。这样仿真和理论就在同一基准下比较了。4.5 频带利用率曲线画成斜线和预期不符现象频带利用率随信噪比变化低信噪比时接近 0高信噪比时接近 2。 原因用了带信噪比项的频带利用率公式把噪声功率折算进有效带宽了。这种定义在特定文献里有但和通常说的“频带利用率只取决于调制阶数”不是一回事。 解决如果课设要求对比调制方式本身的频谱效率直接用常数 1 bps/Hz 和 2 bps/Hz 画水平线。如果要求考虑噪声影响就在图注里写清楚公式来源和定义避免和理论值混淆。5. 从能跑到好用把仿真脚本改成可复用的性能评估工具5.1 参数化封装与一键切换调制方式原始脚本把 BPSK 和 QPSK 写死在两个模型里改一次参数要动 Simulink 界面。更高效的做法是用 MATLAB 函数封装把调制方式、信噪比范围、仿真时长作为输入参数内部自动切换模型或模块使能。下面是一个简化版的函数框架。function [ebno, ber_sim, ber_theory] run_mod_sim(mod_type, ebno_range, sim_time) % mod_type: BPSK 或 QPSK % ebno_range: 信噪比范围如 0:0.5:10 % sim_time: 仿真时长单位秒 ebno ebno_range; snr_linear 10.^(ebno/10); ber_sim zeros(1, length(ebno)); % 根据调制方式选择模型文件 if strcmp(mod_type, BPSK) model_name BPSK_only.slx; k 1; % 每符号比特数 elseif strcmp(mod_type, QPSK) model_name QPSK_only.slx; k 2; else error(不支持的调制方式%s, mod_type); end % 设置仿真时长 set_param(model_name, StopTime, num2str(sim_time)); for i 1:length(ebno) assignin(base, EbNo, ebno(i)); assignin(base, BitsPerSymbol, k); sim(model_name); % 假设 To Workspace 变量名为 ber_out ber_sim(i) ber_out.signals.values(end, 1); end % 理论误码率 ber_theory 0.5 * erfc(sqrt(k * snr_linear)); end这个函数的价值在于换调制方式只需要改一个字符串信噪比范围和仿真时长都是入参跑完直接返回仿真值和理论值。k是每符号比特数BPSK 取 1QPSK 取 2理论公式里乘在信噪比上正好对应 Eb/No 和 Es/No 的换算关系。5.2 用理论曲线校验仿真结果的可信度仿真跑完不能只看曲线好不好看得和理论值对一遍。我一般会算一个“偏差指标”在 Eb/No 大于 4 dB 的区间仿真误码率和理论误码率的对数差如果超过 0.5 个数量级就说明模型有问题。常见原因包括信源比特数不够导致统计涨落、AWGN 模块的随机种子固定导致噪声样本重复、解调器判决门限偏移。下面这段代码可以自动标注偏差过大的点。% 计算仿真与理论的偏差对数域 valid_idx ebno 4; % 只看高信噪比区间 deviation_bpsk abs(log10(ber_bpsk_sim(valid_idx)) - log10(ber_bpsk_theory(valid_idx))); deviation_qpsk abs(log10(ber_qpsk_sim(valid_idx)) - log10(ber_qpsk_theory(valid_idx))); % 找出偏差超过 0.5 个数量级的点 bad_bpsk find(deviation_bpsk 0.5); bad_qpsk find(deviation_qpsk 0.5); if ~isempty(bad_bpsk) fprintf(BPSK 在 Eb/No %s dB 处偏差过大\n, mat2str(ebno(valid_idx(bad_bpsk)))); end if ~isempty(bad_qpsk) fprintf(QPSK 在 Eb/No %s dB 处偏差过大\n, mat2str(ebno(valid_idx(bad_qpsk)))); end这个校验步骤花不了几分钟但能帮你提前发现模型里的系统性错误。比如有一次我跑出来 QPSK 曲线在高信噪比下翘尾查了半天发现是 Error Rate Calculation 模块的接收延迟设成了 1而实际解调输出没有延迟导致比特对齐错位。把延迟改成 0 就正常了。5.3 从课设到工程这套模型还能怎么改这套仿真框架的边界很清楚它只覆盖 AWGN 信道只比较 BPSK 和 QPSK只做硬判决。如果你想用它做更接近实际的评估有三个方向可以扩展。第一把 AWGN 换成瑞利衰落信道观察多径对两种调制的影响这时候 QPSK 的优势可能会被削弱。第二把硬判决改成软判决配合卷积编码和 Viterbi 译码看编码增益能补回多少误码率损失。第三加入载波频偏和符号定时偏差模拟同步不完美时的性能下降这一步最接近真实接收机。我自己的习惯是每次改完模型先跑一遍 Eb/No 0 到 10 dB 的扫描和理论曲线对一遍偏差在可接受范围内再往下做。从那以后我每次搭新的 Simulink 通信模型都强制走一遍“理论校验—偏差标注—参数回查”的流程省下来的返工时间远比写校验脚本的时间多。希望这套东西能帮你在课设或项目里少熬一个晚上。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询