MATLAB生成QPSK水声通信发射波形:2比特映射、星座图与WAV文件导出

📅 2026/6/26 6:41:00
MATLAB生成QPSK水声通信发射波形:2比特映射、星座图与WAV文件导出
MATLAB生成QPSK水声通信发射波形2比特映射、星座图与WAV文件导出关键词MATLAB QPSK、水声通信仿真、QPSK WAV、星座图、采样率、载波频率、符号率、通信原理课程设计上一篇写了 BPSK从 0/1 比特生成一段可以保存为 WAV 的水声通信发射波形。BPSK 的优点是简单直观但每个符号只携带 1 bit。这篇继续往前走一步用 MATLAB 生成 QPSK 水声通信发射波形。QPSK 的核心变化是每 2 个 bit 组成 1 个符号用 4 个不同相位表示信息。这样在相同符号率下QPSK 的理论比特率是 BPSK 的 2 倍如果保持相同比特率QPSK 可以使用更低的符号率。本文配套项目ZoperIOT/underwater-acoustic-modulation1. QPSK 在水声通信仿真里解决什么问题QPSK全称 Quadrature Phase Shift Keying正交相移键控。BPSK 可以理解为用两个相位表示 0 和 1而 QPSK 用四个相位表示四种 2 bit 组合比特组合十进制值QPSK 符号相位000π / 4 \pi/4π/40113 π / 4 3\pi/43π/41025 π / 4 5\pi/45π/41137 π / 4 7\pi/47π/4在这个项目中QPSK.m默认使用phaseOffset pi/4因此星座点不会落在 I/Q 坐标轴上而是整体旋转 45°。这样做在工程和教学里都很常见因为四个星座点分布更直观也便于观察 I/Q 两路都参与调制。可以把 QPSK 的复基带符号写成s k e j ( ϕ 0 2 π m k / 4 ) s_k e^{j(\phi_0 2\pi m_k/4)}sk​ej(ϕ0​2πmk​/4)其中m k m_kmk​是每 2 bit 转成的整数取值为 0、1、2、3ϕ 0 \phi_0ϕ0​是初始相位偏移本项目默认是π / 4 \pi/4π/4每个s k s_ksk​是一个复数星座点。后面的流程和 BPSK 类似符号序列经过 RRC 脉冲成形再上变频到声学载波频率最后得到实值通带波形并写入 WAV 文件。2. 发射端基本流程QPSK 发射端可以拆成下面几步生成或读取 0/1 比特流每 2 bit 分成一组将00、01、10、11映射到 4 个 QPSK 星座点对复基带符号做 RRC 脉冲成形用载波频率fc上变频取实部得到可播放的实值通带波形归一化并写入 WAV 文件。如果只看代码接口这个项目已经把中间过程封装好了[waveform,info]QPSK(bits,options);其中bits是输入比特流options是采样率、载波频率、符号率等参数waveform是输出的实值通带波形info保存本次生成的调制方式、参数、符号、基带信号等信息。3. 参数怎么设置fs、fc、Rs 和 sps本文使用一组适合先跑通的参数参数含义本文取值设置建议sampleRate/f s f_sfs​采样率96000 Hz要远高于载波频率且满足奈奎斯特采样carrierFrequency/f c f_cfc​载波频率10000 Hz必须小于f s / 2 f_s/2fs​/2symbolRate/R s R_sRs​符号率200 Baud决定每秒发送多少个 QPSK 符号rolloff/α \alphaαRRC 滚降系数0.5影响频谱占用与时域拖尾filterSpanRRC 滤波器跨度10单位是符号数phaseOffset星座整体相位偏移π / 4 \pi/4π/4QPSK 常用设置每符号采样点数为s p s f s R s 96000 200 480 \mathrm{sps} \frac{f_s}{R_s} \frac{96000}{200} 480spsRs​fs​​20096000​480也就是说每个 QPSK 符号在离散波形中由 480 个采样点表示。这里有一个很重要的约束sampleRate / symbolRate必须是整数。否则每个符号无法对应固定数量的采样点后续上采样和脉冲成形都会变得不一致。4. 一段可以直接运行的 MATLAB 代码把下面代码保存为项目根目录下的examples/demo_qpsk_to_wav.m或者直接在 MATLAB 命令窗口逐段运行。%% MATLAB 生成 QPSK 水声通信发射波形并写入 WAVclear;clc;close all;% 1) 将项目源码加入 MATLAB 路径addpath(src);% 2) 固定随机种子保证每次结果可复现rng(2026);% QPSK 每 2 bit 映射成 1 个符号所以 bit 数必须是偶数numberOfBits256;bitsrandi([01],1,numberOfBits);% 3) 设置发射端参数optionsstruct(...sampleRate,96000,...% fs96 kHzcarrierFrequency,10000,...% fc10 kHzsymbolRate,200,...% Rs200 Baudrolloff,0.5,...% RRC 滚降系数filterSpan,10,...% 滤波器跨度单位为符号数phaseOffset,pi/4);% QPSK 默认相位偏移% 4) 比特流 - QPSK 星座映射 - RRC 成形 - 实值通带波形[waveform,info]QPSK(bits,options);% 5) 写入 WAV 文件outputFileqpsk_10kHz_200baud.wav;audiowrite(outputFile,waveform,info.sampleRate);% 6) 打印本次生成的信息fprintf(调制方式%s\n,info.modulation);fprintf(输入 bit 数%d\n,numel(info.bits));fprintf(QPSK 符号数%d\n,numel(info.symbols));fprintf(采样率%.0f Hz\n,info.sampleRate);fprintf(载波频率%.0f Hz\n,info.carrierFrequency);fprintf(符号率%.0f Baud\n,info.symbolRate);fprintf(每符号采样点数%.0f\n,info.sampleRate/info.symbolRate);fprintf(时长%.3f s\n,info.durationSeconds);fprintf(输出文件%s\n,outputFile);% 7) 绘制 QPSK 星座图figure(Color,w);plot(real(info.symbols),imag(info.symbols),bo,MarkerFaceColor,b);axis equal;grid on;xlabel(I 路);ylabel(Q 路);title(QPSK 星座图);% 8) 绘制时域波形展示前 40 mst(0:numel(waveform)-1)/info.sampleRate;figure(Color,w);plot(t*1e3,waveform,b);xlim([0,min(40,t(end)*1e3)]);grid on;xlabel(时间 / ms);ylabel(归一化幅度);title(QPSK 实值通带波形);% 9) 绘制频谱nfft2^nextpow2(numel(waveform));n0:numel(waveform)-1;window0.5-0.5*cos(2*pi*n/(numel(waveform)-1));% Hann windowspectrumfft(waveform(:)..*window,nfft);spectrumabs(spectrum(1:nfft/21));spectrumDb20*log10(spectrum/max(spectrum)1e-8);f(0:nfft/2)*info.sampleRate/nfft;figure(Color,w);plot(f/1000,spectrumDb,LineWidth,1.2);xline(info.carrierFrequency/1000,--r,10 kHz carrier);grid on;xlim([0,20]);ylim([-80,5]);xlabel(频率 / kHz);ylabel(归一化幅度 / dB);title(QPSK 发射波形频谱);运行后会得到一个 WAV 文件qpsk_10kHz_200baud.wav这个文件本质上是一段实值声学通带波形。如果后面接声卡、功放和换能器就可以作为发射端测试信号如果只做课程设计或仿真也可以把它作为后续信道、同步、解调模块的输入。5. QPSK 和 BPSK 的关键区别很多同学第一次从 BPSK 写到 QPSK 时容易把“比特率”和“符号率”混在一起。BPSK1 symbol 1 bit 1\ \text{symbol} 1\ \text{bit}1symbol1bitQPSK1 symbol 2 bits 1\ \text{symbol} 2\ \text{bits}1symbol2bits所以如果符号率都是 200 Baud调制方式每符号 bit 数符号率理论比特率BPSK1 bit/symbol200 Baud200 bit/sQPSK2 bit/symbol200 Baud400 bit/s这里的“理论比特率”只考虑调制映射本身没有计算帧头、导频、保护间隔、纠错编码等开销。在真实水声通信系统里QPSK 不一定总是比 BPSK 更好。QPSK 的频谱效率更高但对相位估计、同步和信道条件也更敏感。水声信道里常见的多径、多普勒和低信噪比都会让 QPSK 解调更难。所以比较合理的学习顺序是BPSK 发射波形 ↓ QPSK 发射波形 ↓ 加入信道、多径和噪声 ↓ 做同步、解调和 BER 分析6. 为什么输入 bit 数必须是偶数因为 QPSK 每 2 bit 组成 1 个符号。例如0 1 1 0 0 0 1 1可以分成01, 10, 00, 11但如果输入 bit 数是奇数0 1 1 0 0最后一个0没有办法和另一个 bit 组成完整的 QPSK 符号。项目中的底层函数会检查这个条件。如果 bit 数不能被 2 整除会报类似下面的错误Input length must be divisible by 2.解决方法也很简单生成 bit 流时保证numberOfBits是偶数例如 128、256、512或者在实际数据末尾补 0再在接收端根据帧长度去掉补零。7. 为什么频谱集中在 10 kHz 附近本文设置了carrierFrequency,10000这表示把复基带 QPSK 信号上变频到 10 kHz 附近。如果只看基带信号它的频谱会围绕 0 Hz 展开上变频之后频谱会搬移到载波频率附近因此图中主能量集中在 10 kHz 附近。这也是水声通信发射端常见的处理方式先在基带完成符号映射和脉冲成形再搬移到换能器适合工作的声学频段。8. 为什么还要做归一化WAV 文件通常希望音频样本落在[-1, 1]范围内。如果幅度超过这个范围写入或播放时可能产生削波如果幅度太小则播放能量不足后续实验信噪比可能偏低。这个项目在生成实值通带波形时已经做了峰值归一化。也就是说QPSK函数输出的waveform通常已经适合直接写入 WAVaudiowrite(outputFile,waveform,info.sampleRate);如果你后面要自己叠加前导、静音段、多路信号或做功率控制建议在最终写 WAV 前再统一检查一次max(abs(waveform))如果结果大于 1就需要重新归一化或降低增益。9. 常见问题9.1sampleRate / symbolRate为什么必须是整数因为离散仿真里通常用固定数量的采样点表示一个符号。例如本文fs 96000 Hz Rs 200 Baud sps fs / Rs 480这表示每个 QPSK 符号占 480 个采样点。如果设置成struct(sampleRate,96000,symbolRate,333)那么96000 / 333 288.288...不是整数。这样每个符号到底占多少个采样点就不清楚了所以项目会直接报错。9.2 载波频率能不能随便设不能。首先要满足奈奎斯特采样f c f s 2 f_c \frac{f_s}{2}fc​2fs​​本文采样率是 96 kHz因此理论上载波频率必须小于 48 kHz。其次水声实验还要考虑换能器、功放和水池环境的实际频段。比如你设置了 30 kHz但换能器在这个频段效率很低实际发射效果可能就不好。9.3 QPSK 的phaseOffset pi/4是必须的吗不是必须但很常用。如果设置为 0星座点会落在 I/Q 坐标轴上如果设置为pi/4星座点会整体旋转 45°。在本项目中QPSK.m默认把phaseOffset设为pi/4defaultsauc.common_options();defaults.phaseOffsetpi/4;如果你想观察不同相位偏移对波形和星座的影响可以把它改成phaseOffset,0然后重新运行并比较星座图。9.4 QPSK 生成的 WAV 能直接听吗可以播放但不一定适合“人耳听”。本文载波频率是 10 kHz属于较高频段。电脑扬声器或普通耳机不一定能稳定输出更不用说真实水声实验还需要换能器。所以这里的 WAV 更准确地说是“可保存、可播放、可作为发射链路输入的数字波形文件”而不是普通意义上的音乐或语音文件。10. 可以继续扩展什么这篇只讨论 QPSK 发射端波形生成。后面可以继续做加入 AWGN 噪声观察星座点扩散加入多径信道观察码间干扰写 QPSK 相干解调做载波同步和符号同步统计不同 SNR 下的 BER比较 BPSK、QPSK、8PSK、QAM 的频谱效率和误码率。如果是通信原理课程设计可以把题目写成基于 MATLAB 的 QPSK 水声通信发射波形生成与频谱分析如果想做得更完整可以进一步扩展成基于 MATLAB 的 QPSK 水声通信收发链路仿真与误码率分析11. 项目链接本文代码对应的开源项目https://github.com/ZoperIOT/underwater-acoustic-modulation当前项目主要覆盖水声通信发射端波形生成包括 BPSK、QPSK、8PSK、QAM、DSSS 和 OFDM 等调制方式。本文重点讲 QPSK如何从 bit 流生成复基带符号再生成可以写入 WAV 的实值通带波形。如果你正在做通信原理课程设计、水声通信仿真入门或者想找一个 MATLAB 调制波形生成项目作为起点可以先从 BPSK 和 QPSK 这两篇开始跑通。