QPSK与AWGN信道MATLAB仿真:误码率BER与误符号率SER理论曲线验证

发布时间:2026/10/20 11:25:49
QPSK与AWGN信道MATLAB仿真:误码率BER与误符号率SER理论曲线验证 做数字通信仿真的人几乎没有人能绕开QPSK和AWGN这个组合。QPSK是四相位调制AWGN是最干净的高斯白噪声信道模型把两者放在一起跑误符号率SER和误比特率BER既是通信原理课上的经典实验也是很多实际系统物理层性能验证的第一步。这个项目的交付物是一套MATLAB仿真程序核心就一件事发送端随机产生比特流QPSK调制后送入AWGN信道接收端相干解调统计不同信噪比下的SER和BER再用理论公式画两条参考曲线一起对比。适合通信专业的学生、刚接触物理层算法的工程师以及所有想搞清楚“仿真曲线为什么能对上理论值”的人。我按自己交付代码时的习惯把整个设计思路、公式推导、代码实现和踩坑经验拆开讲清楚。1. 为什么是QPSK、AWGN和“双曲线验证”1.1 QPSK从BPSK到高阶调制的“性价比之王”QPSK全称Quadrature Phase Shift Keying中文叫正交相移键控。它属于线性数字调制核心思想是用载波的四个不同相位承载信息每个符号携带2个比特。相比BPSKQPSK在相同带宽下传输速率翻倍相比8PSK、16QAM这类更高阶调制它对相位噪声和非线性失真又更宽容星座点距离相对更大抗噪声能力更好。从学习和开发角度看QPSK是理解数字通信系统的一个分水岭。BPSK处理的是实信号、一维判决很多人天然能理解而QPSK引入了复数基带、I/Q两路并行、二维星座图、符号级判决这些概念。可以说搞懂QPSK后面看16QAM、OFDM的子载波映射、LDPC软解调都会顺很多。我见过不少初学者一上来就仿真OFDM结果星座图、误码率全对不上回头补QPSK基础反而很快。1.2 AWGN信道性能对比的“基准赛道”AWGN信道是加性高斯白噪声信道。接收信号在发送信号上叠加一个复高斯噪声这个噪声的瞬时值服从高斯分布功率谱密度在关心的频带内是平坦的所以叫“白”。物理上它可以用接收机热噪声、放大器噪声来理解中心极限定理保证了大量独立随机源叠加后近似高斯。选择AWGN作为第一个仿真信道是因为它没有任何选择性衰落、没有多径、没有频偏是公平的“基准赛道”。一个调制方案如果在AWGN下都达不到理论误码率那基本可以断定实现有bug反过来在AWGN下验证通过后再往系统里加多径、加频偏、加相位噪声才能逐步定位每个模块的贡献。这个递进思路比一上来就搞完整系统链路要稳妥得多。1.3 为什么同时统计SER和BER误符号率SER描述的是“符号被判错”的概率误比特率BER描述的是“比特被判错”的概率。未编码系统中一个符号判错不代表里面所有比特都错尤其使用Gray映射时相邻星座点只差1比特最常见的错误是1个符号错1个比特。因此SER和BER之间存在换算关系但二者不等价。同时统计这两个指标等于给同一个实验加了两把标尺。SER用来验证调制格式本身的设计是否合理BER用来评估最终信息比特的可信程度。如果在系统中接入信道编码编码器工作在比特级那么BER就更贴近系统最终性能。项目中同时输出两条曲线也方便和不同的理论公式做交叉验证避免“曲线看着对但实际上公式套错”的问题。2. QPSK方案设计星座映射、Gray编码与能量归一化2.1 星座图与I/Q两路调制QPSK的调制过程可以拆成两路独立的BPSK一路打在I支路同相分量一路打在Q支路正交分量两路幅度各为 ±1/√2。于是星座点落在复平面上四个位置分别是$$s \in \left{\frac{1j}{\sqrt{2}}, \frac{-1j}{\sqrt{2}}, \frac{-1-j}{\sqrt{2}}, \frac{1-j}{\sqrt{2}}\right}$$这样每个符号的功率都是1。MATLAB仿真里不需要真的生成载波直接在复基带上操作即可把每2个比特拆开前一个比特映射到I路后一个映射到Q路组成复数符号。这个方式的好处是模型干净和教科书上的星座图完全对应。2.2 Gray映射为什么优于自然映射星座点可以按相位顺序排列关键问题是怎么给四个点分配二进制编号。如果按自然顺序沿逆时针排列成00、01、10、11那么相邻象限之间会出现一次变化2个比特的情况。而在高信噪比下判决错误基本发生在相邻星座点之间自然映射会让某些错误一次拖累2个比特。Gray映射把相邻星座点的编码设计成只差1个比特例如00、01、11、10。这时最常见的相邻错误只导致1个比特错实际BER就会更优。在我的仿真里发送端按“I路比特和Q路比特各自独立”的方式映射接收端也按I/Q独立判决这个方案和理论公式能精确对上同时实现了Gray映射的好处。2.3 符号能量归一化的数学与必要性不少初学者写QPSK时会顺手把星座点写成 ±1±j这个习惯非常危险。如果星座点是 ±1±j符号能量是2后续所有Eb/N0和N0的换算都会偏离3dB。正确做法是把星座点写成 (±1±j)/√2这样每个符号的模平方正好是1。为什么能量归一化如此重要因为整个误码率公式建立在“符号能量Es”和“每比特能量Eb”的定义之上。接收信噪比给定后噪声方差N0是由能量反推出来的如果Es多算一倍等效于噪声加小了一倍仿真曲线会对比理论曲线左移约3dB。所以在代码里养成一个习惯每次调制完立刻算一下mean(abs(sym).^2)确认等于1再进主线。2.4 相干解调与判决区域接收端采用相干解调默认接收机已经恢复出准确的载波相位和定时。在复基带模型里这体现为直接取接收符号的实部和虚部分别做硬判决。判决阈值是0I路大于等于0判为1/√2对应比特0小于0判为-1/√2对应比特1。Q路同理。由此四个象限分别对应四个比特组合。误差性能取决于星座点到判决边界的欧氏距离边界越远抗噪声能力越强。这个简单的阈值判决就是最大后验准则在等概率星座下的退化形式不需要像多用户检测那样做复杂搜索。3. AWGN信道建模与信噪比体系3.1 复基带AWGN的生成方式实数AWGN信道只要加一个实高斯噪声而复数基带的QPSK仿真必须加复高斯噪声。复高斯噪声由两个独立实高斯噪声组成一个加在实部一个加在虚部二者方差各为N0/2。MATLAB里的标准写法noise sqrt(N0/2) * (randn(1, Nsym) 1j*randn(1, Nsym));验证方法很简单算一下噪声样本的功率mean(abs(noise).^2)结果应该非常接近N0。如果这里写错比如只加sqrt(N0)*randn(1,Nsym)实部和虚部的噪声特性就不对仿真曲线会莫名其妙地“优于”理论值而且星座散点图会呈现奇怪的非对称分布。3.2 Eb/N0、Es/N0和噪声方差的关系信噪比体系是整个仿真最容易翻车的地方。常用指标是Eb/N0即每比特能量与噪声功率谱密度的比值单位通常是dB。QPSK每符号携带2比特因此每符号能量和每比特能量的关系是:$$E_s k \cdot E_b 2E_b$$转换成dB就是 Es/N0(dB) Eb/N0(dB) 3.01 dB。仿真中给定Eb/N0(dB)后线性值由10^(EbN0_dB/10)得到然后根据Es1反推出N0$$N_0 \frac{E_b}{(E_b/N_0)_{lin}} \frac{1/2}{10^{E_b/N_0(dB)/10}}$$举例Eb/N010dB时(Eb/N0)_lin10N00.05噪声每维标准差 sqrt(N0/2)≈0.158。这个数值可以在调试时先打印出来手算核对一遍能省去后面大量排查时间。3.3 误符号率与误比特率的理论推导QPSK可以看成两个正交BPSK的叠加。每一路BPSK的比特错误概率为$$p Q\left(\sqrt{\frac{2E_b}{N_0}}\right)$$两路同时判决正确的概率是 (1-p)^2所以误符号率$$P_s 1 - (1-p)^2 2p - p^2$$$$P_s 2Q\left(\sqrt{\frac{2E_b}{N_0}}\right) - Q^2\left(\sqrt{\frac{2E_b}{N_0}}\right)$$误比特率在I/Q独立判决且采用Gray映射的情况下正好等于单路BPSK的误码率$$P_b Q\left(\sqrt{\frac{2E_b}{N_0}}\right)$$很多教材写成“误比特率约等于误符号率的一半”其实就是高信噪比下忽略p^2项得到的近似。严格按完整公式计算仿真点和理论虚线的贴合度会更好尤其在低信噪比区域。3.4 蒙特卡洛仿真与理论曲线的对赌逻辑蒙特卡洛仿真的本质是用大量随机实验的频率逼近概率。理论公式给出的是极限值仿真结果是有限样本下的估计值二者存在统计涨落。如果仿真点和理论曲线整体贴合只是在高低信噪比点上有轻微抖动说明实现正确。怎么判断“轻微”我的经验是看两个维度一是每个信噪比点统计到的错误符号数二是多个连续信噪比点的整体趋势。错误数低于50时单点波动会非常明显错误数达到100以上时相对误差大约在±10%以内。连续点如果都在理论曲线附近随机抖动属于正常如果所有点系统性偏向一侧基本可以确定公式或参数写错了。4. MATLAB仿真实现与核心代码4.1 参数初始化先想清楚要扫什么写代码之前先把仿真框架列清楚扫什么参数、扫多大范围、每个信噪比点跑多少符号。项目里默认扫0到10dB步长1dB每个点跑1e6个符号。之所以不扫到12dB以上是因为该点的BER已经低于1e-61e6个符号只有2e6个比特统计到的错误比特往往只有个位数曲线必然乱跳。参数区还应该把调制阶数M、每符号比特数k这些常量提取出来。以后扩展成8PSK或16QAM时只改参数区就能复用框架。代码里我习惯写成M 4; k log2(M);这样不仅在调制的地方清楚在理论公式里也能直接对应。4.2 主循环调制、加噪、解调、统计主循环里最重要的一步是“先算噪声方差再加噪声”。噪声方差N0必须放在Eb/N0循环内部计算因为每个信噪比点对应的噪声强度都不一样。调制时把比特流按奇偶位置拆成I路和Q路bI bits(1:2:end); bQ bits(2:2:end); sym ((2*bI - 1) 1j*(2*bQ - 1)) / sqrt(2);这行代码完成了比特到星座点的映射同时完成了能量归一化。接收端判决也很直白bI_hat real(rx) 0; bQ_hat imag(rx) 0;统计错误时比特错误要分别统计I路和Q路再求和符号错误则用“或”逻辑判断该符号的I路或Q路是否任一出错。这个区别很关键不然SER会被错算成BER。4.3 理论曲线计算与绘图理论曲线用MATLAB自带的qfunc函数计算。注意qfunc输入的参数是线性值不是dB值所以要先做一次线性转换BER_theory(idx) qfunc(sqrt(2*EbN0_lin)); SER_theory(idx) 2*qfunc(sqrt(2*EbN0_lin)) - qfunc(sqrt(2*EbN0_lin)).^2;绘图时用semilogy因为误码率跨度可能达到几个数量级线性坐标会把低误码率区域全部压到横轴上。仿真曲线用带标记的实线理论曲线用不带标记的虚线这样打印出来也能一眼分清。4.4 完整可运行的仿真脚本下面是我交付这个项目时用的完整脚本可以直接复制运行。核心参数都标了注释方便按需求调整%% QPSK over AWGN: BER and SER Monte Carlo Simulation clear; clc; close all; % ---------------- 仿真参数 ---------------- EbN0_dB 0:1:10; % 比特信噪比扫描范围(dB) nSym 1e6; % 每个SNR点发送符号数 M 4; % QPSK调制阶数 k log2(M); % 每符号比特数 nBits nSym * k; % 总比特数 % ---------------- 结果存储 ---------------- BER zeros(size(EbN0_dB)); SER zeros(size(EbN0_dB)); BER_theory zeros(size(EbN0_dB)); SER_theory zeros(size(EbN0_dB)); % ---------------- 主循环 ---------------- for idx 1:length(EbN0_dB) % 线性信噪比 EbN0_lin 10^(EbN0_dB(idx)/10); % 1) 随机比特流 bits randi([0 1], 1, nBits); % 2) QPSK调制, Gray映射, 符号能量Es1 bI bits(1:2:end); bQ bits(2:2:end); sym ((2*bI - 1) 1j*(2*bQ - 1)) / sqrt(2); % 3) AWGN信道 N0 (1/k) / EbN0_lin; % Es1, 所以Eb1/k noise sqrt(N0/2) * (randn(size(sym)) 1j*randn(size(sym))); rx sym noise; % 4) 相干解调与硬判决 bI_hat real(rx) 0; bQ_hat imag(rx) 0; % 5) 误差统计 bitErr sum(bI_hat ~ bI) sum(bQ_hat ~ bQ); BER(idx) bitErr / nBits; symErr sum((bI_hat ~ bI) | (bQ_hat ~ bQ)); SER(idx) symErr / nSym; % 6) 理论曲线 p qfunc(sqrt(2 * EbN0_lin)); BER_theory(idx) p; SER_theory(idx) 2*p - p^2; end % ---------------- 绘图 ---------------- figure(Color, w); semilogy(EbN0_dB, SER, bo-, LineWidth, 1.2, MarkerSize, 6); hold on; semilogy(EbN0_dB, BER, rs-, LineWidth, 1.2, MarkerSize, 6); semilogy(EbN0_dB, SER_theory, b--, LineWidth, 1.2); semilogy(EbN0_dB, BER_theory, r--, LineWidth, 1.2); grid on; xlabel(Eb/N0 (dB)); ylabel(Error Probability); legend(仿真SER, 仿真BER, 理论SER, 理论BER, Location, southwest); title(QPSK over AWGN: BER and SER vs Eb/N0); axis([min(EbN0_dB) max(EbN0_dB) 1e-6 1]);运行后应该能看到四条曲线两条理论虚线在对应实线附近整体趋势呈线性下降。如果出现明显偏移直接跳到后面的踩坑清单排查。5. 仿真曲线怎么看结果分析与样本量控制5.1 典型曲线特征与正确性判据以0到10dB扫描为例Eb/N00dB时BER大约在0.05量级SER大约在0.1量级到10dB时BER降到约4e-6SER约8e-6。整条曲线在semilogy坐标下接近一条向下倾斜的直线高信噪比区间每增加约3dB误码率下降约一个数量级。判断仿真是否正确的第一个标准是仿真点是否围绕理论曲线随机抖动。第二个标准是SER和BER两条实线的间距高信噪比下SER约为BER的2倍对应3dB的视觉间隔。如果你看到两条线完全重合大概率把SER统计成了BER如果间距过大可能符号判决逻辑写错了。5.2 蒙特卡洛抖动的来源与抑制抖动来自有限样本的统计涨落。同一个信噪比点换一组随机比特重新跑BER结果会略微变化这是正常现象。低信噪比时错误数多相对稳定性好高信噪比时错误数稀少一个错误数目的差异就会导致估计值明显变化。抑制抖动最直接的方法是增大每个点的符号数。但如果所有点都无脑加大到1e8程序会跑得非常慢而且低信噪比点根本不需要那么多样本纯属浪费。更科学的做法是根据目标误码率动态调整样本量让高信噪比点自动多跑。5.3 仿真点数选择策略与自适应方案误码率估计本质上是一个伯努利试验的概率估计问题。统计到N_err个错误时相对标准差约为 1/sqrt(N_err)。想要估计误差在10%以内至少让每个点积累100个错误比特想压到3%以内需要积累约1000个错误比特。一个实用的自适应方案是先用理论公式估算该点的BER然后反推需要的比特数nMinErr 100; nBitsNeeded ceil(nMinErr / max(BER_theory(idx), 1e-12));然后把nBitsNeeded作为该点的实际调制比特数。这样低信噪比点样本量可以小高信噪比点自动变大总运行时间可控。缺点是每个点样本量不同绘制曲线时视觉上可能会有一点“前密后稀”的感觉但在概率坐标下完全不影响结果呈现。5.4 仿真点偏离理论时的排查思路如果仿真曲线整体比理论值好也就是仿真误码率更低先检查噪声功率是否加小了星座能量是否归一化、N0是否忘了除以k、噪声是否为复噪声。如果仿真曲线整体比理论值差先检查判决是否是硬判决、星座映射是否写错、信号能量是否被额外衰减。还有一种隐蔽情况理论公式用对了但横轴错位。比如把Eb/N0坐标写成了Es/N0曲线会整体右移约3dB把Es/N0写成了Eb/N0曲线会整体左移约3dB。所以在代码里把横轴变量、单位都写在figure的xlabel里一目了然。6. 踩坑实录常见问题与调试经验速查6.1 曲线整体偏移3dB能量换算被搞混这是最高频的问题没有之一。现象是仿真曲线和理论曲线形状几乎一样但整体沿横轴平移3dB左右。原因基本出在符号能量Es和每比特能量Eb的换算上。QPSK的Es2Eb转换到dB就是3.01dB。如果代码里直接用N0 1/EbN0_lin相当于把Es当成了1而不是2会把噪声加小3dB曲线自然左移。解决方法是把换算过程显式写清楚先设Es1然后EbEs/k再计算N0Eb/EbN0_lin。同时可以在代码里打印一行fprintf(Eb/N0 %.1f dB, N0 %.4f, Es %.2f\n, EbN0_dB(idx), N0, mean(abs(sym).^2));调试时盯着输出错误一眼就能发现。6.2 复噪声写成实噪声结果“虚好”有人会图省事写成rx sym sqrt(N0) * randn(size(sym));这样只给实部加了噪声虚部完全没噪声等效信噪比比设定值高仿真曲线会比理论曲线好一大截。而且星座散点图会明显变形实部方向散开虚部方向几乎没有分布。QPSK的信号本身同时占据实部和虚部噪声也必须同时作用在两个分量上。标准写法是sqrt(N0/2)*(randn(1,nSym)1j*randn(1,nSym))。每次写完可以画一个散点图检查噪声分布是否呈圆形对称这是判断复噪声是否正确的直观方式。6.3 高信噪比曲线乱跳样本量不够很多新手把0到10dB全跑1e6个符号看到10dB点BER在1e-5到1e-6之间剧烈跳动就开始怀疑代码。其实这个点理论上只有约4e-6的错误概率2e6比特里预期只有8个错误比特任何一个错误数变化都会带来约12%的相对偏差跑出来的数自然不稳。实用的做法是用5.3节的自适应样本量方案或者干脆把扫描范围限制到BER不低于1e-5的区间。仿真耗时和曲线平滑度是需要权衡的不需要为了一个点把所有SNR点的样本都提升。6.4 理论公式套错SER的平方项被丢掉误符号率完整公式是 2p-p^2其中 pQ(sqrt(2Eb/N0))。不少人参考网上代码时只写 2*p忽略p^2项导致理论SER曲线在低信噪比区域比正确值偏高几个百分点。低信噪比时p本身很大p^2不可忽略高信噪比时p很小二者差距才看不出来。所以在项目代码里我特意保持完整公式并且把p先算出来再组合成两个指标避免在同一行里写两次qfunc导致代码混乱。改p的定义时两个指标会自动同步更新。6.5 出图细节半对数坐标与曲线样式误码率曲线必须用对数纵轴线性纵轴在误码率低于1e-2后就什么都看不出来了。建议用semilogy或者绘图后用set(gca,YScale,log)。横轴范围不要拉得太长否则曲线会在高信噪比区域贴到底边观感很差一般让最低误码率停在图形下端约两格的位置比较合适。曲线样式上仿真点用带Marker的实线理论曲线用无Marker的虚线这样在黑白打印时也能区分。图例放在southwest而不是默认位置因为高分贝端曲线较低默认位置容易盖住数据。最后再分享一点实际体会这个程序我前前后后写了很多版本最早也翻过车当时图省事把星座能量设成2结果曲线左移3dB我盯着理论公式看了半天没发现问题后来打印Es才意识到。从那以后我养成一个习惯每次仿真前先算一次理论BER确定哪些信噪比点值得仿真再决定样本量。这个方法帮我省了无数跑批量的时间。项目里的脚本是按最简结构组织的后续如果想扩展成8PSK或者加一个Gray映射查找表只需要在调制和解调两处做局部替换主循环和统计部分完全不用动。希望这篇记录能帮你少踩几次坑。

关于本文作者

来自尧图内容编辑团队

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

尧图内容编辑团队

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

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

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

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

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

网站改版的5个关键决策

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

获取专属建站方案

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

立即免费咨询