☰
MATLAB直接序列扩频通信系统仿真:从m序列到抗干扰BER曲线的完整实现
2026/10/11 20:26:24 网站建设 项目流程

简介:面向通信工程、电子信息等专业毕业设计或课程作业的MATLAB直接序列扩频(DSSS)通信系统仿真源码包,完整覆盖扩频通信核心链路,包括PN/M序列与Walsh码生成、BPSK/QAM调制、频谱扩展与解扩、扰码解扰、AWGN及多径衰落信道模拟、误码率(BER)统计与结果绘图等环节。压缩包共26个文件,以24个.m脚本为主体,另有README.md和LICENSE,总大小仅12KB,模块划分清晰,主程序与调制解调、扩频解扩、扰码解扰、误码统计等模块各成独立脚本,方便对照流程阅读、修改参数和二次开发。目前已有141人学习/下载,在同类课程设计资源中有一定参考热度。通过这套代码,读者可以对照实现完整的DSSS发送-信道-接收流程,调整扩频比、信噪比、多径时延等参数观察系统性能变化,也可用作课程报告或毕业设计答辩的支撑材料,并深入体会扩频通信在抗干扰、安全性和多径环境下的实际优势。

1. 直接序列扩频通信系统仿真:为什么难的不是扩频,而是后面两步

“基于MATLAB的直接序列扩频通信系统仿真”这个题目,是通信类毕设和课程作业里的常客。我见过不少同学拿到手之后,第一件事是去翻通信原理课本,把扩频公式抄成注释,再用randn加噪声跑一条BER曲线就准备交差。实际做下来你会发现,扩频本身只需要几行代码,真正让整个通信系统仿真翻车的是扩频码同步、误码率统计口径和干扰建模这三件事。这篇笔记按可复现的顺序拆开讲,从m序列生成一路做到抗干扰对比,新手照着跑能出图,老手可以直接把代码改写成自己的毕设仿真链路。

这套方案解决的核心问题是:在纯软件环境里,把直接序列扩频的扩频、解扩、处理增益和抗窄带干扰特性完整演出来,不依赖任何硬件。适合通信工程、电子信息类专业做课程作业或本科毕设的同学,也适合想快速验证一个新扩频码性能的从业者。下面我按码序列层、扩频调制层、信道层、同步与判决层来组织内容,每层都给可运行的MATLAB代码和参数边界。先把m序列这件事做扎实,后面的坑会少一半。

2. DSSS仿真的核心模块与m序列选型:先把最小链路跑顺

直接序列扩频(DSSS)的系统结构其实很简单:发射端把信息比特乘上一个高速伪随机码序列,接收端用同一个码序列做相关解扩。但“简单”不等于“容易跑通”,因为仿真里每一步的参数选择都会影响后面整条链路。这一章先把三个基础模块讲清楚:为什么选DSSS、怎么生成m序列、怎么验证扩频码本身是对的。

2.1 课程作业为什么选DSSS而不是跳频:三种扩频体制的建模成本对比

扩频通信有三种常见体制:直接序列扩频、跳频扩频(FHSS)和跳时扩频(THSS)。课程作业里绝大多数选DSSS,不是因为它性能最好,而是因为它在MATLAB里的建模成本最低。DSSS可以用基带等效模型完成全部核心验证,连载波都不用显式仿真;跳频则需要同时仿真伪随机序列控制的频率跳变图案和接收端的频率合成,手写起来周期长,还容易在时频对齐上出问题。跳时更麻烦,它需要精确的时间同步,本科课程设计很少碰。

从仿真维度看,三者的差异很直观。我给一个自己常用的对比表,做选型时直接照这个思路判断:

扩频体制核心仿真对象MATLAB建模复杂度课程作业适配度
直接序列扩频扩频码、码片乘法、相关解扩低,基带离散序列即可高,重点突出处理增益
跳频扩频频率跳变图案、频率合成与同步中,需要多个载波支路中,代码量偏大
跳时扩频时间门控、精确时统高,同步模块复杂低,演示效果不直观

选DSSS还有一层原因:它的数学表达可以完全离散化。发射端码片序列是c(n)=d(n)·p(n),其中d(n)是双极性信息比特序列,p(n)是双极性扩频码;接收端做v(n)=r(n)·p(n)再积分判决。这两步在MATLAB里就是两次逐点乘法和一次求和,没有任何连续时间积分器,调试成本极低。理解这一点后,下面几节的代码就顺理成章了。

2.2 m序列生成的MATLAB实现:自己写LFSR而不是赌工具箱接口

m序列是直接序列扩频最常用的伪随机码,周期为2的n次方减1,由n阶本原多项式通过线性反馈移位寄存器(LFSR)生成。工程上最常见的配置是7阶m序列,周期127个码片,正好对应扩频因子127。注意,m序列是0/1序列,但扩频运算需要双极性信号,所以生成后要做一个映射:0变成-1,1变成+1。

很多教程直接调用通信工具箱的commpn,但不同MATLAB版本对这个函数的抽头参数传法有差异,换台电脑就可能报错。与其去查版本差异,不如自己写一个LFSR函数,十几行代码,行为完全可控,答辩时还能直接讲清楚寄存器反馈原理。下面这个函数我一直在用:

function mseq = lfsr_mseq(taps, init, N) % taps: 反馈抽头索引,例如7阶本原多项式 x^7+x^3+1 对应 taps=[7 3] % init: 初始状态向量,长度等于阶数,不能全为0 % N: 要输出的序列长度,工程上取 2^length(init)-1 n = length(init); period = 2^n - 1; reg = init(:); % 列向量,reg(1)是最左侧寄存器 mseq = zeros(1, period); for i = 1:period mseq(i) = reg(end); % 最右侧寄存器作为输出 fb = mod(sum(reg(taps)), 2); % 抽头异或后作为反馈 reg = [fb; reg(1:end-1)]; % 反馈值移入最左侧 end mseq = mseq(1:N); end

调用方式很简单。下面的代码生成一个周期127的m序列,并完成双极性映射:

init = ones(1,7); % 初始状态,七个寄存器都置1 mseq = lfsr_mseq([7 3], init, 127); mseq_bip = 2*mseq - 1; % 0->-1, 1->+1,扩频必须用双极性

逻辑说明:LFSR每个时钟周期把抽头位置的寄存器值异或后反馈到最左端,同时最右端输出一位,这样产生的序列周期是2的7次方减1等于127。taps=[7 3]对应本原多项式x^7+x^3+1,这是通信原理教材附录里常用的7阶本原多项式。参数说明:初始状态不能全为0,否则反馈永远为0,序列会卡死;N一般取完整周期长度,这样后面做扩频时“一个信息比特对应一个完整m序列周期”,处理增益恰好等于N。

还有一个容易被忽略的点:m序列在一个完整周期里,1的个数比0的个数多一个。周期127时,1出现64次,0出现63次。这个“平衡性”在后面抗直流干扰仿真里会起关键作用,第4章会再提到。

2.3 单比特扩频与解扩的最小链路:验证m序列自相关特性的基础代码

在写完整收发机之前,先花五分钟验证一件事:扩频码本身是否正确。下面的程序发送一个信息比特,经过扩频、理想信道、解扩,最后判决回来。这段代码虽然短,但它是后续所有链路的地基。

N = 127; % 扩频因子,等于m序列周期 bit = 1; % 发送信息比特 1 chips = bit * mseq_bip; % 扩频:信息比特直接乘整段码序列 rx = chips; % 理想信道,无噪声无干扰 % 解扩:乘本地码再取平均 soft = sum(rx .* mseq_bip) / N; bit_hat = soft > 0; fprintf('soft = %.3f, 判决结果 = %d\n', soft, bit_hat);

逻辑说明:扩频就是在双极性比特与双极性码序列之间做逐点相乘,解扩则是再做一次逐点相乘并求和。当本地码与发送码完全对齐时,soft等于N除以N,也就是1;如果相位错开,m序列的自相关旁瓣会降到很低的水平,soft会趋近于0或一个很小的数。参数说明:这里的判决门限是0,soft > 0判为比特1,soft < 0判为比特0;无噪声时soft应该精确等于±1,如果结果不是,多半是m序列的双极性映射出了问题,最常见的是忘了把0换成-1。

把这段跑通之后,你可以自己验证一个有趣的结论:把接收端的本地码右移一位再做相关,soft会从1掉到接近0。这就是扩频码自相关特性的直观体现,也是后面同步模块实现的理论依据。

3. 从扩频码片流到BER曲线:完整基带收发仿真的MATLAB实现

单比特链路验证通过后,就可以把它扩展成完整的收发机仿真。这一章给出一个可以直接运行的DSSS-BPSK基带仿真脚本,覆盖发射端、AWGN信道、接收端和误码率统计四个部分。这也是课程作业里最常见的交付形式。

3.1 脚本式仿真和Simulink模型怎么选:调试速度优先的落地经验

MATLAB里做DSSS仿真有两条路:纯脚本(全部用m文件)和Simulink模型。我的建议是课程作业优先选脚本式,因为调试和改参数更快,同步、判决、BER统计都在一处代码里,出图方便。Simulink的可视化确实强,拖几个模块就能搭出漂亮框图,但Simulink里的BER工具需要额外配置延迟补偿,扩频码相位对齐也得手动调,很多同学在这里耗掉的时间比写脚本多得多。

从实践角度看,两者各有适用场景。脚本适合参数扫描和性能验证,Simulink适合做系统演示和模块化展示。如果你时间充裕,可以先把脚本跑通,再用Simulink搭一个展示版。需要注意一点:MATLAB版本从R2023b换到R2025b甚至更新的版本时,脚本基本不用动,但Simulink模型偶尔会提示通信工具箱模块路径变更,答辩前换电脑演示时容易踩这个雷。

对比项脚本式仿真Simulink模型
调试速度快,断点加在m文件里慢,信号线排查麻烦
参数扫描循环直接改变量需要批量仿真配置
误码率统计自己写,逻辑透明依赖BER工具,延迟补偿容易错
演示效果一般,需要自己画图直观,适合答辩展示

3.2 发射端实现:kron扩频、双极性映射与AWGN噪声注入

发射端的核心是把随机比特流变成扩频码片流。这里最关键的MATLAB函数是kron,它能把每个信息比特复制N次,再与m序列逐点相乘。很多新手在这里用点乘,得到维度错误后改用循环,代码跑起来又慢又丑。正确做法如下:

clear; clc; N = 127; % 扩频因子,等于m序列周期 numBits = 20000; % 仿真比特数,用于BER统计 EbN0_dB = 0:2:10; % 比特信噪比扫描范围 % 生成m序列并做双极性映射 mseq = lfsr_mseq([7 3], ones(1,7), N); mseq_bip = 2*mseq - 1; % 发射端:随机比特 -> 双极性 -> 扩频 data = randi([0 1], 1, numBits); data_bip = 2*data - 1; % 0->-1, 1->+1 tx_chips = kron(data_bip, mseq_bip); % 每个比特复制N个码片再相乘

逻辑说明:kron(data_bip, mseq_bip)做的事情是先取出data_bip里的一个元素,把它与整个mseq_bip相乘,得到一段长度为N的码片序列,然后对每个比特重复这个过程并拼接起来。最终tx_chips的长度是numBits * N,也就是254万码片。参数说明:numBits取20000是为了让BER曲线在低误码率段不至于因为样本太少而抖动;如果你想在高信噪比区域看满10的负4次方以下的误码率,建议把numBits加到50000以上。

噪声注入也在这个阶段处理。AWGN信道下,加性噪声的方差由比特信噪比决定。注意这里的能量换算:因为每个码片幅度是±1,所以一个信息比特的能量是N个码片能量之和,即Eb = N。这个关系很多同学写错,导致BER曲线整体偏左或偏右几个dB。

3.3 接收端实现:reshape分组、相关解扩与误码率统计口径

接收端是整个仿真里最容易出逻辑错误的地方。解扩的正确做法是把接收码片流按N个码片一组重新排列成矩阵,然后让本地m序列与这个矩阵做矩阵乘法,得到每个比特的相关输出。误码率统计必须在比特判决之后做,绝不能拿码片判决结果凑数。

ber = zeros(size(EbN0_dB)); for k = 1:length(EbN0_dB) % 等效噪声方差:实基带AWGN下 sigma^2 = N0/2 Eb = N; % 每比特能量,码片幅度为1 N0 = Eb / 10^(EbN0_dB(k)/10); noise = sqrt(N0/2) * randn(1, length(tx_chips)); % 信道:rx = tx + noise rx_chips = tx_chips + noise; % 解扩:按N个码片分组,每列对应一个信息比特 rx_mat = reshape(rx_chips, N, numBits); soft = mseq_bip * rx_mat; % 相关输出,1×numBits bits_hat = soft > 0; % 判决门限0 % 误码率统计:按比特对比 ber(k) = sum(bits_hat ~= data) / numBits; end figure; semilogy(EbN0_dB, ber, 'o-'); grid on; xlabel('Eb/N0 (dB)'); ylabel('BER'); title('DSSS-BPSK over AWGN');

逻辑说明:reshape(rx_chips, N, numBits)把长度为numBits*N的码片流变成N行numBits列的矩阵,第i列恰好是第i个比特扩展出的N个码片。mseq_bip * rx_mat是行向量与矩阵的乘法,相当于对每一列做一次相关求和,输出正好是numBits个软判决值。参数说明:Eb=N是因为每个比特跨N个码片且码片能量为1;N0由比特信噪比反推得出,sqrt(N0/2)是实AWGN的噪声标准差。

这套代码跑完后,你会得到一条随Eb/N0变化的BER曲线。注意一点:如果你的BER曲线在低误码率区域剧烈抖动,优先增加numBits而不是检查算法。第6章会专门讲怎么用“最少误码数”来控制这个抖动。

3.4 AWGN下的BER曲线解读:为什么扩频“看起来”没有增益

运行上一节代码后,你会看到DSSS-BPSK的BER曲线和普通BPSK的理论曲线几乎重合。很多同学第一次看到这个结果都会怀疑自己写错了,怀疑扩频是不是压根没有作用。这里必须澄清一个关键概念:DSSS在AWGN信道下本来就不会带来误码率改善。处理增益换来的是抗窄带干扰能力,而不是在纯净高斯白噪声下的性能提升。

原理不复杂。扩频把信号能量从窄带展开到宽带,白噪声的功率谱密度是平坦的,解扩时信号能量被完整收回来,噪声却没有被压低,所以信噪比不变,误码率自然不变。换句话说,DSSS并没有“变出”增益,而是把干扰环境下的性能劣势扳了回来。这个结论一定要写进课程作业报告里,因为在答辩时“为什么扩频后BER没有改善”是出现频率最高的问题。把这个逻辑讲清楚,顺理成章地引出第4章的抗干扰仿真——那才是评分的加分项。

4. 抗干扰仿真是评分关键:处理增益计算与单音干扰对比试验

如果说AWGN下的BER曲线是及格线,那抗干扰仿真就是拉开差距的部分。DSSS最本质的优势是抗窄带干扰,而这一点必须通过对比试验来体现。这一章先讲处理增益的计算方法,再给一个完整的单音干扰对比仿真,最后讨论两个容易被忽视的干扰参数边界。

4.1 处理增益怎么算:扩频因子、码片速率与信息速率的换算关系

处理增益是直接序列扩频的核心指标,定义为扩频后信号带宽与信息带宽之比。在连续系统里,它等于码片速率除以信息速率,取对数后就是Gp = 10*log10(Rc / Rb)。在我们的离散仿真里,因为一个信息比特恰好对应N个码片,所以码片速率与信息速率之比就是扩频因子N,处理增益直接写成:

N = 127; Gp = 10*log10(N); % 处理增益,约为21.0 dB

参数说明:Gp是理论上限,实际仿真会因为干扰相位、判决门限和m序列非理想自相关而有损耗,一般能测到19到20dB就算正常。很多报告把这一行代码当作“仿真结果”直接交上去,容易被导师质疑,正确做法是把实测增益也测出来,和理论值放在同一张表里,第6章会给出具体做法。

注意:处理增益与信噪比增益不是一回事。DSSS的抗干扰能力来自干扰被扩频码二次扩频后摊平到整个频带,接收端积分滤波器只保留其中1/N的功率。这个机理在单音干扰仿真里最容易直观看到。

4.2 单音干扰对比仿真:扩频系统与非扩频系统的BER随干信比变化

单音干扰是最经典的窄带干扰模型,直接在基带码片序列上叠加一个正弦信号就行。为了展示DSSS的价值,我习惯做一套对比:一套普通BPSK,一套DSSS-BPSK,其他条件相同,逐步增大干扰幅度,观察两条BER曲线。注意,这里先不加噪声,只看干扰影响。

% 单音干扰仿真:干扰幅度从0.1扫到1.0 jam_amp = 0.1:0.1:1.0; f_j = 0.03; % 归一化干扰频率,相对码片采样率 ber_dsss = zeros(size(jam_amp)); for k = 1:length(jam_amp) % 干扰:幅度为jam_amp(k)的单音正弦 jam = jam_amp(k) * cos(2*pi*f_j*(0:length(tx_chips)-1)); rx = tx_chips + jam; % 信道:只加干扰 rx_mat = reshape(rx, N, numBits); soft = mseq_bip * rx_mat; ber_dsss(k) = sum((soft > 0) ~= data) / numBits; end % 非扩频BPSK,同等条件下的对比 ber_n = zeros(size(jam_amp)); for k = 1:length(jam_amp) jam_n = jam_amp(k) * cos(2*pi*f_j*(0:numBits-1)); rx_n = data_bip + jam_n; % 每个比特一个样本 ber_n(k) = sum((rx_n > 0) ~= data) / numBits; end

逻辑说明:扩频系统接收端做解扩时,干扰项被本地m序列调制后再积分,窄带干扰能量被摊开,只有很小一部分通过积分器的等效低通;而非扩频系统直接对符号样本判决,干扰功率全部落在判决域里。参数说明:f_j取0.03意味着干扰频率远小于码片速率,落在信号带宽内;如果想要更贴近实际的结论,可以让f_j在一个范围内扫,观察BER的波动。

运行结果通常很直观:非扩频系统在干扰幅度超过0.2左右就大面积出错,而扩频系统要到干扰幅度接近1才出现显著恶化。这个对比图放进度报告里,比任何文字都更有说服力。

4.3 干扰频率位置与直流干扰:两个容易被忽视的仿真边界

单音干扰仿真有几个隐藏的边界条件,处理不好会让结果变得不可解释。最典型的是干扰频率与码片速率的关系。当f_j很小,比如0.001时,正弦波形在一个码片内几乎不变,解扩时干扰实际上是对m序列本身做加权求和。由于m序列的平衡性,这个值会压缩到极低水平,系统表现异常好;当f_j增大到接近0.5时,正弦符号在每个码片内快速翻转,解扩后残余干扰变大,处理增益会下降。所以报告里一定要写明干扰频率的设置,否则换个频率结果就变了。

直流干扰是一个更经典的边界案例。如果干扰是固定偏置,也就是f_j = 0,那么解扩输出里干扰分量等于直流乘上m序列的求和。利用m序列的平衡性,这段求和值接近0,所以DSSS对直流偏置有天生的抑制能力。可以在代码里验证:

jam_dc = 0.5 * ones(size(tx_chips)); % 直流干扰,幅度0.5 rx = tx_chips + jam_dc; soft = mseq_bip * reshape(rx, N, numBits); % 由于m序列在一个周期内1比0多一个,soft中干扰分量很小

逻辑说明:mseq_bip的127个元素中,64个是+1,63个是-1,求和等于1,所以直流干扰经解扩后只剩原幅度的1/127,几乎可以忽略。这个现象值得在报告里单独写一段,因为它展示了m序列本身的设计价值。参数说明:直流幅度取0.5是为了和信号幅度同量级,如果取5,残留下扰也会相应变大,但仍然能看出扩频系统的抑制能力。

5. 扩频码同步避坑:解扩输出全是雪花时的四个排查点

同步是直接序列扩频仿真里最容易翻车的环节。很多同学在理想信道下跑通了主链路,一加入噪声或干扰,解扩输出就变成随机判决,专业点说就是“输出全是雪花”。这一章先讲同步的两种建模层次,再讲参数设计的第一原则,最后给出四个高频坑的具体排查方法。

5.1 同步的两种建模层次:先验对齐和滑动相关搜索分别解决什么问题

课程作业里最常见的“偷懒”写法是接收端直接复制发射端的mseq_bip变量,从这个角度说码相位天然是对齐的。如果只是为了演示扩频原理,这种先验对齐方式能跑通;但导师追问“接收端在真实系统里怎么知道码从哪里开始”,偷懒的写法就撑不住了。正确的做法是至少实现一个滑动相关搜索模块,证明你考虑过捕获过程。

滑动相关搜索的思路朴素:把接收码片流按滑动窗口切段,每段与本地m序列求相关值,相关峰出现的位置就是码相位。最小实现如下:

% 假设rx_chips是接收码片流,但码相位未知 L = length(rx_chips); search_range = L - N; % 滑动范围 corr_out = zeros(1, search_range); for k = 1:search_range seg = rx_chips(k : k+N-1); corr_out(k) = abs(mseq_bip * seg(:)); % 相关绝对值 end [peak_value, sync_idx] = max(corr_out); fprintf('峰值=%.2f, 同步位置=%d\n', peak_value, sync_idx);

逻辑说明:窗口每滑动一个码片,与本地码做一次相关。对齐时相关值峰值接近N,不对齐时接近旁瓣值。sync_idx就是接收码片流的起始位置。参数说明:这里按码片步进搜索,实际系统会先做粗捕获再做跟踪,但课程作业做到捕获层就够了。如果你要把搜索后的码片流送进解扩模块,记得先做rx_chips(sync_idx:end)截断,再进入reshape。

5.2 采样率、码片速率、信息速率三者的整数倍关系:参数设计的第一原则

MATLAB离散仿真里没有真实的连续时间,所有“速率”都通过样本关系体现。我建议的默认模型是“一个码片对应一个样本”,这样码片速率等于采样率,信息速率等于采样率除以N。这个模型下,N必须是整数,且一个信息比特恰好对应N个样本,任何内插或抽取都会破坏这个关系。

参数推荐取值说明
扩频因子N1277阶m序列周期,处理增益约21dB
m序列阶数7LFSR寄存器个数
每码片样本数1基带等效模型,按码片采样
信息比特数20000以上保证BER曲线稳定
Eb/N0扫描范围0到10dB每2dB一档即可

如果你尝试过每码片4个样本的过采样模型,那reshape的宽度要从N变成N乘以4,本地序列也得先用kron(mseq_bip, ones(1,4))拉长,对应关系全变了。对课程作业来说,过采样带来的真实感有限,但出错概率成倍增加。我一般建议保持1样本每码片,把精力留给同步和干扰建模。

5.3 四个高频翻车点:从现象到原因再到解决办法

第一个坑是软判决值始终接近0,判决结果随机。现象是跑完单比特链路后soft不是接近±1,而是接近0。原因是本地码与发送码相位错开,或者双极性映射没做对。解决办法是先在无噪声无干扰下核对,用第2章的最小链路确认soft峰值为N;确认无误后再跑滑动相关,看峰值位置是否与理论一致。

第二个坑是BER随信噪比提高反而变大。现象是ber曲线在高Eb/N0段不降反升或剧烈波动。原因通常是误码率统计口径错了,把每个码片的判决当成比特判决来统计。一个比特对应N个码片,只能对解扩积分后的soft做一次判决,不能对码片逐个做0/1判断再数错误。解决方法是先reshape再相关,最后与data本身做对比,中间不掺入任何按码片维度的统计操作。

第三个坑是数据长度对不上,reshape报错或矩阵维度不匹配。现象是发射端用了kron扩频,长度应该是numBits*N,但接收端拿numBits当长度去reshape,维度直接报错。原因是对kron和点乘的区别不熟悉。kron(data_bip, mseq_bip)是每个比特复制N个码片,而data_bip .* mseq_bip要求两者长度相同。解决办法是确认发射端length(tx_chips)是否等于numBits*N,并在注释里写明这个关系,避免过两天自己看代码时又混。

第四个坑是滑动相关峰不明显,甚至出现多个相近峰值。现象是在低信噪比或强干扰下,corr_out的最大值和旁瓣相差不大,无法确定sync_idx。原因是搜索范围内包含了多个比特的扩频码,相邻比特的码片边界也会产生相关响应。解决办法是先在无噪声下调试同步模块,让峰值尖锐;再逐步加噪,或者做多帧累积相关,把几帧的相关输出叠加后再找峰值。也可以用m序列自相关的旁瓣值做归一化门限,峰值超过旁瓣若干倍才认为捕获成功。

6. 答辩前值得花20分钟做的三个仿真验证技巧

交作业前,我习惯用固定的流程给仿真结果做一次“体检”。三个小技巧,每个几分钟,能筛掉大部分潜在问题。

第一个技巧是BER扫描不要用固定比特数,而是用最少误码数控制循环终止。固定numBits=20000时,低误码率区域可能只有几个误码,曲线抖动非常难看。更稳的做法是动态累加,直到某个Eb/N0点累计到至少100个误码或达到最大比特数才退出。这样曲线在10的负4次方以下的区域也平滑。代码骨架如下:

maxBits = 5e5; minErrors = 100; % 循环内累计误码数,达到minErrors则break,否则继续发比特

第二个技巧是用眼图验证解扩前的码片质量。在干扰仿真里,眼图比BER曲线更直观。eyediagram(rx_chips(1:20000), 2)可以直接看到码片波形张开度;干扰增强时眼图闭合,扩频系统的处理增益会让眼图重新张开。这张图放进报告里,视觉冲击力比一条BER曲线大得多。

第三个技巧是把理论处理增益和实测增益放在同一张表里。实测方法:在某个干信比下,找到扩频系统与非扩频系统BER相等的那一点,两者的干信比差值就是实测增益。比如非扩频系统在干信比为负5dB时BER为1e负3,扩频系统到正15dB才达到同一BER,那实测增益就是20dB,与理论值21dB接近。这个表格是答辩时的硬通货:

系统达到BER=1e负3所需干信比备注
非扩频BPSK-5 dB干扰功率低时已恶化
DSSS-BPSK+15 dB处理增益生效
实测增益约20 dB理论值21dB

我自己当年做这个题目时,把m序列周期设成31,扩频因子却设成127,两个数字对不上,曲线怎么调都不干净。后来把所有参数统一成“一个信息比特对应一个完整m序列周期”,问题才彻底消失。现在每次做扩频仿真,我都会在文件头部把N、码片速率、采样率的关系写进注释,避免重复踩同一个坑。希望这些经验能让你少走一段弯路,祝仿真一次跑通。

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

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

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

立即咨询