MATLAB生成BPSK水声通信发射波形:从比特流到WAV文件
2026/6/25 16:07:54 网站建设 项目流程

MATLAB生成BPSK水声通信发射波形:从比特流到WAV文件

关键词:MATLAB BPSK、水声通信仿真、BPSK WAV、载波频率、采样率、符号率、通信原理课程设计

水声通信的发射端,最容易被低估的一步是:把 0/1 比特真正变成一条可播放、可写入 WAV 的实值声学波形。

这篇文章用一个可复现的 MATLAB 项目,从随机比特流出发,生成带根升余弦脉冲成形的 BPSK 通带波形,并保存为 WAV 文件。本文只讨论发射端;同步、解调、信道估计和 BER 属于接收端工作,不在本文范围内。在这里插入图片描述

本文配套项目:ZoperIOT/underwater-acoustic-modulation

1. BPSK 在水声通信中做什么?

BPSK(Binary Phase Shift Keying,二进制相移键控)用两个相位表示 1 bit 信息。最常见的映射可以写成:

b k ∈ { 0 , 1 } ⟶ a k = 2 b k − 1 ∈ { − 1 , + 1 } b_k \in \{0,1\}\quad\longrightarrow\quad a_k = 2b_k-1 \in \{-1,+1\}bk{0,1}ak=2bk1{1,+1}

映射后的符号先经过根升余弦(RRC)脉冲成形,再与载波相乘,得到实值通带信号。写成连续时间形式,可理解为:

s ( t ) = ℜ { ∑ k a k g ( t − k T s ) e j 2 π f c t } s(t)=\Re\left\{\sum_k a_k g(t-kT_s)e^{j2\pi f_c t}\right\}s(t)={kakg(tkTs)ej2πfct}

其中g ( t ) g(t)g(t)是脉冲成形滤波器,T s = 1 / R s T_s=1/R_sTs=1/Rs是符号周期,f c f_cfc是载波频率。

对初学者来说,BPSK 是很好的发射端起点:映射清楚、波形直观,也便于后续扩展到 QPSK、QAM 或 OFDM。

2. 环境与项目准备

  1. 下载或克隆项目:underwater-acoustic-modulation。
  2. 在 MATLAB 中将当前目录切到项目根目录。
  3. src加入路径。

项目只使用 MATLAB 基础数值函数;RRC 滤波器已经包含在仓库内,不依赖 Communications Toolbox。

3. 先理解这 4 个参数

下面的配置是项目中适合先跑通的起点:96 kHz 采样率、10 kHz 载波、200 Baud 符号率。

参数含义本文取值设置时的硬约束 / 建议
sampleRate/f s f_sfs每秒采样点数96000 HzsampleRate / symbolRate必须是整数
carrierFrequency/f c f_cfc声学载波频率10000 Hz必须小于f s / 2 f_s/2fs/2,且要落在换能器可用频段
symbolRate/R s R_sRs每秒发送符号数200 Baud越高越快,但带宽需求和多径敏感性通常也会上升
rolloff/α \alphaαRRC 滚降系数0.5取值范围为 0 到 1,影响带宽与时域拖尾

本例的每符号采样点数为:

s p s = f s R s = 96000 200 = 480 \mathrm{sps}=\frac{f_s}{R_s}=\frac{96000}{200}=480sps=Rsfs=20096000=480

也就是说,每个 BPSK 符号在离散波形中用 480 个采样点表示。项目会检查这个值是否为整数;不满足时会直接报错,避免生成时间轴不一致的波形。

4. 一段可直接运行的 MATLAB 代码

将下面代码保存为项目根目录下的examples/demo_bpsk_to_wav.m,或直接在命令窗口逐段运行。

%% MATLAB 生成 BPSK 水声通信发射波形,并写入 WAVclear;clc;close all;% 1) 将项目源码加入 MATLAB 路径addpath('src');% 2) 固定随机种子,保证每次生成的比特流可复现rng(2026);numberOfBits=256;bits=randi([01],1,numberOfBits);% 3) 设置发射端参数options=struct(...'sampleRate',96000,...% fs:96 kHz'carrierFrequency',10000,...% fc:10 kHz'symbolRate',200,...% Rs:200 Baud'rolloff',0.5,...% RRC 滚降系数'filterSpan',10,...% 滤波器跨度(符号数)'phaseOffset',0);% 初始载波相位% 4) 比特流 -> RRC 成形 -> BPSK 实值通带波形[waveform,info]=BPSK(bits,options);% 5) 写入标准 WAV 文件outputFile='bpsk_10kHz_200baud.wav';audiowrite(outputFile,waveform,info.sampleRate);% 6) 在命令窗口查看本次生成的信息fprintf('调制方式:%s\n',info.modulation);fprintf('采样率:%.0f Hz\n',info.sampleRate);fprintf('载波频率:%.0f Hz\n',info.carrierFrequency);fprintf('符号率:%.0f Baud\n',info.symbolRate);fprintf('时长:%.3f s\n',info.durationSeconds);fprintf('输出文件:%s\n',outputFile);% 7) 绘制时域波形(展示前 35 ms)t=(0:numel(waveform)-1)/info.sampleRate;figure('Color','w');plot(t*1e3,waveform,'b');xlim([0,min(35,t(end)*1e3)]);grid on;xlabel('时间 / ms');ylabel('幅度');title('BPSK 水声通带波形(前 35 ms)');% 8) 绘制归一化频谱nfft=2^nextpow2(numel(waveform));% 手写 Hann 窗,避免额外工具箱依赖n=0:numel(waveform)-1;window=0.5-0.5*cos(2*pi*n/(numel(waveform)-1));X=fft(waveform.*window,nfft);f=(0:nfft/2)*info.sampleRate/nfft;magdB=20*log10(abs(X(1:nfft/2+1))/max(abs(X))+eps);figure('Color','w');plot(f/1e3,magdB,'LineWidth',1.2);xlim([0,20]);ylim([-100,5]);grid on;xlabel('频率 / kHz');ylabel('归一化幅度 / dB');title('BPSK 水声通带波形频谱');

运行后会在当前目录得到:

bpsk_10kHz_200baud.wav

该 WAV 的采样率为 96 kHz,样本为已归一化的双精度实值信号,范围在[-1, 1]内。

5. 代码内部实际发生了什么?

项目中的BPSK(bits, options)做了四件事:

  1. 检查bits是否仅包含 0 和 1;
  2. 2 * bits - 1映射到-1/+1
  3. 进行 RRC 脉冲成形;
  4. 乘以复载波并取实部,最后按峰值归一化为实值通带波形。

归一化的作用是把波形峰值控制在[-1,1]:一方面满足audiowrite的常用浮点输入范围,另一方面避免后续写入 DAC 或音频链路时因幅度过大而削顶。注意,归一化不等于完成了硬件幅度标定;真正接功放和换能器时,仍需按设备的满量程、增益和安全声压校准。

6. 波形和频谱应该怎么看?

上图是同一组参数下的教学示意。你运行上一节的 MATLAB 脚本后,会得到由当前比特流和项目 RRC 成形器生成的本机精确波形与频谱。

时域图中能看到 10 kHz 附近的快速振荡,而符号切换处的包络并不是生硬跳变——这是 RRC 脉冲成形带来的结果。频谱图的能量集中在 10 kHz 载波附近。

对滚降系数为α \alphaα的理想升余弦系统,基带单边带宽可用下面的近似关系理解:

B ≈ ( 1 + α ) R s 2 B\approx \frac{(1+\alpha)R_s}{2}B2(1+α)Rs

本例R s = 200 R_s=200Rs=200Baud、α = 0.5 \alpha=0.5α=0.5,因此主能量大致围绕 10 kHz 在数百 Hz 的窄带范围内展开。实际频谱还会受到有限长度、窗函数和滤波器截断的影响。

7. 三个高频问题

7.1 为什么sampleRate / symbolRate不能随便设?

该项目的单载波波形按“每符号固定采样点数”进行上采样和脉冲成形。因此sampleRate / symbolRate必须是整数,且至少为 2。例如:

% 合法:96000 / 200 = 480struct('sampleRate',96000,'symbolRate',200)% 不合法:96000 / 333 不是整数struct('sampleRate',96000,'symbolRate',333)

如果想把Rs调高,建议优先从能整除fs的值选起,例如在 96 kHz 下尝试 400、600、800、1200 Baud。

7.2 载波频率为什么不能乱设?

最基本的数字信号约束是:

0 < f c < f s 2 0<f_c<\frac{f_s}{2}0<fc<2fs

否则会混叠。但满足奈奎斯特条件只是第一步。水声实验还要检查换能器频响、功放带宽、DAC/ADC 采样率以及水下声道在该频段的衰减。

7.3 为什么不能直接用方波符号上载波?

可以,但频谱旁瓣通常更宽。RRC 脉冲成形的价值在于控制占用带宽,并为后续接收端的匹配滤波和定时恢复保留更规范的接口。对于课程设计或实验记录,它也让波形从“能响”走向“可分析”。

8. 下一步可以怎么扩展?

完成 BPSK 发射端后,可以按下面顺序继续:

  1. BPSK替换为QPSK,观察每符号 2 bit 时的比特分组约束;
  2. 比较不同rolloffsymbolRate下的频谱占用;
  3. 使用项目的OFDM入口生成导频辅助 QPSK-OFDM 发射波形;
  4. 加入预导、同步、信道、多径和接收端解调,形成完整链路。

项目地址再次放在这里:https://github.com/ZoperIOT/underwater-acoustic-modulation。如果你是在做通信原理课程设计,建议先把本节的 BPSK WAV 生成、时域图和频谱图跑通,再往接收端扩展;每一步都会更容易定位问题。


本文代码对应项目的 BPSK 发射端实现。默认参数可在仓库src/+auc/common_options.m中查看;不同硬件条件下,请以实际设备规格为准。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询