news 2026/10/1 1:19:08

BPSK调制解调MATLAB仿真全解析:从成型滤波到误码率验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
BPSK调制解调MATLAB仿真全解析:从成型滤波到误码率验证

简介:BPSK调制解调仿真MATLAB代码,面向通信原理和信号处理学习者,完整覆盖随机序列生成、双极性变换、上采样、成型滤波、载波调制、加高斯白噪声、相干解调、低通滤波、匹配滤波和抽样判决等全链路环节。包内含5个文件:四个M脚本(主程序、低通滤波、升余弦滚降滤波、双边单片频谱绘制)和一个文本说明,压缩包仅5KB,轻量易用。目前已有3973人浏览学习。代码注释非常详细,可输出时域波形、功率谱、频谱图、抽样后星座图、眼图以及理论与仿真误码率曲线;通过将EB/N0设为单个值即可直观查看所有中间过程图谱。代码在MATLAB 2018和2023版本均可无错运行,适合课程设计、仿真实验或自学理解BPSK调制解调原理及成型滤波、匹配滤波的作用。

1. BPSK调制解调仿真:超详细的MATLAB实现解析

BPSK(二进制相移键控)是数字通信里最基础的调制方式,也是很多通信工程从业者第一次在MATLAB里完整跑通「比特流→基带波形→射频/中频信号→加噪声→解调→判决→误码率统计」全链路的起点。但说实话,网上能搜到的BPSK仿真代码大多只给一个调制函数加一个解调函数,中间缺了成型滤波、匹配滤波、载波同步、定时恢复这些真正决定系统性能的环节,跑出来的星座图乱成一团,误码率曲线跟理论值对不上,也不知道问题出在哪。这篇文章把这份超详细的BPSK调制解调仿真代码拆开,从系统参数设定到滤波器的每一行代码实现,再到常见的翻车点排查,保证你拿到代码后能跑通、能看懂、能改参数,也能把仿真结果跟课本上的理论曲线对齐。适合正在做通信原理课程设计的学生,也适合需要用MATLAB做通信系统预研的工程师。

2. 仿真架构与参数预设:先把系统链路和数值关系理顺

2.1 参数之间不是独立的:采样率、符号速率与载波频率的约束

BPSK仿真的第一步不是写代码,是定参数。很多新手直接拿一个随机比特序列,乘以cos(2πft)就算完事,结果出来的频谱混叠得一塌糊涂,原因就是符号速率、采样率、载波频率三者之间没有遵循基本的数值约束。

我一般把系统参数集中放在脚本头部,用注释标明每个参数的作用,这样后面改起来不用满文件找。核心参数包括:

  • 符号速率Rs:决定每秒传多少个BPSK符号,通常取 1000 或 10000 这类好算的数
  • 采样率Fs:必须远大于符号速率,工程上常见取Fs/Rs为 8~32 之间的整数,这个比值叫过采样率sps(samples per symbol)
  • 载波频率Fc:必须小于Fs/2,否则不满足奈奎斯特采样定理;同时Fc最好也满足Fc/Rs是整数或简单分数,便于仿真时离散频率对齐
% BPSK仿真系统参数设定 Rs = 1000; % 符号速率(符号/秒),决定仿真中每个符号的持续时间 sps = 16; % 过采样率,每个符号采16个点 Fs = Rs * sps; % 采样率 = 符号速率 × 过采样率,即16000 Hz Fc = 4000; % 载波频率,必须小于 Fs/2 = 8000 Hz numSymbols = 1000; % 仿真符号总数,用于统计误码率 snrRange = 0:2:12; % SNR扫描范围(dB),从0到12,步进2 % 由这些参数推导出的时间轴和频率分辨率 t = (0:numSymbols*sps-1) / Fs; % 总仿真时间轴,单位秒

参数说明:这里的sps=16意思是每个符号采样16个点,这是给成型滤波器留出足够的频谱余量。如果sps太小,比如等于2,成型滤波器的过渡带会跟相邻频谱镜像重叠,滤波效果大打折扣。Fc=4000选在采样率的四分之一处,保证信号频谱有足够的频带放置,又不至于离采样率边界太近。

2.2 整体仿真框架:从随机比特到误码率统计的主循环

完整的BPSK仿真不是一个孤立的调制函数,而是一条分阶段的主链路。我把框架写成四个阶段:发射端(比特生成→符号映射→成型滤波→上变频)、信道(加AWGN噪声)、接收端(下变频→匹配滤波→采样判决)、分析端(误码率计算与绘图)。

下面是主框架代码,为了便于理解,我先给出不带滤波器的简化版本,等下一章再插入成型滤波和匹配滤波的完整实现。

% BPSK仿真主循环:扫描多个SNR点,统计每个点的误码率 berResults = zeros(size(snrRange)); % 存储每个SNR下的误码率 bitErrorsTotal = zeros(size(snrRange)); for snrIdx = 1:length(snrRange) snr = snrRange(snrIdx); % 1. 生成随机比特流,长度=符号数(BPSK每符号1比特) dataBits = randi([0 1], numSymbols, 1); % 2. 比特映射:0 -> -1,1 -> +1(BPSK的两种相位状态) symbols = 2 * dataBits - 1; % 3. 上采样:每个符号按过采样率扩展成脉冲序列 txSignalBaseband = upsample(symbols, sps); % 4. 上变频到载波频率:乘cos(2πFc t) txSignal = real(txSignalBaseband .* exp(1j*2*pi*Fc*t.')); % 5. 加高斯白噪声,噪声功率由SNR决定 rxSignal = awgn(txSignal, snr, 'measured'); % 6. 下变频回基带 rxBaseband = rxSignal .* exp(-1j*2*pi*Fc*t.'); % 7. 匹配滤波(这里先用最简单的矩形窗,第3章替换为RRC) % 8. 降采样:每个符号取中间采样点作为判决值 rxSymbols = rxBaseband(1:sps:end); % 9. 判决:实部大于0判为+1(即原始比特1),否则判为-1 rxBits = real(rxSymbols) > 0; % 10. 统计误码 bitErrorsTotal(snrIdx) = sum(dataBits ~= rxBits); berResults(snrIdx) = bitErrorsTotal(snrIdx) / numSymbols; end % 理论误码率:Q(sqrt(2*SNR_linear)),作为对照曲线 snrLinear = 10.^(snrRange/10); berTheory = 0.5 * erfc(sqrt(snrLinear));

这段代码的逻辑说明:核心思路是把每个SNR点独立跑一遍完整的收发链路,用瑞利分布以外的AWGN信道模型,awgn函数会自动按当前信号功率计算噪声功率。第7步的匹配滤波我用注释留了位置,因为矩形窗匹配滤波在无成型滤波时等效于直接降采样,不影响结果;下一章换成RRC滤波器后就不能这样直接降采样了,需要先滤波再降采样,时序要对齐。第8步的1:sps:end是降采样操作,从每个符号的16个采样点里取一个。这里注意dataBits ~= rxBits的比较方法是逐元素比较逻辑向量,得到的是逻辑值向量,sum之后就是误差个数。

3. 成型滤波与匹配滤波:BPSK信号频谱成型的核心环节

3.1 不滤波的后果:信号频谱旁瓣过大,邻道干扰直接拉高误码率

如果你跑过第2章的简化代码,会发现误码率曲线跟理论值基本能对上,因为AWGN信道下矩形脉冲本身就是匹配的。但如果你把这个信号频谱画出来,会看到旁瓣衰减很慢——矩形脉冲的频谱是sinc函数,第一旁瓣只比主瓣低约13dB。在真实系统中这意味着能量泄漏到相邻频带,对邻道造成干扰。所以在发送端必须加成型滤波,把信号频谱限制在需要的带宽内。

BPSK成型滤波最常用的选择是升余弦(Raised Cosine,RC)滤波器或根升余弦(Root Raised Cosine,RRC)滤波器。RC滤波器在接收端直接做匹配滤波即可;RRC滤波器则是发射端和接收端各放一个,两个根升余弦级联后等价于一个升余弦滤波器,这在工程上更常用,因为收发两端各分担一半的频谱成型任务。

3.2 用 rcosdesign 设计RRC滤波器:滚降因子和滤波器长度的选择

MATLAB通信工具箱里的rcosdesign函数可以直接生成RRC滤波器系数,一行代码搞定,但参数怎么选是有讲究的。滚降因子 β 决定频谱过渡带的宽度:β 越小过渡带越窄、带宽利用率越高,但对定时误差和载波偏移越敏感;β 越大过渡带越宽、实现越容易,但频谱占用也越大。工程上 β 通常在 0.2~0.5 之间取,我一般取 0.35,折中效果好。

% 设计RRC成型滤波器 beta = 0.35; % 滚降因子,0.2~0.5之间取,0.35是常用折中值 filterSpan = 8; % 滤波器截断长度,单位是符号周期 rrcFilter = rcosdesign(beta, filterSpan, sps, 'sqrt'); % 查看滤波器频响 fvtool(rrcFilter, 'Analysis', 'freq'); % 打开滤波器可视化工具查看频率响应

代码逻辑说明:rcosdesign的第三个参数sps必须是整数,表示每个符号的采样点数;'sqrt'指定生成根升余弦滤波器。filterSpan=8表示滤波器截断为8个符号周期,总长度是filterSpan*sps+1 = 8*16+1 = 129个抽头。抽头太少会让滤波器频响跟理想RRC偏差大,抽头太多则增加计算量。实际使用中filterSpan在 6~12 之间居多,低于6的话滤波器阻带衰减不够,高于12收益很小但计算开销线性增长。

这里有个关键操作:滤波前需要做上采样,滤波后信号会有一个群延迟,延迟量为filterSpan*sps/2个采样点,后面匹配滤波和降采样时要把这个延迟补偿掉,否则星座图会有明显的相位旋转。

% 发射端:基带符号序列经过上采样和RRC成型滤波 txUpsampled = upsample(symbols, sps); % 插零上采样,每个符号间补 sps-1 个零 txFiltered = filter(rrcFilter, 1, txUpsampled); % 成型滤波:卷积上采样后的脉冲序列 % 补偿滤波器延迟,保证脉冲"中心"对齐到采样网格 filterDelay = filterSpan * sps / 2; % 群延迟 = 截断符号数 × 每符号采样数 / 2 txCompensated = txFiltered(filterDelay+1:end); % 去掉前 filterDelay 个采样点

参数说明:upsample函数在每个符号后插入sps-1个零,形成脉冲序列。filter函数做的是FIR滤波,等效于序列与滤波器系数的卷积。延迟补偿的数学原理是:线性相位FIR滤波器的群延迟恒为(N-1)/2个采样点,其中 N 是滤波器抽头数;对于rcosdesign生成的滤波器,群延迟恰好是filterSpan*sps/2。不补偿的话,后续判决时采样点偏离脉冲峰值,幅度衰减且相位偏移,误码率会明显恶化。

3.3 接收端匹配滤波:根升余弦的第二次滤波

接收端的匹配滤波原则是:当发射端用了RRC成型,接收端必须再经过一个相同的RRC滤波器,两个RRC级联等效于一个RC滤波器,此时在符号采样点上的信号幅度最大,噪声功率被最小化。这就是匹配滤波器的物理含义——让信号分量增强、噪声分量通过频率响应被抑制。

% 接收端:匹配滤波,使用与发射端相同的RRC滤波器 rxMatched = filter(rrcFilter, 1, rxBasebandCompensated); % 匹配滤波后再补偿一次延迟(接收端滤波器同样有群延迟) rxMatchedComp = rxMatched(filterDelay+1:end); % 降采样:每个符号取1个判决点 rxSymbols = rxMatchedComp(1:sps:end); % 判决 rxBits = real(rxSymbols) > 0;

这里需要特别注意的是延迟补偿做两次:发射端做一次,接收端再做一次。很多简化教程里把降采样点的选取写成rxMatched(delay+1:sps:end)或者直接在滤波前就补偿,两种做法都对,但计算方式要一致。我习惯的做法是发送端补偿完再上变频、接收端下变频后再补偿一次,相当于在整个链路里统一了时间基准。

参数上还有个容易被忽略的点:filter函数默认不缩放滤波器增益,rcosdesign设计出来的滤波器在通带内增益约为sqrt(sps),也就是说信号经过RRC滤波后幅度会被放大。如果你在仿真中对比发射功率,需要关心这一点;好在awgn函数用'measured'选项会自动测实际信号功率,不会因为增益造成SNR偏差。

4. 完整收发链路与判决逻辑:把成型滤波匹配滤波融进主循环

4.1 上变频与下变频的实现细节

基带信号要搬到载波频率上去传输,这一步叫上变频;接收端再乘同频同相的载波搬回来,叫下变频。MATLAB里最直接的做法是用复指数exp(1j*2*pi*Fc*t)相乘再取实部。

% 上变频:将基带信号调制到载波 Fc txSignal = real(txCompensated .* exp(1j*2*pi*Fc*t.')); % 注意:这里 t 是列向量,txCompensated 也是列向量,逐元素相乘不需要转置 % 信道:加AWGN rxSignal = awgn(txSignal, snr, 'measured'); % 下变频:恢复基带信号,乘共轭复指数 rxBaseband = rxSignal .* exp(-1j*2*pi*Fc*t.');

参数说明:t.'是转置,保证时间轴是列向量,与信号向量维度一致。上变频取实部是因为实际信道传输的物理信号是实信号;下变频后得到复数基带信号,实部是I路、虚部是Q路,BPSK只用实部判决。这里有个关键点:上下变频的载波必须同频同相,这就是「相干解调」的条件。仿真中我们理想化地假设载波同步完全准确,实际系统中需要PLL等载波恢复电路来解决频率和相位偏移。

如果把Fc取得太低,比如Fc=100而符号速率Rs=1000,那么每个符号周期内只过了0.1个载波周期,波形上根本看不出相位变化,这种参数组合毫无意义。我一般保证每个符号周期内至少有几个完整的载波周期,即Fc/Rs至少大于3。

4.2 完整主循环:整合所有模块的代码

现在把第2章的主循环替换成带成型滤波和匹配滤波的完整版本。

% BPSK完整仿真主循环(含成型滤波与匹配滤波) % 系统参数 Rs = 1000; % 符号速率 sps = 16; % 每符号采样点数 Fs = Rs * sps; % 采样率 Fc = 4000; % 载波频率 numSymbols = 2000; % 仿真符号数,增大以减小BER统计波动 snrRange = 0:2:12; % SNR范围 beta = 0.35; % 滚降因子 filterSpan = 8; % 滤波器截断符号数 % 生成RRC滤波器 rrcFilter = rcosdesign(beta, filterSpan, sps, 'sqrt'); filterDelay = filterSpan * sps / 2; % 时间轴 t = (0:numSymbols*sps-1)' / Fs; % 预分配 berResults = zeros(size(snrRange)); for snrIdx = 1:length(snrRange) snr = snrRange(snrIdx); % 发射端 dataBits = randi([0 1], numSymbols, 1); symbols = 2 * dataBits - 1; txUpsampled = upsample(symbols, sps); txFiltered = filter(rrcFilter, 1, txUpsampled); txCompensated = txFiltered(filterDelay+1:end); % 上变频 txSignal = real(txCompensated .* exp(1j*2*pi*Fc*t)); % 信道 rxSignal = awgn(txSignal, snr, 'measured'); % 接收端 rxBaseband = rxSignal .* exp(-1j*2*pi*Fc*t); rxMatched = filter(rrcFilter, 1, rxBaseband); rxMatchedComp = rxMatched(filterDelay+1:end); % 降采样与判决 rxSymbols = rxMatchedComp(1:sps:end); rxBits = real(rxSymbols) > 0; % 误码统计 berResults(snrIdx) = sum(dataBits ~= rxBits) / numSymbols; end

逻辑说明:txCompensated和rxMatchedComp的长度比原始采样序列短了filterDelay个点,这是因为滤波过程引入了延迟、我们从第filterDelay+1个点开始取。降采样时取1:sps:end的每个第16个点,对应每个符号周期的最后一个采样位置。之所以取最后一个而不是中间,是因为经过两次RRC滤波和延迟补偿后,脉冲峰值出现在符号周期的末尾采样点处——这个位置取决于滤波器和延迟补偿的具体方式。如果你换了filterSpan或sps,要重新验证采样点位置对不对,判断方法是做星座图:采样点收敛到 ±1 附近就说明对齐了,如果发散就说明偏了。

4.3 误码率统计的两种方式:直接计数与理论曲线对比

误码率统计要对比仿真值和理论值才可信。BPSK在AWGN信道下的理论误码率为:

$$P_b = Q\left(\sqrt{\frac{2E_b}{N_0}}\right) = \frac{1}{2}\text{erfc}\left(\sqrt{\frac{E_b}{N_0}}\right)$$

在MATLAB中直接用erfc计算理论曲线,跟仿真结果画在同一张图上。两者应该在大约0.5dB以内吻合,差别过大说明链路实现里有问题。

% 理论BER曲线计算 snrLinear = 10.^(snrRange/10); % 注意:awgn函数中snr的单位是dB,对应的是Eb/N0还是SNR取决于信号类型 % 对于基带实信号模型,awgn的SNR直接等于 Eb/N0 * (Rs/Fs) 的关系,这里按仿真设置处理 ebN0 = snrRange; % 简化处理:基带等效模型中SNR≈Eb/N0(当sps足够大且无滤波损耗时) berTheory = 0.5 * erfc(sqrt(10.^(ebN0/10))); % 画图对比 figure; semilogy(snrRange, berResults, 'bo-', 'LineWidth', 1.5); hold on; semilogy(snrRange, berTheory, 'r*-', 'LineWidth', 1.5); grid on; xlabel('SNR (dB)'); ylabel('BER'); legend('仿真值', '理论值', 'Location', 'southwest'); title('BPSK 误码率曲线对比');

这里有个常见的坑:awgn函数里的 SNR 和通信理论里的Eb/N0不是同一个量。awgn用的是信号总功率与噪声功率之比;Eb/N0是每比特能量与噪声功率谱密度之比。两者在数值上差一个带宽因子,只有当信号是单位能量的基带脉冲且采样率与符号速率的关系恰当时,数值才相近。如果仿真曲线整体右移或左移,优先检查是否把 SNR 直接当 Eb/N0 用了。严格的做法是先算 Eb/N0,再换算成 awgn 函数需要的 SNR 输入,公式为SNR = EbN0 + 10*log10(Rs/Fs),但这个换算是基于一定的信号模型假设的,实际中我更推荐直接用awgn的'measured'方式配合手动校准。

5. 避坑排查:BPSK仿真中常见的五个翻车点

5.1 星座图旋转了45度

现象:接收判决点的实部和虚部都有值,星座图整体旋转了一个角度,不再是干净的±1两点。

原因:上变频和下变频的载波相位不一致。如果你在接收端直接乘exp(-1j*2*pi*Fc*t),而发射端用的也是exp(1j*2*pi*Fc*t),理论上相位是同步的。但如果你在发射端用了cos(2*pi*Fc*t)作为载波,在接收端用cos(2*pi*Fc*t)做解调,就会产生一个相差45度或90度的旋转——因为cos是实信号,实际等价于(exp(j*2*pi*Fc*t) + exp(-j*2*pi*Fc*t))/2的实部,混频后会带来镜像分量。

解决:统一用复指数形式exp(1j*2*pi*Fc*t)做上下变频。这是仿真和实际系统最大的差异之一——仿真里没有真实的振荡器,镜像频率可以直接舍去,但实信号混频的公式如果不加低通滤波就会把镜像混进来。最稳妥的做法是上变频用real(x .* exp(1j*2*pi*Fc*t)),下变频后用低通滤波器滤掉2倍载频分量,或者用第4章的复指数直接乘的方法——后者在数字域上天然不会产生镜像。

5.2 误码率在某几个SNR点突然崩坏

现象:BER曲线在低SNR区正常,到了高SNR区反而突然抬升。

原因:仿真符号数太少,高SNR下误码事件变成小概率事件比如千分之一,numSymbols=1000时理论上平均只发生1个错误,随机波动极大。比如SNR=12dB时理论BER约为 1e-8,仿真1000个符号几乎不可能出现错误,统计结果是0,画对数坐标时直接掉到负无穷。

解决:增加仿真符号数。SNR每增加2dB,BER降低一个数量级,为了统计到至少10~20个误码,符号数要按10 / BER来取。SNR=10dB时BER约1e-5,需要至少1e6个符号。仿真时间会长,但这是必要的。可以用每SNR点动态调整符号数:预判BER数量级,设置足够多的符号,或直接用berawgn函数对照。

5.3 眼图睁不开,采样点分布散乱

现象:画眼图时「眼睛」完全闭合,采样点不在眼图中央而是散布一片。

原因:最常见的是滤波器延迟补偿做错了。filterSpan*sps/2是理论群延迟,但如果同时在做上采样和滤波时对边界效应没处理,比如filter函数输出的前几个点是滤波器瞬态响应,直接把这些点也参与降采样就会引入大量偏差。另一种原因是没有做匹配滤波,直接用有成型滤波的信号降采样。

解决:先画出滤波前后信号的波形对比,用stem(t(1:100), txCompensated(1:100))观察脉冲形状。正确情况下,滤波后的脉冲在符号中心位置有最大幅度,边缘衰减平滑。然后把降采样点从1:sps:end改为delay+1:sps:end或者sps/2+1:sps:end逐一试算,看哪个位置让星座图最收敛。我用过最直接的技巧是:写一个循环,让降采样相位从1到sps遍历,统计每个相位下的星座图方差,方差最小的就是正确的采样相位。

5.4 滤波器增益导致信号幅度偏移

现象:带滤波的仿真误码率曲线比理论值差了好几个dB,星座图点虽然聚但不在±1上,而是±0.7或±1.5。

原因:rcosdesign生成的滤波器增益不是1。通带增益约为sqrt(sps),信号经过两个RRC级联后整体增益为sps倍。如果你在比较理论曲线时用的Eb/N0是基于单位能量信号算的,而实际信号功率是sps^2倍,SNR自然就偏了。

解决:归一化滤波器增益。设计完滤波器后除以它的通带增益:rrcFilter = rrcFilter / sum(rrcFilter) * sps;或用rrcFilter = rrcFilter / sqrt(sum(rrcFilter.^2)) * sqrt(sps);。我通常的做法是直接在滤波器设计完成后检查sum(rrcFilter)的值,再统一除以这个值,让滤波器的直流增益为1。

5.5 下变频后直流分量去除不干净

现象:频谱分析时看到0频附近有很强的分量,星座图的中心位置不在原点。

原因:上变频信号通过实信道传输后,下变频用复指数相乘,会把2倍载频分量保留在基带信号里,如果后续没有低通滤波处理,这些高频分量混入匹配滤波器后可能造成直流偏置,影响判决。

解决:在接收端加一个低通滤波器。低通滤波器的截止频率设为Fc + Rs/2以上但不能超过Fs/2,阶数取30~50即可。也可以直接在频域上截断:对rxBaseband做FFT后把超过Fc+Rs的频点置零再做IFFT,不过这会让信号保真度受到影响,不如直接设计一个FIR低通。

6. 进阶验证:用眼图、星座图和频谱图确认仿真可信度

仿真跑通了、BER曲线能对上了,这只是及格。真正让仿真结果「可信」的验证手段是同时看三种图形——眼图、星座图、频谱图——它们分别验证时域波形的质量、判决点聚集度和频域占用情况。这三个视图任何一个异常,都说明链路里还有没发现的问题。

眼图的做法是把接收端匹配滤波后的信号按符号周期分段叠加显示。MATLAB里没有直接画眼图的函数,但可以用reshape把基带信号重组成sps行、N列的矩阵,每列对应一个符号周期,画成二维线图即可。

% 画眼图:取匹配滤波后的基带信号,按符号周期分段 eyeLen = 100; % 画前100个符号周期的眼图 eyeMatrix = reshape(rxMatchedComp(1:eyeLen*sps), sps, eyeLen); plot(1:sps, eyeMatrix, 'b', 'LineWidth', 0.5); xlabel('采样点(一个符号周期内)'); ylabel('幅度'); title('BPSK 眼图(SNR=8dB)'); grid on;

眼图通过的标准是:在符号采样时刻眼图开口最大,左右两侧的轨迹聚拢成清晰的束。如果眼图开口小、轨迹散乱,大概率是定时同步或匹配滤波没做好。星座图则直接看判决点的分布,越靠近±1越好,如果看到明显的以原点为中心的旋转椭圆,说明载波相位残留了偏移。

频谱验证用pwelch函数画功率谱密度,观察信号的带宽和旁瓣衰减。

% 频谱验证:计算并绘制成型滤波后信号的功率谱 [psd, f] = pwelch(txCompensated, [], [], [], Fs); figure; plot(f, 10*log10(psd)); xlabel('频率 (Hz)'); ylabel('功率谱密度 (dB/Hz)'); title('BPSK 基带信号功率谱'); grid on; xlim([-Fs/2, Fs/2]);

频谱图上的预期结果是:主瓣宽度约为(1+beta)*Rs = 1.35*1000 = 1350 Hz,旁瓣滚降迅速,阻带衰减在40dB以上。如果旁瓣衰减不够,检查滤波器抽头数是否够多、滚降因子是否设置合理。

最后说一个我自己的习惯——也是踩过几次坑之后固化的流程:每次改参数后,先跑一个numSymbols=1e4的快速仿真看BER是否在理论值附近;如果偏离,先画星座图和眼图定位问题环节,而不是盲目调参数;确认无误后再把符号数放大到1e6跑最终曲线。这套流程看起来多花几分钟,实际上能避免好几次一跑就是半小时、最后发现是滤波器增益没归一化的返工。从那以后我每次做BPSK仿真都强制走一遍这个验证顺序,短期看是多做了两步,长期看省下的时间远多于浪费的。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 1:18:40

Win8.1老机器跑Steam:VxKex与nocef sandbox兼容方案实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 1:18:22

基尔霍夫电压定律KVL详解:参考方向、列方程与实测验证

很多人第一次接触电路,都会背下这样一句话:沿着任意闭合回路绕一圈,所有电压的代数和等于零。这就是基尔霍夫电压定律,通常简写成KVL。但真正做题、搭电路、拿万用表去验证的时候,你会发现,难的根本不是这句…

作者头像 李华
网站建设 2026/10/1 1:18:19

倩女幽魂大盗宝藏收益计算器:游戏经济建模与刷本决策优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 1:17:32

机械工程师面试高频考点:材料、热处理与公差实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 1:17:17

马德拉酒全解析:从“不死之酒”风味到品鉴配餐指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 1:17:11

扩展欧几里得算法全解析:从数学原理到RSA私钥计算与工程实践

扩展欧几里得算法这名字,听起来像是个只会在数学竞赛和密码学课本里出现的东西,但实际上我工作这些年,发现它的出场频率远比想象中高:做算法题求模逆元、写安全相关逻辑算 RSA 私钥、甚至解一个简单的不定方程找整数解&#xff0c…

作者头像 李华