
简介这是一份围绕CDMA通信系统仿真与实现的完整毕业论文文档面向通信工程、电子信息类专业学生及需要入门扩频通信的研究者。内容系统介绍码分多址技术作为3G核心的工作原理、码分与多址两种基本技术并结合MATLAB展开两路信号扩频、混合、加噪、解调与信号分离的完整仿真流程通过误码率、波形图与频谱图对系统性能进行分析、改进与调试既展示CDMA抗干扰与多址通信的核心机制又提供了MATLAB通信系统仿真的具体实践路径可作为毕业设计写作框架和仿真方法的重要参考。资源为单个doc文件压缩包大小1.99MB包含中英文摘要、目录与正文结构完整便于直接查阅。已有127人学习下载适合需要撰写通信方向毕业论文或系统学习CDMA仿真的读者。1. 这个毕业论文题到底在做什么MATLAB 里的 CDMA 仿真不是把 3G 协议栈搬进来很多人一看到“CDMA 通信系统的仿真与实现”下意识以为要把 WCDMA 那套编码、交织、功控、切换全做进 MATLAB。实际上去翻几篇同类毕业论文就会发现题目里说的 CDMA几乎都是指直序扩频DS-CDMA的基带链路仿真发端把每个信息比特用一串高速码片扩频收端用同一串码片解扩中间加上噪声和多径最后用误码率曲线说明系统性能。它能解决的是在没有硬件平台的条件下把“扩频增益、PN 码同步、RAKE 接收”这些概念讲清楚并且产出可复现的仿真结果。适合通信工程毕设、考研复试讲项目、以及刚入职想补扩频基础的从业者。我通常给学生的第一句话是先别想着做多复杂把 63 个码片的直扩链路跑通这篇论文的地基就打好了。2. 从 m 序列到相干解扩搭一条最小 CDMA 收发链路2.1 为什么先定处理增益仿真里的关键参数怎么选DS-CDMA 仿真里有三个参数必须在一开始就定死处理增益也叫扩频因子、PN 码周期、以及一次仿真跑多少个比特。处理增益在码片级仿真里就是“一个信息比特对应多少个码片”常用 sfspreading factor表示。它直接决定带宽扩展倍数也决定解扩后信噪比的提升量。毕设里最常见的选择是 sf 63对应 6 级移位寄存器产生的 m 序列周期正好是 2^6 - 1 63一个信息比特刚好承载一个完整 PN 周期接收端做相关积分时不需要跨周期拼接实现最干净。选 63 而不是 15、31、127理由很实际处理增益太小如 15扩频带来的抗干扰效果弱论文里的 BER 曲线和 BPSK 差距不明显太大如 127仿真量成倍上涨而性能曲线本质上只是把横轴平移并不产生新结论。63 这个值在 CDMA 教学里最常用答辩时也最容易解释。码片速率在基带等效仿真里不需要真实设置因为误码率只和 Eb/N0 有关和绝对速率无关。但论文里一般会补一句假设码片速率 1.2288 McpsIS-95 的典型值处理增益 63则信息速率约 19.5 kbps这样显得你清楚带宽和时间尺度的关系。另一个常被忽略的是调制方式。DS-CDMA 收端相干解扩通常配 BPSK因为 BPSK 的相干解调实现简单扩频前后的星座点只有 ±1 两个值解扩后软判决量直接对应极性。QPSK 或更高阶调制也能做但毕业论文里多一个星座旋转、相位模糊的问题容易把重点带偏。我一般建议把 BPSK 跑通后再提 QPSK 扩展。2.2 发射端代码m 序列生成、扩频与 BPSK 调制发射端的核心是两步生成 PN 码然后把每个信息比特和 PN 码逐码片相乘。下面这段代码先用通信工具箱的 comm.PNSequence 生成 63 个码片的 m 序列再做扩频和 BPSK 调制。% 系统基本参数 sf 63; % 处理增益1 比特对应 63 个码片 numBits 5000; % 每轮仿真的比特数BER 统计需要足够样本 % 生成 m 序列本原多项式 x^6 x^4 x^3 x 1 pnGen comm.PNSequence( ... Polynomial, [6 4 3 1 0], ... InitialConditions, [1 0 0 0 0 0], ... SamplesPerFrame, sf); pn0 pnGen(); % 输出是 0/1 序列长度 sf pn 2 * pn0 - 1; % 转成双极性 ±11 对应 10 对应 -1 % 随机信息比特0/1 data randi([0 1], numBits, 1); % 双极性 BPSK0 - -11 - 1 dataBpsk 2 * data - 1; % 扩频把每个比特复制成 sf 个码片再逐位乘上 PN 码 spreadMat repmat(pn, numBits, 1); % numBits x sf每行都是同一段 PN 码 txChips dataBpsk .* spreadMat; % 每个比特的极性决定了码片取正还是取反 tx txChips(:); % 按列展开连续码片流长度 numBits*sf逻辑说明repmat 把长度为 63 的 PN 码复制成 numBits 行每行都是同一个 PN 周期。dataBpsk 是列向量和 spreadMat 做点乘时自动广播第 k 行的 63 个码片就是 dataBpsk(k) 乘上整段 PN 码。这一步正是直扩的本质信息比特的宽度被压缩到 1/63能量被铺开在 63 个码片上。tx 是按列展开的码片流它和后面接收端的 reshape 必须保持同样的排列顺序否则解扩结果会乱。参数说明Polynomial 写成 [6 4 3 1 0] 表示 x^6 x^4 x^3 x 1最后一个 0 对应常数项 1。InitialConditions 长度必须等于移位寄存器级数 6全 1 也可以但不能全 0否则序列出不来。SamplesPerFrame 设为 sf 是为了让每个信息比特恰好对应一个完整的 m 序列周期这样收端相关峰值稳定不会出现半个周期参与积分的问题。注意 matlab 的:展开顺序是列优先所以 txChips(:) 得到的是第 1 个比特的 63 个码片、第 2 个比特的 63 个码片……依次排列接收端 reshape 时也要按同样的列优先规则还原。2.3 接收端解扩与 AWGN 信道积分解调的数学与落地接收端做的事情和发射端相反把收到的码片流按 sf 个一组切分每组和本地 PN 码做相关累加得到一个软判决量再判 0 或 1。从数学上看发送的码片是 d(k) * pn(n)其中 d 是第 k 个比特的极性收端本地乘以 pn(n) 再累加 63 个码片PN 码的极性被乘掉剩下 d(k) * 63 再加噪声项。噪声每码片独立且方差相同累加后噪声功率增加 63 倍信号幅度也增加 63 倍信噪比正好提升 63 倍也就是 18 dB 的处理增益。% AWGN 信道先把比特能量算清楚 Eb sf; % 码片能量归一化为 1一个比特能量 sf * 1 EbN0dB 8; EbN0 10^(EbN0dB / 10); N0 Eb / EbN0; % 噪声单边功率谱密度 sigma2 N0 / 2; % 实通道 BPSK每个维度噪声方差取 N0/2 noise sqrt(sigma2) * randn(size(tx)); rx tx noise; % 解扩按比特分组每列是一组 63 个码片 rxMat reshape(rx, sf, numBits); % 相关积分pn * rxMatpn 是列向量结果是 1 x numBits 的软判决量 soft pn * rxMat; % BPSK 判决软判决小于 0 判为 0否则判为 1 dataHat soft 0; % 误码率 ber sum(dataHat ~ data) / numBits;逻辑说明Eb sf 这一行是整段代码最容易出问题的地方。码片能量归一化为 1也就是每个码片的幅度平方为 1那么一个比特的 63 个码片总能量就是 63。噪声方差 sigma2 取 N0/2是因为 BPSK 是实通道单边谱密度 N0 分布在正负频率上实际在实信号上的噪声方差是 N0/2。很多论文里 BER 曲线差 3 dB就是这里把 N0 当方差用等于噪声功率多给了 3 dB。参数说明reshape(rx, sf, numBits) 的列优先顺序和发射端 txChips(:) 的展开顺序是一一对应的第 1 列是第 1 个比特的 63 个码片第 k 列是第 k 个比特的码片。pn * rxMat 是 1×63 乘以 63×numBits得到 1×numBits 的软判决向量。soft 的正负号来自 dataBpsk 的极性发送 1 时 soft 约等于 63发送 -1 时约等于 -63噪声会让它偏离但只要噪声不超过信号幅度 63判决就不会错。这个信号累加 63 倍、噪声累加 sqrt(63) 倍的对比是答辩时被问到处理增益为什么是 18 dB的标准答案。3. 把 BER 仿真跑通Eb/N0 扫描、噪声注入与误码统计3.1 仿真框架怎么写一次仿真只跑一个 Eb/N0 点误码率仿真的标准做法是扫多个 Eb/N0 点每个点独立做一次蒙特卡洛实验。原因很简单不同 Eb/N0 下误码率可能差好几个数量级混在一个仿真里既没法统计也没法控制每个点的置信度。我习惯写成下面这种结构把收发链路封装成一个函数主脚本只负责循环和画图。function ber runCdmaSim(sf, numBits, EbN0dB, pn) % 参数sf 处理增益numBits 比特数EbN0dB 当前信噪比pn 本地 PN 码 data randi([0 1], numBits, 1); dataBpsk 2 * data - 1; spreadMat repmat(pn, numBits, 1); tx (dataBpsk .* spreadMat); % numBits x sf txStream tx(:); Eb sf; N0 Eb / (10^(EbN0dB / 10)); sigma2 N0 / 2; rx txStream sqrt(sigma2) * randn(size(txStream)); rxMat reshape(rx, sf, numBits); soft pn * rxMat; dataHat soft 0; ber sum(dataHat ~ data) / numBits; end % 主脚本 EbN0dBVec 0:2:10; berSim zeros(size(EbN0dBVec)); pnGen comm.PNSequence(Polynomial, [6 4 3 1 0], ... InitialConditions, [1 0 0 0 0 0], SamplesPerFrame, 63); pn 2 * pnGen() - 1; for k 1:length(EbN0dBVec) berSim(k) runCdmaSim(63, 50000, EbN0dBVec(k), pn); fprintf(Eb/N0 %.1f dB, BER %.3e\n, EbN0dBVec(k), berSim(k)); end % 理论 BPSK 曲线 berTheory qfunc(sqrt(2 * 10.^(EbN0dBVec / 10))); semilogy(EbN0dBVec, berSim, o-, EbN0dBVec, berTheory, s-); grid on; xlabel(Eb/N0 (dB)); ylabel(BER); legend(CDMA 仿真, 理论 BPSK);逻辑说明runCdmaSim 每次调用都重新生成随机数据、噪声和误码统计主循环只改 EbN0dB。把随机数据放在函数内部是为了保证每个信噪比点的数据独立。仿真中 numBits 的取值对结果稳定性影响很大如果某个 Eb/N0 点误码率是 1e-3理论上要 5 万比特才能看到约 50 个误码统计方差才比较小。所以上面的代码用 50000 而不是最开始的 5000这一点在 5.4 节还会展开。参数说明EbN0dBVec 从 0 dB 扫到 10 dB 是毕设常用的区间。0 dB 时误码率约 0.0810 dB 时约 7.8e-6跨度足够画出一条从 1e-1 到 1e-5 的曲线。如果想看更低误码率把 EbN0dBVec 的终点提到 12 dB但 numBits 要相应加大到 1e5 以上否则曲线尾部会剧烈抖动。3.2 Eb/N0 与噪声功率怎么换算仿真里最容易错的 3 dB噪声注入的正确顺序是先算比特能量 Eb再算 N0最后除以 2 得到实噪声方差。这里的物理背景是N0 是单边功率谱密度而 matlab 的 randn 产生的是双边功率谱的白噪声方差等于 N0/2。如果直接写 noise sqrt(N0) * randn(...)等于噪声功率加倍BER 曲线会比理论值差约 3 dB。还有一个同样隐蔽的问题码片能量归一化。很多初学者把每个码片幅度设成 1然后在信道代码里又对 tx 做了一次功率归一化导致 Eb 不再是 sf实际发射功率变小BER 曲线同样偏移。我的经验是发射端码片幅度直接定为 ±1不去归一化因为 BPSK 星座点到原点的距离就是 1能量就是 1归一化反而多此一举。如果你在链路里加了脉冲成形滤波器或过采样才需要重新算每码片能量码片级仿真里不需要。检查 Eb/N0 换算有没有做对有一个快速方法在 Eb/N0 0 dB 时仿真 BER 应当接近 0.076也就是 qfunc(sqrt(2 * 1)) 的值。如果差异超过 10%先查 sigma2 的写法再查 Eb 是否等于 sf。3.3 和理论 BPSK 曲线对比判定 CDMA 仿真是否正确的标尺单用户、理想同步、AWGN 信道下的 DS-CDMA解扩后的误码率理论上和 BPSK 完全一致。因为扩频加解扩是一对可逆操作发送端把能量铺开接收端把它收拢信息论上没有损失。所以第 3 章代码里和理论 BPSK 曲线对比并不是为了证明 CDMA 比 BPSK 好而是为了验证仿真链路本身的正确性。只要仿真曲线和理论曲线在统计误差范围内重合说明发射、信道、接收三段的极性、能量、判决都对了。这一点在论文里要主动写清楚否则答辩老师问你你的 CDMA 仿真曲线为什么和 BPSK 一样你答不上来就很尴尬。可以写单用户直扩系统的 BER 理论上限就是 BPSK 的匹配滤波性能CDMA 的优势体现在抗多径、抗窄带干扰、多址复用上而不是单用户 AWGN 下的链路更优。这也是后面第 4 章要做 RAKE 的原因。4. 多径信道与 RAKE 接收论文里拉开差距的部分4.1 两径信道模型时延、抽头增益与码间干扰AWGN 下的单用户 CDMA 太干净论文只做到这一层很难出彩。多径是 CDMA 最经典的卖点信号经过两条以上路径到达接收端每条路径有不同时延和衰减。在码片级仿真里最简单也最好解释的模型是两径第一径增益归一化为 1第二径增益取 0.5 或 0.3时延取整数个码片。时延必须和 PN 码周期对照着选我一般取 25 个码片太小时延1 个码片第二径几乎和主径重叠RAKE 分不开太大时延接近 sf会让相关峰落在 PN 码自相关函数的旁瓣上反而产生干扰。% 两径信道主径增益 1第二径增益 0.5时延 2 个码片 d 2; h [1, 0.5]; % 构造延迟两个码片的发射信号 txDelayed [zeros(d, 1); txStream(1:end-d)]; % 信道输出主径加第二径再加噪声 rx txStream 0.5 * txDelayed sqrt(sigma2) * randn(size(txStream));逻辑说明txDelayed 前面补两个零相当于第二径比主径晚到 2 个码片。rx 里同时存在未延迟的码片流和延迟 2 个码片的衰减副本这个叠加就是码间干扰的来源——某个比特的第 n 个码片会叠加下一个码片或下一个比特的内容。如果不用 RAKE直接拿整段 rx 做解扩PN 码的自相关特性会把一部分多径干扰抑制掉但不能完全消除BER 曲线会出现明显的高信噪比平底。参数说明时延 d 的单位是码片因为整个仿真没有引入采样率概念一个样点就是一个码片。如果论文想更严谨可以写成 d floor(tau * fc)其中 tau 是物理时延fc 是码片速率。第二径增益 0.5 意味着这条路径的能量只有主径的四分之一合并时权重也会按这个比例关系调节。要注意边界效应txDelayed 末尾被截掉的 2 个样点只是损失最后 2 个码片对 50000 比特的整体误码率影响极小可以不做边界补偿。4.2 RAKE 接收的实现每径相关、加权合并RAKE 的思路不是去消除多径而是把多径当成多份信号能量收集起来。对每一径先用对应的时延对齐本地 PN 码做一次相关累加得到该径的软判决量再把所有径的软判决量按信道增益加权求和。因为 PN 码的自相关函数在零时延处是尖峰、在其他时延处接近零每一径相关器能把自己的那部分能量提取出来同时抑制其他径。% RAKE 接收分别对主径和第二径做相关 % 注意 rx 是列向量先按比特分组 rxMat reshape(rx, sf, numBits); % 主径相关和发射端一样从第 1 个码片开始 soft0 pn * rxMat; % 第二径相关由于第二径延迟 2 个码片本地 PN 码要相对前移 2 个码片 pnShift circshift(pn, d); % 循环移位将 PN 码右移 d 位 soft1 pnShift * rxMat; % MRC 合并按信道增益共轭加权 softComb conj(h(1)) * soft0 conj(h(2)) * soft1; dataHat real(softComb) 0; berRake sum(dataHat ~ data) / numBits;逻辑说明软判决量 soft0 和 soft1 都是复数形式这里虽然实信道没有复数增益但写成 conj(h) 可以保留扩展性——如果后面把信道改成带相位偏移的复数衰落模型这段代码不用大改。soft1 用的是 circshift(pn, d)让本地码片和收到的第二径对齐。这个循环移位体现了 PN 码同步的核心接收端必须知道每条径的准确时延并把本地码片挪到对应位置。论文里常把这一过程写作码片同步与时延估计仿真是直接给定真值工程上要用滑动相关来估。参数说明d 2 的循环移位方向要和信道模型保持一致。信道里 txDelayed [zeros(d,1); tx(1:end-d)]表示第二径晚到那么本地码片应该相对提前也就是把 pn 循环右移 d 个位置。如果方向和实际相反soft1 会变成 PN 码自相关旁瓣合并后信噪比反而下降。MRC 合并要求每径权重与信道增益匹配主径 1、第二径 0.5代表接收端已知信道信息这在仿真里是可以直接给的。做毕设时我会再补一段未知信道参数下的滑动相关时延估计让论文更完整。4.3 EGC 与 MRC 的取舍仿真参数怎么调RAKE 合并有等增益合并EGC和最大比合并MRC两种常见形式。EGC 把所有径的软判决量直接相加权重都是 1MRC 按信道增益的共轭加权增益大的径贡献更大。在 AWGN 加静态两径信道里MRC 是最优的能让你在 BER 曲线上看到比单径 AWGN 更陡的下降趋势。因为第二径提供了额外能量等效接收信噪比提高曲线会向左偏移。具体偏移量约等于 10*log10(1 |h2|^2)第二径增益 0.5 时大约偏移 1 dB 左右。% EGC 对比权重全是 1 softEgc soft0 soft1; berEgc sum(real(softEgc) 0) / numBits; % MRC 对比权重分别是 1 和 0.5 softMrc 1.0 * soft0 0.5 * soft1; berMrc sum(real(softMrc) 0) / numBits;参数说明第二径增益从 0.5 改到 0.8 时MRC 相对 EGC 的优势会变大改成 0.2 时两者几乎一样因为弱径本身贡献小。时延 d 的选择也会影响结果d 太小两个相关器提取的能量有重叠合并增益下降d 太大PN 码旁瓣泄漏增加性能反而变差。我一般会画一张 BER 随 d 变化的曲线从 1 扫到 10 个码片论文里用这张图说明RAKE 对时延的敏感性比只用一条 BER 曲线更有说服力。注意 MRC 的权重在仿真里是理想值实际系统要估计信道增益所以 4.2 节代码里的 conj(h) 可以保留但要配合信道估计一起讲。5. 避坑CDMA 仿真常见的 5 个翻车现场5.1 误码率比理论曲线高 3 dBEb/N0 换算错误现象仿真 BER 曲线和理论 BPSK 曲线形状一致但整体向右偏了约 3 dB。低信噪比处还不太明显越高越明显。原因噪声方差写错。最常见的是 noise sqrt(N0) * randn(size(tx))把单边谱密度 N0 直接当成了噪声功率。BPSK 是实信号匹配滤波后噪声方差是 N0/2。另一个原因是 Eb 算错比如忘记乘处理增益 sf把码片能量当比特能量相当于少算了 18 dB 的发送能量曲线会偏得离谱不只是 3 dB。解决统一写成 sigma2 N0/2N0 Eb / 10^(EbN0dB/10)Eb sf * EcEc 是每码片能量。如果用了脉冲成形或过采样还要把滤波器能量算进去。改完之后在 Eb/N0 0 dB 处做单点校验仿真 BER 若在 0.070.08 范围内说明换算基本正确。5.2 误码率在高信噪比下不下降PN 码相位与周期问题现象仿真曲线在低信噪比段和理论曲线重合但到 8 dB 以上开始出现平台从 1e-4 再往下就压不下去像一条水平的尾巴。原因PN 码没有和比特边界对齐。比如直接用 randn 长度等于 numBits*sf 的本地 PN 序列去对接收信号做相关但发射端每个比特都是从 PN 码起点开始两个序列的相位差导致相关积分里混入了旁瓣泄漏。另一种情形是 m 序列周期不是 sf或者采样率不是整数倍码片速率实际参与积分的码片数不对。解决把 PN 码做成周期重复的序列每个信息比特都从同一相位开始。用 comm.PNSequence 时把 SamplesPerFrame 设为 sf发射端用 repmat 复制收端本地码片固定用同一段 pn。如果要模拟非整数时延先在物理层把码片过采样到 4 倍以上再做延迟不要试图在整数码片模型里硬凑。5.3 多径仿真结果异常时延没有按码片对齐现象加了两径信道后BER 曲线比单径还差或者 RAKE 合并后性能没有任何改善甚至比不加 RAKE 更差。原因第二径时延在仿真里写成小数比如 0.5 或 1.7但码片级模型里每个样点就是一个码片小数时延无法表示。这时你会下意识用 round 取整结果真实时延和本地 PN 码相位对不上RAKE 相当于用错误的本地码片做相关。解决码片级仿真只接受整数时延且 d 必须和 circshift 的移位位数一致。想模拟更真实的非整数时延就把链路改成过采样结构每码片 4 个采样点发射端对码片流做脉冲成形接收端先做匹配滤波再做码片同步然后进入解扩。这个工程量比整数时延大不少毕设里如果只是验证 RAKE 原理用整数时延即可论文里可以加一句实际系统采用码片同步与分数时延估计这里为简化采用整数码片时延。5.4 仿真跑起来太慢逐比特循环拖死了整个脚本现象一段代码用 for 循环逐比特生成码片、逐比特算相关仿真 50000 比特加多径时要跑好几分钟扫描 6 个 Eb/N0 点要等半小时以上。原因MATLAB 是向量化语言for 循环每迭代一次就做一次矩阵拼接、函数调用和内存分配逐比特循环开销极大。尤其是 63 个码片的点乘循环执行 50000 次远慢于一次 50000×63 的矩阵运算。解决把所有比特一次性构造成 numBits×sf 的矩阵用 repmat 扩频、reshape 展开、矩阵乘法做相关正如第 2、3 章的代码。还要注意避免在仿真主循环里重复生成 PN 码把 pn 作为参数传入函数而不是在每轮 Eb/N0 扫描里重新调用 comm.PNSequence。如果还想更快可以把跑 6 个 Eb/N0 点的循环换成 parfor通信工具箱对象在 parfor 里通常能正常使用但需要确保每个 worker 都能访问 pn 变量。5.5 答辩时被问性能提升不明显单用户理想同步的尴尬现象论文里只有单用户 AWGN 和单用户两径两条 BER 曲线看起来和 BPSK 区别不大答辩老师问你的 CDMA 到底提升了什么现场答不上来。原因单用户、理想同步、无干扰的直扩系统确实不会比 BPSK 更好它的抗干扰优势要在有窄带干扰、多径、多用户竞争的背景下才能体现。前期仿真时没有把这些场景加进去导致题目叫 CDMA 通信系统内容却只是 BPSK 加扩频。解决在第 4 章两径信道的基础上做 RAKE给出 MRC 相对单径的性能增益再加一个单用户加窄带干扰的仿真展示扩频处理增益对干扰的抑制效果如果时间允许做 23 个用户的 Gold 码多址仿真用误码率和眼图说明相互干扰随用户数上升。这些扩展不需要大改链路只需改 PN 码管理和干扰注入部分却能把论文的论据补完整。6. 让毕业设计仿真更有说服力验证手段与三个扩展方向6.1 验证手段星座图、眼图和蒙特卡洛次数仿真曲线出来后先别急着截图放进论文。我会做三个验证第一把理论 BPSK 曲线、AWGN 仿真曲线、RAKE 仿真曲线画在同一张坐标里若前两者在统计误差内重合链路正确性就有保障第二在 Eb/N0 6 dB 时画出解扩前的码片星座图和解扩后的软判决直方图能直观看到处理增益把 63 个点的极性累加成两个清晰团簇第三用误码数的 95% 置信区间估算蒙特卡洛次数目标误码率 1e-3 时至少跑 10 万个比特保证有约 100 个误码数曲线尾部才不抖。6.2 扩展方向Gold 码多用户、功率控制与新版工具箱如果时间还有富余优先做 Gold 码多用户仿真。Gold 码由两个 m 序列优选对模 2 加得到互相关特性比 m 序列好更贴近 CDMA 多址场景。实现上只需把每个用户的 PN 码换成不同 Gold 码发射端叠加发射接收端用目标用户的码片解扩其余用户信号由于互相关接近零而被抑制。此时你会清楚看到近远效应功率大的用户会把功率小的用户压下去顺势引入开环功率控制让各用户到达基站功率一致BER 曲线立刻改善。另一个要注意的是 MATLAB 版本。手头如果是 R2024b 之后的版本通信工具箱里 comm.PNSequence 仍在维护但部分老教程里的pnsequence对象或hadamard相关函数接口可能变化。装新版 MATLAB 后先跑一个最小 PN 码示例确认函数输入参数格式再写全链路。我在 R2023b 和 R2025a 上都跑过上面这段代码核心逻辑没有兼容性问题只有 MATLAB 自动缩进和工具箱警告的差异。最后说个我自己的血泪经验第一次做这个仿真时我花了一整周调 BER 曲线怎么都不对后来发现是第 3 章那个 3 dB 问题。从那以后我每写一段仿真第一件事就是把理论曲线和仿真曲线叠在一起看而不是先调参数碰运气。验证链路正确性比调参数更值得花时间这个习惯帮我后面少踩了很多坑。希望帮到你。本文还有配套的精品资源点击获取