资讯详情

资讯详情

MATLAB直接序列扩频通信系统仿真:参数标定、解扩判决与误码率验证

简介面向通信原理、扩频通信课程学习者与MATLAB仿真入门者的设计文档围绕直接序列扩频系统的建模、解扩和性能评估展开可用于课程设计、实验报告撰写与仿真复核。压缩包仅含1个doc文件约320KB正文以实验原理、直扩系统模型、伪随机码类型、扩频优势和仿真结果为主线说明BPSK调制下信息码与PN码的模二加过程并比较m序列、GOLD码、WALSH码和OVSF码的适用场景。文中给出信源速率2kbps、扩频因子64、高斯信道等参数及部分MATLAB程序片段读者可据此观察误码率随信噪比变化的趋势理解抗同频干扰、抗衰落和抗多径干扰的实现思路。已有143人学习下载适合需要完整实验原理、参数设置和结果分析参考的读者。1. 为什么值得花一周把一条直扩链路在 MATLAB 里跑通做「基于 MATLAB 的直接序列扩频通信系统仿真设计」这个题目的人多半一开始都觉得它简单画一张发射机、信道、接收机的框图信源和 PN 码模二加加高斯白噪声出一条误码率曲线报告就能交。真坐下来写代码才发现处处不顺——扩频因子写 64m 序列一个周期却是 63载波频率设成 40 kHz采样率只有 4 kHz滤波器一通判决点被群延迟拖走半个码片。曲线要么贴着 0.5 不动要么掉下去又弹回来怎么看都不像教科书上那条瀑布线。这篇按交付顺序把链路重搭一遍定架构和参数、写扩频码与速率匹配、做 BPSK 调制解调与判决、摊开几个最容易翻车的点、最后给一套答辩时能自证的验收方法。2. 总体架构设计发射—信道—接收三段链路与参数标定直扩系统的教科书框图只有六个方块但落到代码里至少要拆成十二个可独立调试的步骤。拆得粗出了问题只能整段重跑连是哪一级坏的都不知道拆得细每一级都能单独出图对照调试才有抓手。这一章先把链路切成三段、把参数钉死在一张表里后面三章才有共同的坐标系。2.1 发射端的三级结构信源映射、扩频、载波搬移发射端做三件事顺序不能乱。第一件是把二进制信源映射成双极性不归零码0 变 -1、1 变 1第二件是用伪随机码逐位相乘把窄带信息摊到宽带上第三件是乘载波把基带谱搬到中频。很多报告里写「信源与 PN 码模二加」这是 0/1 域的说法和 ±1 域的乘法完全等价。仿真里我更愿意用乘法因为后面的载波调制也是乘法整条链路可以统一成「信号 × 序列 × 载波」的连乘形式省掉一层又一层判断也避免了原文那种sign(code(mod(i,7))-0.5)的绕法——这种写法一旦码长和循环变量对不上错在哪都看不出来。% 信源等概率二进制序列映射成双极性不归零码 Nbit 5000; bits randi([0 1], 1, Nbit); sym 2*bits - 1; % 0 - -1, 1 - 1 % 扩频每个比特与整段伪随机码逐位相乘 pn gen_mseq(6, [6 1], ones(1,6)); % 长度 63 的 m 序列取值 ±1 spread kron(sym, pn); % 长度 Nbit*63 的基带扩频序列 % 码片成型每码片保持 Ns 个采样点等价于矩形脉冲成形 Ns 8; txS reshape(repmat(spread, Ns, 1), 1, []);kron这一步是整个发射端的关键它把「每个比特复制一份完整的 63 位码」这件事写成一行得到的序列长度是Nbit*63。如果用两层 for 循环手写很容易把内层索引写成1:7而不是1:63跑出来的扩频比实际只有 7处理增益凭空少了 9 dB。repmat加reshape的组合负责码片成型Ns决定波形的采样密度取 8 已经能看清码片边沿取再大只是白烧内存。2.2 接收端相干解调、解扩与积分判决的次序接收端的顺序是有讲究的先乘本地载波下变频低通滤掉二倍频分量再乘本地伪随机码解扩最后在一个比特周期内积分清洗并判决。这个顺序对应「中频采样 数字下变频」的实现路线好处是低通滤波器只作用于基带信号不会把扩频码的陡峭边沿磨圆——如果反过来先解扩再滤波码片边沿被平滑之后相关峰的高度会明显下降。解扩的本质是一次相关运算本地码与接收信号逐点相乘同相位的码片乘积恒为 1反相位的码片乘积恒为 -1一个比特周期内累加得到的就是「63 或 -63 加上噪声」这样的判决量。干扰和噪声因为与本地码不相关相乘之后正负相消累加结果趋近于零这就是处理增益的来源。Rc 2000*63; % 码片速率 126 kcps fs Rc*Ns; % 采样率 1.008 MHz fc 2*Rc; % 载波 252 kHz低于 fs/2 t (0:numel(txS)-1)/fs; carrier cos(2*pi*fc*t); txRF txS .* carrier; % 发射基带扩频序列搬移到中频 rxRF awgn(txRF, 8, measured); rxBase rxRF .* carrier; % 相干解调 [b,a] butter(4, 2*Rc/fs); % 截止频率约一个码片带宽 rxLPF filtfilt(b, a, rxBase); % 零相位滤波规避群延迟 rxDe rxLPF .* pnS; % 与本地同步码逐点相乘butter(4, 2*Rc/fs)里的归一化截止频率是相对奈奎斯特频率的写成2*Rc/fs而不是Rc/fs这一点错了滤波器会把有用边带切掉一半解扩后的眼图会变成一锅粥。filtfilt做正反两遍滤波等效群延迟为零代价是运算量翻倍——在几百万点的仿真里这点开销完全可以接受换来的是判决点不用手工补偿延迟。2.3 参数表把比特率、扩频因子和采样率钉死在一张表里链路的四个速率——比特率、码片率、采样率、载波频率——之间存在硬约束任何一个改动都会牵动其他三个。我习惯在脚本最前面用一张表把它们全部算出来后面所有模块只引用变量名不再出现任何魔数。参数符号取值由谁决定比特率Rb2000 bps题目给定比特周期Tb0.5 ms1/Rb扩频因子SF63m 序列周期 2^6-1码片速率Rc126 kcpsRb×SF每码片采样Ns8波形分辨率采样率fs1.008 MHzRc×Ns载波频率fc252 kHz2×Rc且远小于 fs/2处理增益Gp18 dB10log10(SF)仿真比特数Nbit5000决定 BER 分辨率Rb 2000; Tb 1/Rb; SF 63; Rc Rb*SF; Tc 1/Rc; Ns 8; fs Rc*Ns; fc 2*Rc; Gp 10*log10(SF); % 18.0 dB Nbit 5000;这张表最重要的一列是「由谁决定」。比特率是题目给的不能动扩频因子受码长限制也不能随便取只有采样率Ns是自由变量调它只影响波形精细度和内存占用不影响任何物理结论。把自由变量和受约束变量分开后面改参数时就不会出现「改了一个、崩了三个」的连锁反应。3. 扩频码生成与扩频模块m 序列、GOLD 序列与速率匹配扩频码是这条链路里唯一一个「算错了也照样能跑出图」的模块所以最容易被糊弄过去。码长、抽头、初相、自相关旁瓣任意一项不对BER 曲线不会报错只会悄悄变差。这一章把 m 序列和 GOLD 序列的生成写清楚再把「速率匹配」这件事讲透——很多报告里写的扩频因子和代码里实际生效的扩频比根本不是一回事。3.1 m 序列的移位寄存器实现与抽头选择m 序列由线性反馈移位寄存器产生级数n决定周期2^n-1抽头位置决定它是不是本原多项式。级数取 6周期就是 63级数取 7周期 127。注意这个「减一」全零状态是死锁态必须排除所以 m 序列的周期永远比 2 的整数次幂少一位。这一位之差就是后面所有对不上的根源。function code gen_mseq(stage, taps, seed) % stage : 移位寄存器级数输出序列周期为 2^stage-1 % taps : 反馈抽头位置需对应一个本原多项式 % seed : 初相向量长度等于 stage且不能全为 0 reg seed(:).; L 2^stage - 1; code zeros(1, L); for n 1:L code(n) reg(end); % 末级输出即序列当前位 fb mod(sum(reg(taps)), 2); % 抽头模二加得到反馈位 reg [fb, reg(1:end-1)]; % 寄存器右移反馈位进最高位 end code 2*code - 1; % 0/1 映射为 -1/1 end三个入参里最容易错的是taps。6 级寄存器常用的本原多项式是 x^6x1对应抽头[6 1]如果随手写成[1 2]得到的序列周期会缩短到 3 或 7自相关特性完全破坏。验证方法很简单把生成的序列循环移位后与自身逐位比较只有零位移时相关系数为 1其余位移的旁瓣应该落在 -1/63 附近。跑一遍这个检查比盯着 BER 曲线猜半天管用。seed不能全零这一点在代码里没有强制判断实际工程里我一般会加一句assert(any(seed), seed 不能全零)省得后面调半天发现序列是一条直线。3.2 GOLD 序列与地址码什么时候不该用 m 序列m 序列的自相关特性很好但互相关特性不行——同一级数下不同抽头产生的 m 序列互相关峰值可能高到 0.5 以上多用户场景下这种互相关就是实打实的多址干扰。GOLD 序列正是为此设计的取一对互相关满足优选准则的 m 序列模二加之后得到新序列同一对优选对能生成2^n1条互相关性有界的码地址数比 m 序列多得多。m1 gen_mseq(6, [6 1], ones(1,6)); m2 gen_mseq(6, [6 5 2 1], [1 0 1 0 1 1]); % 另一条同周期 m 序列 gold m1 .* m2; % ±1 域相乘等价于模二加这两条序列必须来自同一级数、同一码时钟、且构成优选对随便换一组抽头得到的 GOLD 码互相关峰值可能超过 0.7反而比 m 序列更差。判断是否优选对的方法是把两条序列的互相关函数全算出来取绝对值最大值理论上应满足三值特性。单用户的高斯信道仿真里用 m 序列完全够用只有做到多址或者抗多址干扰那一章才需要换 GOLD 码——这一点在报告的结构安排上也要对应别在单用户章节里大谈 GOLD 码的优势答辩时容易被追问「你的仿真里多址在哪」。WALSH 码是另一条路长度可以是 2 的整数次幂两两完全正交互相关恒为零代价是除了零位移之外自相关旁瓣很大对同步误差极其敏感。如果题目明确要求扩频因子取 64用 64 阶 WALSH 码是最省事的做法处理增益按 10log10(64)18.06 dB 报数值上和 63 差别可以忽略。3.3 扩频的本质是速率匹配不是「加个扰码」很多报告把扩频描述成「给信号加一层伪随机扰码」这个说法在概念上就偏了。扩频真正做的是速率匹配把一个Tb宽的比特拆成SF个Tc宽的码片时域上每个码片携带同样的信息频域上带宽被展宽SF倍功率谱密度被压低SF倍。这一步做完信号的时间分辨率和带宽分辨率都变了后面的采样率、滤波器带宽、积分长度全都要跟着变。pnS reshape(repmat(pn, Ns, 1), 1, []); % 一个码周期内的采样展开 pnS repmat(pnS, 1, Nbit); % 铺满整个比特流 assert(numel(pnS) numel(txS), 本地码长度与接收信号不匹配);assert这一行看着多余却是我踩过坑之后加上的固定动作。只要本地码和接收信号差一个采样点.*运算在 MATLAB 里会广播成矩阵乘法不报错结果全错。加一行断言把这种沉默错误变成显式崩溃调试时间能省掉一大半。速率匹配还有一层含义如果伪随机码的周期不能被扩频因子整除每个比特对应的码段就会发生相位滑动解扩时相关峰高度会在 63 和 62 之间来回跳BER 曲线出现规律的锯齿。解决办法是让码周期等于扩频因子或者让扩频因子是码周期的整数倍最忌讳的是「码长 7、扩频因子 64」这种既不相等也不成倍数关系的组合。4. BPSK 调制、信道与解扩判决一条能出波形也能出星座的链路前三章把发射端和码序列搭完了这一章补上调制、信道和解调判决链路才算闭环。这一段最容易出的问题不是算法错而是「量纲错」——载波频率和采样率不在一个数量级、滤波器带宽和码片速率对不上、加噪时的功率基准被滤波器改过。逐个对齐之后剩下的就是纯粹的统计工作。4.1 双极性码与 BPSK 映射相位跳变要看得出 180 度BPSK 的映射规则只有一条比特 1 对应载波相位 0比特 0 对应相位 π。在 ±1 域里这件事就是一次乘法sym .* cos(2*pi*fc*t)符号翻转直接体现为波形在比特边界上的 180 度相位跳变。看波形图时重点看两处比特边界上有没有明显的反相码片边界上有没有连续的相位过渡——如果整段波形光滑得像调幅信号说明载波频率相对码片速率太低一个码片里塞不下一个完整周期相位信息被平均掉了。carrier cos(2*pi*fc*t); txRF txS .* carrier; figure; plot(t(1:2000), txRF(1:2000)); grid on; xlabel(时间 / s); ylabel(幅度 / V); title(BPSK 调制信号局部);画局部波形时横轴范围要按「几个比特周期」来取不要按「几个采样点」拍脑袋。Tb0.5 ms、fs≈1 MHz一个比特就是 504 个采样点取 2000 点大约能看到 4 个比特相位跳变一目了然。取 200 点只能看到噪声一样的抖动取 20000 点又挤成一团黑这两种图在答辩时都拿不出手。4.2 载波频率与采样率的硬约束fc和fs的关系是这条链路上最硬的一条约束fc必须小于fs/2最好再留一倍余量让fc fs/4。一旦越过奈奎斯特线余弦波在采样点上会退化成低频正弦频谱搬移的位置完全错位解调端乘同频载波之后得到的不是基带信号而是一个频率为fs-fc的混叠分量低通滤波器根本拦不住。这条约束在小数采样率下特别容易破。比如按归一化时间单位写代码fs取 4000、fc取 4e4数值上看着都是「几千、几万」的量级实际上是载波频率比采样率还高十倍。波形图照样能画出来因为 plot 只管把点连起来但那条曲线已经不是原来的信号了。我的做法是先把Rc算出来再把fc写成k*Rck 取 2 到 4最后让fs Ns*Rc三个量绑死在一起永远不会出现量级错配。Rc Rb*SF; % 126 kcps Ns 8; fs Rc*Ns; % 1.008 MHz fc 2*Rc; % 252 kHz assert(fc fs/4, 载波频率过高检查采样率或扩频因子);fc 2*Rc意味着一个码片里正好两个载波周期解调后每个码片能积出两个完整的半波低通滤波的过渡带也够宽。如果fc取到Rc/2一个码片里不到半个周期码片边沿的相位不连续会带来严重的频谱泄漏眼图闭合。4.3 解扩本地码同步、低通滤波与积分清洗解扩这一步由三个动作串起来本地码与接收信号逐点相乘、低通滤掉高频分量、在一个比特周期内积分。三个动作里最容易忽略的是积分区间——必须严格对齐比特边界差一个码片积分结果就会混入相邻比特的能量。rxDe rxLPF .* pnS; rxMat reshape(rxDe, SF*Ns, Nbit); % 每列是一个完整比特周期 metric sum(rxMat, 1); % 积分清洗 bitsHat metric 0; % 零门限判决 ber mean(bitsHat ~ bits);reshape的维度顺序是全篇最容易翻车的一行。rxDe是按时间顺序排列的一维向量前SF*Ns个点属于第 1 个比特接着SF*Ns个点属于第 2 个比特所以 reshape 成SF*Ns × Nbit之后每一列才是一个完整比特。如果写成Nbit × SF*Ns每一行变成一个比特sum(...,1)求的就不是比特内积分而是比特间求和判决结果会呈现一种「看起来有信号、但 BER 始终在 0.3 左右」的诡异状态。判决门限取 0 是 BPSK 在等概信源下的最优门限前提是直流分量已经被滤掉。如果低通滤波器是巴特沃斯型且阶数较低通带内可能有轻微不平坦直流附近会残留一点点偏置这时候门限取 0 会让 BER 曲线在低 SNR 段整体抬高。稳妥的做法是先对metric做一次去均值再判决代价几乎为零。5. 常见问题排查误码率不下降的五个翻车点仿真跑通和仿真做对是两件事。下面五条是这条链路上出现频率最高的问题每一条都能让 BER 曲线保持「能出图但没意义」的状态而且在 MATLAB 里全部不报错。5.1 现象BER 贴着 0.5SNR 加到 15 dB 也不动原因本地码与发射码不是同一段或者比特与码块的对齐错位。常见情形是把pnS按码周期铺开时从第 1 个比特开始而txS因为kron的展开方式实际是从第 0 个码片开始两者差了一个码片相关峰直接塌掉。解决先做单比特冒烟测试——把Nbit改成 1不加噪声打印rxDe前 63 个点确认它与pn.^2逐点相等全为 1。这一步通过之后再恢复比特数能排除掉九成的对齐错误。5.2 现象报告写 64 倍扩频答辩被问「你的 m 序列一个周期几位」答不上来原因m 序列周期是2^n-163、127、255 都可能唯独不可能是 64。扩频因子按 64 写、码长按 7 生成、代码里再靠repmat补到 64三层数字互相打架实际生效的扩频比可能是 4 也可能是 7处理增益算出来完全对不上。解决把扩频因子改成 63处理增益如实写 10log10(63)18.0 dB如果任务书硬性要求 64就换 64 阶 WALSH 码并在报告里说明「采用正交码而非 m 序列处理增益 18.06 dB」。数字差 0.06 dB 没人计较前后不自洽才是硬伤。5.3 现象波形看着像调幅频谱图上搬移位置不对原因fc越过fs/2采样后发生混叠。归一化时间单位下这个问题尤其隐蔽因为fs和fc都是无量纲数字量级差十倍也不影响代码运行。解决在参数初始化段落加一条断言fc fs/4让它在脚本一开始就崩而不是等到画频谱图才发现。同时把所有频率量统一写成码片速率的整数倍物理意义清楚量级也不会错。5.4 现象SNR 提高BER 反而在某一段变差原因awgn的measured模式按输入信号的实际功率加噪而信号经过滤波器之后功率已经被衰减过如果在滤波之后调用awgn噪声基准就跟着变了。另一种情形是不同 SNR 点用了不同的信号功率基准曲线自然不单调。解决只在发射端加一次噪声接收端全程不再加噪或者在每个 SNR 点先计算bandpower(txRF)用measured模式时保证输入始终是同一段未滤波的信号。5.5 现象BER 曲线抖动大10^-3 以下全是 0 或者 1原因统计样本太少。5000 个比特在 BER10^-3 时平均只有 5 个错误统计涨落能到 40% 以上画出来就是一条锯齿。解决低 BER 段每个 SNR 点至少跑 10^5 个比特或者只统计到 10^-3 就停报告里注明「10^-3 以下样本不足未作统计」。与其画一条假的光滑曲线不如老老实实标出置信区间答辩时反而是加分项。6. 答辩验收用三条自证曲线把「跑通了」变成「做对了」验收这件事重点不在代码有多长而在能不能用三张图把「这条链路是对的」讲清楚。我一般要求学生准备下面三条曲线缺一条就说明链路里还有没对齐的地方。曲线横轴纵轴通过标准波形对齐图时间35 个比特幅度信源与解调输出的跳变沿逐个对齐无整体平移BER 对比图SNR / dB误码率对数仿真点与0.5*erfc(sqrt(ebn0))理论线偏差 1 dB处理增益图带内 SNR / dB误码率扩频与不扩频两条线间距接近 10log10(SF)第一条曲线最简单也最能唬人。把信源bits和解调输出bitsHat画在同一张图上用不同线型叠起来如果两条线的跳变沿严丝合缝说明从映射到判决的整条路径没有引入延迟如果整体错开一个比特那就是reshape维度反了或者积分窗口偏了一位。这一张图放在报告第一页比十页公式更有说服力。第二条曲线要对上理论。BPSK 在 AWGN 下的误码率是0.5*erfc(sqrt(Eb/N0))把仿真点画上去偏差在半 dB 以内就算合格。偏差超过 1 dB 通常是滤波器带宽太窄把有用边带切了或者awgn的功率基准不对。第三条曲线是这套仿真的核心结论所在。在同一带内 SNR 下扩频系统的 BER 明显低于不扩频的 BPSK两条线的间距应该接近处理增益 18 dB——这是因为解扩把噪声带宽压缩回了信息带宽。但如果把横轴从「带内 SNR」换算成「Eb/N0」两条线应当完全重合因为扩频本身不改变每比特能量与噪声谱密度之比它改变的是抗窄带干扰和抗多径的能力。这一点讲不清楚答辩时被追问「既然一样扩频有什么用」整套仿真就白做了。ebn0 snrList - 10*log10(fs/(2*Rc)); % 带内 SNR 换算到 Eb/N0 berTh 0.5*erfc(sqrt(10.^(ebn0/10))); semilogy(snrList, ber, o-, snrList, berTh, k--); legend(仿真,理论); grid on;从那以后我每次交仿真报告前都会先把这三条曲线跑一遍再动笔——波形对不上就不写结论理论线贴不上就不写增益两条线换算之后不重合就不写「扩频提升抗干扰能力」。这套动作花不了二十分钟却能挡掉答辩现场绝大多数追问。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →