ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

MATLAB直接序列扩频通信系统仿真与误码率验证

MATLAB直接序列扩频通信系统仿真与误码率验证

简介:面向通信原理、扩频通信与MATLAB仿真课程的学习者,这份DOC文档围绕直接序列扩频通信系统的建模与仿真展开,可用于理解DSSS的扩频、解扩流程及抗干扰性能评估。文档从直扩系统组成入手,梳理信源、伪随机码生成、BPSK调制与相关解扩等环节,并比较m序列、GOLD序列、WALSH码和OVSF码的特点与工程应用,同时归纳抗同频干扰、抗衰落和抗多径干扰等优势。仿真部分给出2kbps信源速率、扩频因子64、BPSK调制和高斯信道等参数设置,配合程序代码与误码率随信噪比变化的实验结果,便于读者对照原理检查系统性能。资源包共1个DOC文件,大小约320KB,结构集中,适合课程实验、专题报告或扩频通信入门研究参考。已有142人学习,可作为MATLAB通信仿真练习的辅助材料。

1. 曲线画出来了,答辩为什么还是被问住

做基于 MATLAB 的直接序列扩频通信系统仿真设计,最省事的路径是找一段能跑的脚本,一路 plot 出七八张图,贴进文档就算交差。可真坐到答辩桌前,评委通常只问三件事:扩频因子取了多少、处理增益体现在曲线的哪个位置、带内信噪比为负时凭什么还能正确解调。这三个问题答不上来,图再多也只是一堆彩线。这套方案要解决的就是把“能跑”推进到“讲得清”:从直扩系统模型出发,把信源、模二加扩频、BPSK 调制、高斯信道、相关解扩、积分判决这条链路逐段拆开,给出可复现的 MATLAB 实现,以及一条能和理论 erfc 曲线对得上的误码率结果。适合正在做扩频通信课程设计、通信原理方向毕设,或者需要向别人解释 DSSS 抗干扰到底抗在哪一段的人。

2. 链路建模:从信源到判决的六个环节与参数换算

扩频系统的仿真翻车,八成不是算法写错,而是链路里某一级的速率、带宽、采样率没对齐。所以在敲第一行代码之前,先把整条链路的“单位”统一一遍。直扩系统的骨架其实很朴素:信源出比特,扩频码把每个比特摊成 SF 个码片,BPSK 把码片搬上载波,信道叠噪声,接收端用同一条扩频码把码片重新压回一个比特,最后积分判决。难点全在“同一条扩频码”和“同一个时间轴”这两句话上。

2.1 发端:三次频谱搬移把窄带信号摊成宽带

设信源输出的信息流为 a(t),码元宽度 Ta;伪随机码产生器输出 c(t),码片宽度 Tc,且 Tc 远小于 Ta。两者相乘(等价于模二加后再做极性映射),得到速率与伪随机码相同的扩频序列,此时信息带宽已经被展宽到 1/Tc 量级。这一步是纯基带的,不涉及载波,很多同学一上来就在这层把载波乘进去,后面解扩时再也分不清哪部分是扩频增益、哪部分是调制带来的频谱搬移。

第二步才是调制。BPSK 用扩频序列去乘载波 cos(2πfct),把基带频谱搬到 ±fc 处。至此完成两次搬移:一次由扩频码把窄带摊宽,一次由载波把基带搬到射频。理解这一点,后面看频谱图时就不会把“扩频导致的展宽”和“调制导致的双边带”混为一谈。

用具体数字说话:信源速率 2 kbps,扩频因子 64,码片速率就是 128 kcps。基带信息带宽约 2 kHz,扩频后主瓣宽度约 2Rc = 256 kHz,BPSK 双边带再翻一倍到 512 kHz 量级。带宽被拉开了 64 倍,这就是处理增益的物理来源,换算成 dB 是 10log10(64) ≈ 18 dB。原文里写“处理增益达到 10 dB 以上”,取 64 其实是留了余量,答辩时把这个换算讲出来,比背定义有说服力得多。

2.2 收端:相关解扩对信号是压缩,对干扰是再扩频

接收端的动作顺序和发端严格相反:混频把射频拉回中频或基带,用与发端同步的伪随机码做相关解扩,把宽带的扩频信号还原成窄带的信息信号,再滤波、抽样、判决。这里最关键的一句话是:相关解扩对有用信号是“压缩”,对不相关的干扰和噪声是“再扩频一次”。

从数学上看,解扩就是在一个比特周期内做内积。有用信号与本地码完全对齐,64 个码片同号累加,幅度增长为原来的 SF 倍;噪声与本地码不相关,累加后幅度只按 √SF 增长。于是输出信噪比相对输入提升了 SF 倍,也就是 18 dB。而窄带干扰被本地码相乘后,频谱反而被摊宽了 SF 倍,功率谱密度下降,落在信号通带内的那部分功率被大幅削弱。这一压一摊,就是直扩抗干扰的全部秘密。

仿真里要特别小心“同步”这两个字。载波要同频同相,扩频码要同步对齐,两者缺一不可。很多脚本跑出来误码率恒定在 0.5 附近,或者曲线低信噪比段正常、高信噪比段反而出现平台,基本都是载波相位或码相位没对齐,而不是噪声加错了。

2.3 参数表:把 kbps、扩频因子和采样率钉死在一张表里

参数不一致是这类仿真最隐蔽的坑。文档里写扩频因子 64,脚本里每个比特只重复了 4 个码片,曲线照样能画出来,但处理增益凭空多了 12 dB,和理论值完全对不上。避免的办法是在脚本开头用一张参数表把量纲钉死,后面所有长度、索引、滤波器系数都从这张表推导,不允许出现硬编码的数字。

参数符号取值推导关系
信源比特率Rb2 kbps给定
比特周期Tb0.5 ms1/Rb
扩频因子SF64给定,决定处理增益
码片速率Rc128 kcpsRb × SF
码片周期Tc7.8125 μs1/Rc
每码片采样点数sps8决定时间分辨率
采样率Fs1.024 MHzRc × sps
载波频率fc100 kHz取 Fs 的约 1/10,便于观察
仿真比特数Nbits2000由最低误码率决定

这张表往下推一层,还能得到两个常被忽略的结论。一是每个比特对应 SF × sps = 512 个采样点,脚本里所有“每比特取多少点”的地方都必须是 512,不能是 400 也不能是 500。二是载波周期与采样率之比决定了一个载波周期内有多少个采样点,fc = 100 kHz、Fs = 1.024 MHz 时约 10 个点,足以让 cos 混频后的波形看得清形状,又不至于让采样点数爆炸。

2.4 干扰容限:处理增益到底能换来多少抗干扰余量

处理增益不是拿来炫耀的数字,它直接换算成系统能容忍多大干扰。工程上常用的估算是干扰容限 Mj = Gp − [Lsys + (S/N)o],其中 Gp 是处理增益,Lsys 是系统实现损耗,后面一项是解调器要求的最小输出信噪比。代入 Gp = 18 dB、系统损耗按 3 dB 估、解调门限按 10 dB 算,容限约 5 dB,意思是干扰功率比信号功率高 5 dB 时系统仍能工作。

这个公式在仿真里的对应物就是误码率曲线相对理论 BPSK 曲线的水平平移量。理想情况下,扩频系统的 BER 曲线应该和未扩频的 BPSK 理论曲线重合(横轴用 Eb/N0),差别只体现在带内信噪比可以做到很低。如果你的曲线比理论曲线左移了一大截,别高兴太早,先回去查扩频因子是不是被重复计算了。

3. 扩频码选型:m 序列、GOLD 码与正交码的工程取舍

扩频码决定了系统的自相关特性、多址能力和实现复杂度。直扩系统对扩频码的要求很明确:尖锐的自相关峰、低互相关旁瓣、足够长的周期、易于用移位寄存器产生。m 序列、GOLD 序列、WALSH 码和 OVSF 码分别对应不同的侧重点,选错编码不会让仿真跑不动,但会让结果解释不清。

3.1 m 序列:本原多项式决定一切

m 序列由 n 级线性反馈移位寄存器产生,周期为 2^n − 1,具有二值自相关特性:归一化自相关在主峰处为 1,其余位置为 −1/L。这个特性是直扩系统能够精确同步的基础。产生 m 序列的关键是反馈抽头必须对应一个本原多项式,选错了抽头,寄存器会在一个短周期里循环,输出的根本不是 m 序列。

下面这段代码用 6 级寄存器生成周期 63 的 m 序列,并把它补齐到 64 位,与扩频因子对齐。

% ---------- 6 级 m 序列:反馈抽头对应 x^6 + x + 1 ---------- stage = 6; tap = [1 0 0 0 0 1]; % 抽头系数,依次对应 x^1 ... x^6 reg = [1 1 1 1 1 1]; % 寄存器初相,禁止全零 Lm = 2^stage - 1; % 序列周期 63 mseq = zeros(1, Lm); for k = 1:Lm mseq(k) = reg(end); % 取末级作为输出 fb = mod(sum(reg .* tap), 2); % 模二加反馈 reg = [fb, reg(1:end-1)]; % 整体右移一位 end pn = 1 - 2*mseq; % 0/1 映射为 +1/-1 pn = [pn, pn(1)]; % 补一位凑成 64,与 SF 对齐

代码里tap的每一位对应一个反馈抽头,reg是寄存器状态向量,fb是反馈位。输出取末级而不是首级,是为了让序列的相位关系与教科书上的框图一致,这个细节不影响误码率,但影响你画出的波形和理论波形能不能对上。

补位那一行是有代价的:把 63 位的 m 序列强行补成 64 位,会破坏严格的二值自相关特性,旁瓣从 −1/63 抬高到约 −1/64 之外的不规则值。在单用户、单径的仿真里这点损失几乎看不出来,但如果你要做多址干扰分析,这个补位就是误差来源。更稳妥的做法是把扩频因子取成 63,或者用 7 级 m 序列截断到 64,并在报告里明确写出这处近似。

3.2 GOLD 码:一对优选对扩出整个码族

单条 m 序列的同族互相关特性并不理想,而码分多址需要大量互相关可控的地址码,GOLD 码就是为此设计的。它由两条码长相同、码速率相同的 m 序列优选对逐位模二加构成,每改变两条序列的相对位移,就得到一条新的 GOLD 码。n 级寄存器的一对优选对能产生 2^n + 1 条码,去掉两条原始 m 序列后仍有 2^n − 1 条可用地址。

GOLD 码的价值在于互相关只取三个值。对 n = 6,互相关归一化后落在 {−1, −17, 15}/63 这三个离散值上,最大旁瓣约 −12.4 dB,是可预估、可设计的。这一点在多址仿真里非常重要:干扰功率的上界是确定的,系统容量就能算出来。

% 两条 m 序列逐位模二加,得到 GOLD 码(先用检查脚本确认两条都是 m 序列) m1 = gen_mseq([1 0 0 0 0 1], [1 1 1 1 1 1]); % x^6 + x + 1 m2 = gen_mseq([0 0 0 0 1 1], [1 1 1 1 1 1]); % x^6 + x^5 + 1 gold = mod(m1 + m2, 2); % 模二加,长度 63 gold_pn = 1 - 2*gold; % 映射为 +1/-1

换多项式的时候不要凭记忆写抽头。写一个十行的检查脚本,把生成的序列循环移位 1 到 Lm 次,看是否只有零位移时与原序列完全相同、其余位移都不相同,通过了再拿去当扩频码。这个检查我每次换码都会跑一遍,省下来的返工时间远超写脚本的几分钟。

3.3 WALSH 与 OVSF:正交只在同步那一刻成立

WALSH 函数是一组完备的正交方波函数系,两两之间的互相关严格为 0,因此在同步码分多址里作为地址码使用非常合适。MATLAB 里用hadamard(N)直接生成 N 阶矩阵,每一行就是一条码字。但有两个细节容易被忽略:一是hadamard给出的是自然序(Hadamard 序),不是按过零次数排列的 Walsh 序,两者差一个位反转置换;二是第一行是全 1 序列,直流分量最大,工程上很少拿它当扩频码。

W = hadamard(64); % 64 阶 Hadamard 矩阵,每行一条码字 walsh = W(2, :); % 取第 2 行,避开全 1 的直流码

OVSF 码是正交可变扩频因子码,核心是一棵码树:从根节点开始每次分叉产生两条互相正交的子码,不同分支、不同层级的码字之间保持正交。它保证了不同扩频因子的信道可以在同一时隙共存,代价是码资源受限——一条码被占用后,它的所有父码和子码都不能再用。这也是为什么 OVSF 常见于对扩频因子灵活性要求高的系统,而直扩仿真里用 m 序列就够了。

WALSH 和 OVSF 的共同软肋是:正交性依赖严格的同步。一旦多径导致码相位错开,正交性立刻崩塌,互相关从 0 变成不可控的值。所以做单用户直扩仿真,m 序列或 GOLD 码更省心;做多址仿真且假设理想同步,WALSH 才有优势。选择哪一种码,取决于你在报告里想说明什么问题,而不是哪种码更“高级”。

3.4 码长选择:扩频因子不是越大越好

扩频因子直接决定处理增益,直觉上越大越好,但仿真里要权衡三件事。第一是运算量,Nbits × SF × sps 就是采样点总数,SF 从 64 提到 256,内存和耗时都翻四倍。第二是码长与周期的匹配,SF 取 2^n − 1 可以用一条完整 m 序列,取 2^n 就得截断或补位,自相关特性要打折扣。第三是时间分辨率,SF 越大,一个比特持续的时间越长,在给定比特数下仿真覆盖的物理时间越久,这对分析慢衰落信道反而是好事。

我的习惯是先定比特率和目标误码率,再反推需要的比特数,最后选 SF。目标 BER 到 1e-3,至少需要 100 个错误才能让统计量可信,也就是 10 万比特量级;如果只要看趋势,2000 比特足够把 0 到 8 dB 的曲线画顺。这个取舍在报告里写清楚,比硬堆一个巨大的 SF 更能体现工程判断。

4. MATLAB 实现:一条能跑出 BER 曲线的完整链路

代码组织得好不好,直接决定这份仿真能不能被人接手续做。我一般把脚本切成四块:参数区、发端、收端、扫描与绘图,块与块之间只通过变量传递,不共享临时下标。下面按这个顺序展开,每一段都能单独运行验证。

4.1 参数区与时间轴:一次定义,全脚本共用

参数区只写一次,后面所有长度都从这里推导,包括时间轴。时间轴用(0:N-1)/Fs生成而不是linspace,是为了让下标和物理时刻严格对应,方便后面按码片位置取抽样点。

%% ---------- 1. 全局参数 ---------- Rb = 2e3; % 信源比特率 2 kbps SF = 64; % 扩频因子 Rc = Rb * SF; % 码片速率 128 kcps sps = 8; % 每码片采样点数 Fs = Rc * sps; % 采样率 1.024 MHz fc = 100e3; % 载波频率 Nbits = 2000; % 每轮仿真比特数 Nsamp = Nbits * SF * sps; % 总采样点数 t = (0:Nsamp-1) / Fs; % 时间轴,单位秒

Rb和SF是仅有的两个“人为决定”的量,其余全部推导得出。Nsamp之所以要单独算,是因为后面做conv、reshape时对长度极其敏感,写成表达式比写常数安全。t从 0 开始而不是从 −T/2 开始,是为了让下标 n 与时刻 (n−1)/Fs 一一对应,抽样点索引不用加偏移。原文脚本里时间轴用linspace(-T/2, T/2, N),画波形好看,但做索引对齐时容易差一个点,我一般不用。

4.2 扩频与载波调制:kron 与 repelem 的分工

扩频这一步有两个动作:比特重复成码片(乘扩频码),码片保持成采样点(脉冲成形)。前者用kron一次完成,后者用repelem。这两个函数混用是常见的错误来源,kron做的是序列级联,repelem做的是元素复制,语义完全不同。

%% ---------- 2. 发端 ---------- data = randi([0 1], 1, Nbits); % 信源比特 sym = 1 - 2*data; % 0 -> +1, 1 -> -1 chip = kron(sym, pn); % 每比特乘以整段 64 位扩频码 tx_bb = repelem(chip, sps); % 每码片保持 8 个采样点(矩形成形) tx = tx_bb .* cos(2*pi*fc*t); % BPSK 载波调制

kron(sym, pn)的结果长度是 Nbits × 64,排列顺序是“第 1 个比特的 64 个码片、第 2 个比特的 64 个码片……”,这个顺序必须和收端reshape的顺序一致,否则解扩出来全是噪声。repelem把每个码片复制 sps 份,等价于零插值加矩形滤波,频域上是 sinc 形状,主瓣宽度正好对应码片速率。最后乘载波完成 BPSK 调制。

如果想看扩频前后的频谱对比,直接对sym和chip做pwelch即可,前者主瓣在 2 kHz 附近,后者主瓣在 128 kHz 附近,宽度差 64 倍,这张图放在报告里比任何文字都直观。

4.3 解扩与判决:reshape 内积的正确姿势

收端是整条链路最容易出错的地方,滤波器延迟、抽样时刻、reshape 维度,任何一处偏了都会让误码率卡在 0.5。我的做法是把“解调”和“解扩”分开写,中间用一次显式抽样隔开,出问题时可以逐级打印中间结果。

%% ---------- 3. 信道与收端 ---------- snr_dB = EbN0_dB - 10*log10(Fs/(2*Rb)); % Eb/N0 换算为带内信噪比 rx = awgn(tx, snr_dB, 'measured'); % 高斯信道 rx_i = rx .* cos(2*pi*fc*t); % 相干解调,本地载波同频同相 rx_lp = conv(rx_i, ones(1,sps)/sps, 'full'); rx_lp = rx_lp(1:numel(rx_i)); % 截断到与时间轴等长 idx = round((1:Nbits*SF)*sps - sps/2); % 每个码片积分窗的中心 rx_samp = rx_lp(idx); % 每码片抽取一个判决点 rx_mat = reshape(rx_samp, SF, Nbits); % 每列是一个比特的 64 个码片 soft = sum(rx_mat .* pn.', 1); % 与本地码内积,完成解扩 hard = sign(soft); % 硬判决 ber = mean(hard ~= sym); % 误码率

逐段说明。snr_dB的换算是关键:awgn的参数是带内信噪比,而通信理论关心的是 Eb/N0,两者差一个 Fs/(2Rb) 的因子,对这套参数来说是 256,即 24.1 dB。也就是说 Eb/N0 = 4 dB 时,带内信噪比只有 −20 dB,信号完全埋在噪声里,这正是扩频系统要证明的能力。

conv加矩形窗再做截断,等价于积分清除滤波器。窗长取 sps,正好覆盖一个码片;截断到numel(rx_i)是为了让索引不越界。idx取每个码片的中心位置,保证积分窗完整落在一个码片内,不跨越码片边界。

reshape(rx_samp, SF, Nbits)按列填充,第 1 列是第 1 个比特的 64 个抽样点,与发端kron的顺序严格对应。pn.'是转置,让 64×1 的码向量与 64×Nbits 的矩阵按列相乘,sum沿第一维累加得到 1×Nbits 的软判决值。这一步就是把 64 个码片的能量相干累加,噪声按 √64 增长,信号按 64 增长,信噪比提升 18 dB。

首尾各有一个码片的能量因为conv的边界效应不完整,影响不到两个比特,在 2000 比特的统计里可以忽略。要做严谨,就在发端前后各补 sps 个采样点的保护段再截掉。

4.4 BER 扫描与理论曲线对照:给结果找一个参照系

单点误码率说明不了问题,必须扫出一条曲线,并且和理论值放在一起。理论值用 erfc 计算,BPSK 在相干解调下的误码率是 0.5·erfc(√(Eb/N0)),这一条曲线就是判断仿真对不对的唯一标尺。

%% ---------- 4. 误码率扫描 ---------- EbN0_dB = 0:2:10; % Eb/N0 扫描范围 ber_sim = zeros(size(EbN0_dB)); for k = 1:numel(EbN0_dB) snr_dB = EbN0_dB(k) - 10*log10(Fs/(2*Rb)); rx = awgn(tx, snr_dB, 'measured'); rx_i = rx .* cos(2*pi*fc*t); rx_lp = conv(rx_i, ones(1,sps)/sps, 'full'); rx_lp = rx_lp(1:numel(rx_i)); rx_s = rx_lp(round((1:Nbits*SF)*sps - sps/2)); rx_m = reshape(rx_s, SF, Nbits); ber_sim(k) = mean(sign(sum(rx_m .* pn.', 1)) ~= sym); end ber_th = 0.5 * erfc(sqrt(10.^(EbN0_dB/10))); % BPSK 理论误码率 semilogy(EbN0_dB, ber_sim, 'o-', EbN0_dB, ber_th, 'k--'); xlabel('E_b/N_0 (dB)'); ylabel('BER'); grid on; legend('仿真','理论');

扫描范围从 0 到 10 dB,间隔 2 dB,五个点足够看出趋势。横轴用 Eb/N0 而不是带内信噪比,是为了能和理论曲线直接比较;如果横轴用 SNR,两条曲线会整体右移 24 dB,看起来吓人但实际上完全正确。

判断结果对不对,看两件事:仿真点是否围绕理论虚线波动,以及低 Eb/N0 段的偏差是否在统计误差范围内。2000 比特在 BER = 1e-2 时理论上有 20 个错误,波动会比较大;到 1e-3 时只有 2 个错误,曲线会突然掉到 0,这时候不要以为是算法变好了,是统计量不够。把 Nbits 提到 10 万,曲线立刻规矩。

5. 避坑与排查:仿真跑通但结果不对的五个原因

5.1 扩频因子在文档和代码里对不上

现象:误码率曲线比理论曲线左移十几 dB,看起来性能好得不真实;或者处理增益算出来和 10log10(SF) 完全不符。

原因:文档声明扩频因子 64,脚本里却是每比特重复 4 个码片,中间还夹着采样点重复,两个“倍数”被混成一个。原文那份脚本里就有这个痕迹:比特周期内点数、码片重复段长度、声明参数三者各说各话。

解决:把 Rb、SF、sps 三个量分开定义,所有长度由它们相乘推导,脚本里不出现裸数字。跑之前打印一行[SF, sps, Nsamp],和自己的参数表核对一遍。

5.2 reshape 维度或顺序错,误码率恒定 0.5

现象:无论信噪比多高,BER 始终在 0.5 附近,判决结果和原始比特看起来毫无关系。

原因:reshape的填充顺序与kron的拼接顺序不一致,或者把reshape(x, Nbits, SF)写反了,导致每个比特拿到的是跨越多个比特的杂乱码片。

解决:先用短序列验证,取 Nbits = 4、SF = 8,打印发端chip和收端rx_mat的前几列,肉眼比对。顺序对上了再放大规模。

5.3 Eb/N0 与带内 SNR 混用,曲线整体平移

现象:曲线形状和理论一致,但整体右移或左移一个固定量,怎么调参数都差这么多。

原因:awgn用的是带内信噪比,横轴却按 Eb/N0 标注,中间少了 10log10(Fs/(2Rb)) 这个换算因子。

解决:在加噪之前统一换算,并且把换算公式写在注释里。换一套参数(比如改 sps)后这个因子会变,公式必须跟着参数走,不能抄一个常数。

5.4 载波相位没对齐,高信噪比段出现误码平台

现象:低信噪比段曲线正常,Eb/N0 超过 8 dB 后 BER 不再下降,卡在 1e-3 到 1e-2 之间形成平台。

原因:收端本地载波与发端不同相,cos 混频后有用信号幅度乘了 cos(Δφ),I 路能量损失,信噪比再高也补不回来。相位差 90 度时信号直接归零。

解决:单用户仿真直接用同一条时间轴生成收发载波,保证严格同相。要研究频偏或相位噪声,就得上科斯塔斯环或判决反馈环,这时候误码平台是真实存在的,写进报告里说明即可。

5.5 蒙特卡洛统计量不足,低误码率点不可信

现象:BER 曲线在 1e-3 附近突然断崖式掉到 0,或者相邻两点的值跳变一个数量级。

原因:比特数太少,低误码率下错误事件只有个位数甚至零个,统计涨落主导了结果。

解决:按“至少 100 个错误”反推比特数,Nbits ≥ 100/BER_target。目标 1e-3 就要 10 万比特,目标 1e-4 就要 100 万。算力不够就减少扫描点,别用不可信的数据点凑曲线。

6. 验收与答辩:怎么证明这条曲线是对的

仿真做完,真正的难点是让别人相信结果可信。我的习惯是把验收拆成六个可检查的项,每项都有明确的判据和检查方法,答辩时按表逐条过,比临场解释管用。

验收项合格判据检查方法
扩频码正确性周期等于 2^n − 1,无全零退化循环移位比对,检查自相关主峰唯一
处理增益与 10log10(SF) 相差不超过 1 dB对比不同 SF 下曲线的水平间距
解调正确性Eb/N0 ≥ 6 dB 时 BER < 1e-3统计误码数,确认错误个数 ≥ 100
频谱展宽扩频后主瓣宽度约为信源带宽的 SF 倍pwelch 对比扩频前后功率谱
负信噪比工作带内 SNR = −20 dB 时判决仍正确打印软判决值的符号正确率
曲线吻合度仿真点围绕理论 erfc 曲线波动与 0.5·erfc(√(Eb/N0)) 叠图

第一条最容易被跳过,但它决定了后面所有结论的地基。扩频码退化成一个短周期序列,自相关旁瓣抬高,多址干扰分析全错,而误码率曲线在单用户下看起来完全正常。检查方法就是那段循环移位脚本,十行代码,跑一次几毫秒。

第二条是答辩高频问题。评委常问“处理增益在哪体现”,标准答案不是背 18 dB,而是指着图说:SF 从 64 提到 256,同一条误码率曲线向左平移 6 dB,正好是 10log10(4)。把两个 SF 的曲线画在同一张图上,这个平移量肉眼可测,比任何推导都硬。

第三条要注意统计量。我见过太多报告在 1e-4 处画了一个孤零零的点,一问错误数是 1 个,这个点的置信区间宽得能跑马。要么加比特数,要么把这个点删掉,只保留错误数 ≥ 100 的区间。

第四条是很多人忽略的加分项。扩频前后的功率谱画在一起,信源主瓣窄而高,扩频后主瓣宽而低,总功率不变,这个对比图直接把“扩频”两个字讲明白了。注意纵轴用 dBm 或 dBW 并标明归一化方式,别用线性功率,看不出差异。

第五条是这套方案最有说服力的证据。带内信噪比 −20 dB,意味着噪声功率是信号功率的 100 倍,时域波形上完全看不出信号形状,但解扩后判决全对。把时域波形和解扩后的软判决值并排放在一页上,任何人看一眼就懂扩频抗干扰是怎么回事。

第六条是收尾。仿真点和理论曲线叠在一起,偏差在 1 dB 以内,说明整条链路的增益、损耗、换算都对上了。偏差超过 2 dB 就要回去查 5.3 那个换算因子。

答辩时还有一个小技巧:主动交代近似。补位扩频码、单径信道、理想同步、矩形脉冲,这四条近似写在报告第一页,评委就不会揪着问“为什么没有多径”。主动暴露边界,比被动挨问体面得多。

从那以后我每次带人做这类仿真,都强制先跑一遍“短序列对齐验证”——Nbits 取 4、SF 取 8,把发端码片、收端抽样、reshape 后的矩阵全部打印出来,肉眼确认一一对应,再放大到 2000 比特跑曲线。这一步花十分钟,能省掉后面半天的抓瞎。希望帮到你。

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

返回列表