
简介这是一份以MATLAB脚本形式实现的QPSK与OQPSK调制解调仿真资源面向通信专业学生、算法工程师及需要快速理解数字调制原理的开发者可解决相位调制建模、抗噪声性能分析及符号间干扰观察等共性问题。压缩包内仅含1个m文件整体大小约1KB文件简洁但可直接在MATLAB中运行适合课堂演示、课程设计或基础原理验证。已有453人学习浏览说明该资源在相关领域具有一定参考价值。通过运行代码可模拟QPSK四相绝对相移映射00、01、10、11、加噪信道下的解调恢复并对比OQPSK采用45度相位偏移后在减小包络起伏、抑制符号间干扰方面的差异帮助读者直观掌握两种调制方式的波形、星座图及误码率性能同时也能据此理解QPSK相较于2ASK、2FSK在频带利用率与抗干扰能力上的优势为后续通信系统设计与仿真提供可复用的起点。1. QPSK 为什么能抗干扰从相位星座图说起拿到 oqpsk.m 源码很多人跑完误码率曲线就关掉没吃透 QPSK 的抗干扰来源。QPSK 全称 Quadrature Phase Shift Keying即正交相移键控也叫四相绝对相移调制用四个相位状态承载两位比特相比 BPSK 频谱利用率翻倍。噪声要把相位推过星座点判决边界才会误判这是抗干扰的理论底子。真正的隐患在符号切换QPSK 允许 180 度相位跳变带限后频谱旁瓣抬高功放非线性和 AGC 压力变大OQPSK 把 Q 路延迟半个符号最大跳变压到 90 度带限系统里更稳。资源包里 OQSK 是 OQPSK 的手误oqpsk.m 脚本正是验证这条链路的。下面从原理、源码到调参逐步拆。2. 从 QPSK 到 OQPSK相位跳变、频谱扩展与 ISI 抑制2.1 QPSK 的 180 度相位跳变为什么是隐患QPSK 星座图上有四个点通常分布在单位圆的 45 度、135 度、225 度、315 度位置。符号切换时如果前后两个符号映射到对角方向瞬时相位差就是 180 度。虽然在理想线性信道里不影响判决但无线通信链路里存在带限滤波器、功放非线性环节。180 度跳变意味着载波幅度要先穿过原点再回来包络剧烈起伏经过带通滤波后产生明显的 ISI还伴随频谱旁瓣再生。这也是很多教材强调 QPSK 频谱效率高但工程里很少直接在高功放饱和区用 QPSK 的原因。功放工作在饱和区时AM/PM 效应会把包络波动转成额外相位噪声误码率底噪一下被抬起来。卫星通信里的 TWTA 功放尤其明显设计者要么换 OQPSK要么加预失真也不愿意让信号包络波动太大。2.2 OQPSK 的偏置正交把 180 度拆成两步 90 度OQPSK 全称 Offset Quadrature Phase Shift Keying通常翻译成偏置正交相移键控。它和 QPSK 的星座图几乎一样四个相位点相同唯一区别是 Q 路比 I 路延迟半个符号周期 T/2。延迟之后I、Q 两支路不可能同时改变符号因此信号从一个象限跳到对角象限时实际相位变化会先经过相邻象限最大瞬时相位跳变被限制在 90 度。带来的直接好处是包络不再过零包络起伏明显变小。对于带限系统和非线性功放OQPSK 的频谱再生比 QPSK 小很多等效于减少对相邻频带的干扰。注意 OQPSK 没有改变相位点之间的欧氏距离所以高斯白噪声下理论误码率和 QPSK 一样差别主要体现在有非线性或带限场景。下面是一段 MATLAB 片段用来说明构造 OQPSK 的 I/Q 时序并观察最大相位跳变% 观察 QPSK 与 OQPSK 最大相位跳变的构造方法 N 8; % 符号数取少一点方便观察 oversample 16; % 每符号采样点 bits randi([0 1], N*2, 1); % 随机比特流 iBits bits(1:2:end); % 奇数位给 I 路 qBits bits(2:2:end); % 偶数位给 Q 路 iSeq 1 - 2*iBits; % 双极性电平 1/-1 qSeq 1 - 2*qBits; % 上采样到符号速率 iUp upsample(iSeq, oversample); qUp upsample(qSeq, oversample); % OQPSK 核心Q 路延迟 half symbol half oversample / 2; qDelayed [zeros(half,1); qUp(1:end-half)]; qpskPhase angle(iUp 1j*qUp); oqpskPhase angle(iUp 1j*qDelayed);代码里upsample把每个符号电平扩展成oversample个采样点qDelayed的开头zeros(half,1)就是半个符号周期的时延。对qpskPhase和oqpskPhase做差分可以看到QPSK 会出现 180 度跳变而 OQPSK 最大只有 90 度这就是偏置正交的核心意义。2.3 QPSK 与 OQPSK 的工程选型对比实际工程里选 QPSK 还是 OQPSK主要看信道有没有带限、功放有没有压缩。下表是我做链路仿真时常用的对比维度对比项QPSKOQPSK星座点数44频谱效率2 bit/s/Hz2 bit/s/Hz相邻符号最大相位跳变180 度90 度包络过零会不会带限后的频谱旁瓣较高较低AWGN 理论误码率相同相同对非线性功放的敏感度高低典型场景线性信道、Wi-Fi、LTE卫星链路、扩频系统看这张表再看 oqpsk.m 里的仿真模型就会明白发送端为什么要把 Q 路延迟半个符号。下面进入源码级拆解看这个脚本怎么模拟从比特到星座点的完整过程。3. oqpsk.m 源码拆解调制映射、加噪信道与解调判决3.1 调制端符号映射与成型滤波一份典型的 oqpsk.m 脚本第一步是把二进制比特流映射成 I/Q 两路基带符号。映射用格雷码更好因为相邻相位点只有一位比特变化误判一个相位点只会产生 1 bit 错误。假设data是长度为2N的列向量映射关系可以写成% 基带调制映射使用格雷码 grayMap [0 1 3 2]; % 比特十进制到相位序号的映射 symbols zeros(N, 1); for idx 1:N bits2 data(2*idx-1:2*idx); [~, pos] ismember(bi2de(bits2, left-msb), grayMap); symbols(idx) exp(1j * (pos-1) * pi/2); endgrayMap决定 00、01、11、10 对应 0 度、90 度、180 度、270 度。bi2de把两位比特转成十进制数ismember找到在格雷码表里的位置再用exp(1j*...)生成相应相位的复数符号。注意这里用的是非归零矩形脉冲实际链路里还要接成型滤波器。成型滤波器通常用根升余弦RRC发射端和接收端各放一个合起来是升余弦响应采样点上没有码间串扰。滚降因子一般取 0.25 到 0.5越小频带越窄但滤波器阶数更长定时偏移的容忍度也越差。oqpsk.m 如果只做基带仿真可以省略成型滤波但得到的误码率曲线会偏乐观因为没算带限引入的 ISI。3.2 信道模型AWGN 噪声与 Eb/N0 换算仿真过程中几个信号的尺寸关系经常让人晕先列一张表对照自己的变量名检查信号长度含义data2N×1二进制比特流symbolsN×1调制后的复数符号txSignal取决于成型滤波过采样并滤波后的基带波形rxSymbolsN×1匹配滤波后按符号率抽取的判决值txSignal的实际长度由卷积决定不是严格的 2N×oversample但每比特能量统计要以实际信号长度为准。加噪声的方式决定误码率曲线横轴是 Eb/N0 还是 SNR。Eb/N0 是每比特能量与噪声功率谱密度的比值比较不同调制方式时用它最公平。换算时先把信号能量统计出来再根据目标 Eb/N0 生成对应功率的高斯白噪声% AWGN 信道按 Eb/N0 换噪声功率 EbN0dB 8; % 目标 Eb/N0单位 dB EbN0 10^(EbN0dB/10); Eb sum(abs(txSignal).^2) / length(data); % 每比特能量 No Eb / EbN0; % 噪声功率谱密度 noise sqrt(No/2) * (randn(size(txSignal)) 1j*randn(size(txSignal))); rxSignal txSignal noise;txSignal是成型滤波后的复数基带信号length(data)是比特总数。噪声的实部虚部各取No/2功率合起来总功率是No这是复基带仿真的标准写法。当 Eb/N0 从 0 扫到 10 dB 时误码率会画出典型的下降曲线。3.3 解调端匹配滤波、采样与判决接收端的相干解调分四步匹配滤波、定时采样、相位补偿、距离判决。匹配滤波器的系数就是发射端 RRC 滤波器系数的镜像在实数基带里等价于同一个滤波器做卷积% 接收端匹配滤波root-raised-cosine pulse rrcFilter rcosdesign(0.35, 6, oversample, sqrt); rxFilt conv(rxSignal, rrcFilter, same); % 补偿滤波器延迟并下采样 delaySpan 6 * oversample / 2; rxSymbols rxFilt(delaySpan1 : oversample : end);rcosdesign(0.35, 6, oversample, sqrt)生成长度 6 个符号、滚降系数 0.35 的根升余弦滤波器。conv(...,same)裁剪到和输入一样长但卷积会引入群延迟所以采样起点要跳过delaySpan个点这个点取滤波器阶数的一半。做硬判决时把复数符号的相位映射回四个象限% 最小距离判决并反查格雷码 constellation exp(1j * (0:3) * pi/2); % 四个理想星座点 demodBits zeros(length(rxSymbols)*2, 1); for k 1:length(rxSymbols) dist abs(rxSymbols(k) - constellation); [~, minIdx] min(dist); phaseIdx minIdx - 1; % 恢复相位序号 [~, bitIdx] ismember(phaseIdx, grayMap); demodBits(2*k-1:2*k) de2bi(bitIdx - 1, 2, left-msb); endconstellation和发送端的四个相位点顺序一致dist计算接收符号到每个理想点的欧氏距离取最近点判决。phaseIdx是相位序号通过ismember在格雷码表里反查比特索引再用de2bi展开成两位比特。注意判决前最好做一次平均相位估计把收发本振的固定相位差去掉否则整个星座图旋转后误码率会停在 0.25 左右。仿真脚本里常见错误是忽略滤波延迟导致采样位置偏移误码率曲线比理论值差 2 到 3 dB这是下面要展开的调参重点。4. 参数怎么设MATLAB 仿真中的关键配置与坑4.1 过采样率、滚降因子与滤波器阶数oqpsk.m 里最影响结果的三个参数是过采样率oversample、滚降因子rolloff和滤波器符号跨度spans。过采样率太低成型滤波后的波形不够平滑匹配滤波也难以对准采样点。常见做法是设成 8 或 16符号数多时也可以 4但不要小于 2。仿真时先用 1e5 个符号扫参确认趋势后再加大到 1e6 压尾部误码率能省不少时间。参数参考如下参数推荐值说明oversample8~16每符号采样数影响波形精度rolloff0.25~0.5滚降因子越小越省带宽但越敏感spans6~12滤波器符号长度决定滚降过渡带精度仿真符号数1e4~1e6保证每个 Eb/N0 点至少 100 个错误比特参数组合可以参考下面代码% 参数设置示例 oversample 8; % 每符号采样点数 rolloff 0.35; % 根升余弦滚降因子 spans 6; % 滤波器覆盖 6 个符号周期 rrc rcosdesign(rolloff, spans, oversample, sqrt);rcosdesign生成的滤波器长度是spans*oversample1延迟为spans*oversample/2个采样点接收端做conv之后必须用这个延迟对齐采样位置。很多误码率地板来自这里而不是调制方式本身。4.2 定时同步与相位模糊基带仿真不一定需要完整定时恢复但至少要做最大平均能量对准。简单办法是用相关搜索在滤波后的信号里扫一遍可能的采样偏移选择输出能量最大的一组作为采样点。对于 OQPSK因为 Q 路延迟了半个符号直接按整符号采样会得到类似 QPSK 的误码率但没有体现 OQPSK 的抗带限优势。工程上评估 OQPSK通常还要看功率谱旁瓣而不只是看 AWGN 误码率。相位模糊是另一个容易翻车的点QPSK 星座是旋转对称的如果接收端不知道绝对相位解调可能整体旋转 90 度、180 度、270 度出现与噪声无关的系统性误码。常用方案是在每帧开头插入导频序列估计相位旋转角度再补偿。oqpsk.m 里如果只有一段很短的 bit 序列可以手动观察星座图中心位置指定一个相位偏移但不能写进生产链路。4.3 抗干扰评估从仿真结果看哪些参数影响最大下面这段代码把一个完整的仿真循环压缩成可复现的形态跑通之后再去扩成多个 Eb/N0 点% 不同 Eb/N0 点下的误码统计循环 for EbN0dB 0:2:10 EbN0 10^(EbN0dB/10); noise sqrt(No/2) * (randn(size(txSignal)) 1j*randn(size(txSignal))); rx txSignal noise; rxF conv(rx, rrc, same); rxSym rxF(delaySpan1:oversample:end); % 相位补偿后做最近邻判决并统计错误比特 errors(k) sum(bitErr 0); end这里No要使用仿真的每比特能量除以EbN0算出的固定值不能在循环内重新计算否则每次加噪功率都不一样曲线会抖动。如果发现误码率在高信噪比区域出现地板优先检查滤波延迟和相位补偿而不是怀疑 QPSK 本身性能不行。5. 把仿真结果变成抗干扰指标误码率曲线绘制技巧5.1 用 semilogy 对比理论曲线与仿真曲线仿真跑完最直观的抗干扰指标是误码率曲线。QPSK 在 AWGN 下的理论误码率可以写成qfunc(sqrt(2*EbN0))为了和 OQPSK 仿真对比通常用 semilogy 画在同一张图上。关键是统计误码率时要注意最少错误比特数否则曲线尾部会有一堆毛刺。% 绘制理论值与仿真值的误码率曲线 EbN0dB 0:0.5:10; berTheo qfunc(sqrt(2*10.^(EbN0dB/10))); semilogy(EbN0dB, berTheo, k-, LineWidth, 1.5); hold on; semilogy(EbN0dB_sim, berSim, ro, MarkerFaceColor, r); xlabel(Eb/N0 (dB)); ylabel(BER); legend(理论 QPSK, OQPSK 仿真); grid on;qfunc是 MATLAB 的 Q 函数高斯白噪声下 QPSK 和 OQPSK 理论误码率相同。EbN0dB_sim和berSim要对应循环里每个点的统计结果别把横轴写错成整体 SNR。5.2 去掉曲线尾部毛刺的统计准则经验做法是每个 Eb/N0 点至少统计 50 到 100 个错误比特少于此数就停止继续仿真让该点标记为空。这样曲线尾部不会出现 0 误码率掉到图外的现象。也可以把berSim的零值改成NaNsemilogy会跳过这些点。如果观察到仿真误码率在高信噪比区域比理论值平缓下不去那大概率是残留相位偏差或滤波延迟没对齐。写一个循环扫描相位补偿角% 扫描相位旋转补偿取误码率最小的角度 for theta 0:pi/100:pi/2 rxC rxSym * exp(-1j*theta); % 判决并统计误码率保存最优 theta end扫描范围只需要 0 到 pi/2因为 QPSK 星座是 90 度旋转对称超过 pi/2 的结果重复。把最优 theta 固定下来重新跑整条误码率曲线高 SNR 段的拐点会消失这条曲线才是真正能拿去写报告的抗干扰指标。本文还有配套的精品资源点击获取