news 2026/9/26 13:03:33

多路复用与多址技术详解:从FDM、TDM到CDMA的工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多路复用与多址技术详解:从FDM、TDM到CDMA的工程实践

简介:这份资源是一份《通信原理》第6章“多路复用和多址技术”的教学课件,适合通信工程、电子信息类专业的学生和教师用于课堂讲解、考前复习或备课参考。内容从多路复用的基本概念与信号正交性出发,系统梳理频分复用、时分复用、码分复用、空分复用、极化复用和波分复用等常见方式,并重点展开FDM在模拟电话、调频立体声广播中的应用,以及TDM的抽样原理与系统结构。课件配有原理图、系统方框图和频带分配示意,便于对照理解抽象概念。资源共1个pptx文件,压缩包约683KB,体积较小,便于下载和在线浏览。目前已有228人学习使用,适合需要快速掌握多路复用核心知识点的初学者或备考生。

1. 多路复用与多址技术:一条信道扛不住一个城市,但这章能

做通信系统的人都有个共同记忆:第一次看完第 6 章,才明白一根光纤、一段频段为什么能同时服务上千路电话和几万个手机用户。多路复用解决的是“一条物理信道怎么同时承载多路信号”的问题,多址技术则把这个问题从链路拉到了系统级——多个用户、多个站点怎么共享同一份资源而不互相踩脚。这个 PPT 是通信原理课程的承上启下之作,前面几章讲的调制、编码都是“点对点”,到了这一章才开始面对真实世界的容量压力。适合正在啃通信原理、准备期末或考研的本科生,也适合刚入行做通信算法、需要把频分时分码分概念落成代码的初级工程师。这一章不把用户的信号做出来,后头的系统设计根本没法定参数。

2. 频分复用 FDM 与频分多址 FDMA:频率切得越细,越要先留好缝

2.1 频分复用的频率规划:保护带宽不是浪费,是保命

频分复用的核心操作一句话就能说清:把信道的可用频带按频率切成若干子带,每路信号调制到不同的载波频率上,大家同时传、互不干扰。模拟电话时代一路话音带宽 4kHz,一条 60 路 FDM 群链路就得占 240kHz 左右的频带,但这里有个关键点:不能用 4kHz 乘以 60 就算总带宽。每路信号经过调制后,频谱不是像刀切一样利落的矩形,实际频谱边缘带着滚降特性,相邻两路的频谱尾部会拖进对方的频带里,这就是邻路干扰的来源。所以工程上每两个子带之间必须留保护带宽,也叫 guard band,宽度取多少取决于两个因素:发送端滤波器的滚降系数 α,以及接收端本振频率的稳定度。

做工程的人拿到一个 FDM 系统的频率规划需求,第一件事不是去翻教科书上的频率分配表,而是先定滤波器滚降系数。常用升余弦滤波器的 α 在 0.2 到 0.5 之间,α 越大滚降越缓,频谱尾部拖得越长,保护带宽就得留得越宽。另一方面,如果收发两端用独立晶振,频率偏差可能到几十赫兹甚至上百赫兹,保护带宽至少要把这个偏差量兜住。早期模拟 FDM 系统里,保护带宽经常占到整个子带宽的 20% 到 40%,那个年代频谱资源看起来“够用”,没人觉得心疼。

  • 升余弦滚降系数 α 决定带外衰减速度,α=0.2 时相邻通道最小间隔约为符号速率的 1.2 倍;
  • 振荡器频率稳定度如果只有 10ppm,在 2GHz 载波上就是 20kHz 的漂移,保护带宽低于这个数就等着串话;
  • 接收端中频滤波器的选择性也参与决定保护带宽,矩形系数做不到 1,过渡带必须靠保护带宽兜住。

2.2 用 Python 看两路信号频谱搬移后的重叠情况

讲解频分复用最直白的办法是用 Python 做一次频谱搬移仿真,把两路基带信号分别调制到不同载波上,直接看合成信号的频谱。这个过程跑通了,FDM 的原理就钉在脑子里了。下面这段代码能直接运行,用来观察 5kHz 和 12kHz 两个载波上信号的频谱分布:

import numpy as np import matplotlib.pyplot as plt # 参数设置 fs = 100000 # 采样率 100kHz duration = 0.05 # 仿真时长 50ms t = np.arange(0, duration, 1/fs) # 两路基带信号:频率分别 800Hz 和 1.5kHz base1 = np.sin(2 * np.pi * 800 * t) + 0.3 * np.sin(2 * np.pi * 1600 * t) base2 = np.sin(2 * np.pi * 1500 * t) + 0.2 * np.sin(2 * np.pi * 3000 * t) # 调制到 5kHz 和 12kHz 载波 f_c1, f_c2 = 5000, 12000 mod1 = base1 * np.cos(2 * np.pi * f_c1 * t) mod2 = base2 * np.cos(2 * np.pi * f_c2 * t) s_u = mod1 + mod2 # 复用后的合成信号 # 做 FFT 观察频谱 spectrum = np.fft.fft(s_u) freqs = np.fft.fftfreq(len(t), 1/fs) half = len(freqs) // 2 plt.figure(figsize=(10, 4)) plt.plot(freqs[:half], 20*np.log10(np.abs(spectrum[:half]) + 1e-10)) plt.title("FDM 信号的频谱:两路信号搬移到不同载波") plt.xlabel("频率/Hz") plt.ylabel("幅度/dB") plt.ylim(-120, 10) plt.grid(True) plt.show()

这段代码的逻辑是:先生成两路不同频率成分的基带信号,再分别乘以不同频率的余弦载波实现频谱搬移,最后直接相加。这里的关键参数是载波频率的选择——两路载波 5kHz 和 12kHz 相差 7kHz,而两路调制后的信号谱宽分别约 3kHz 和 6kHz,加在一起占不满这 7kHz 的间隔,所以频谱图上能看到两个清晰的峰。如果你把第二路载波改到 7kHz,让两路信号频谱边缘贴在一起,就能直观看到重叠带来的干扰。

需要提醒的是:仿真里直接相乘就是理想乘法器输出,没有加入升余弦滤波器,所以频谱旁瓣很高。在真实系统里,调制前先得把基带信号过一遍成型滤波器,调制后再过一遍带通滤波器,否则旁瓣能量直接落到邻路里。教科书上只画理想的频谱搬移图,做题可以,做系统不行。

2.3 从 FDM 到 FDMA:复用与多址的分界线在哪

很多初学者把 FDM 和 FDMA 当成同一个东西,这要从工程角度看清楚。FDM 解决的是“多个基带信号如何复用成一路群信号”,它在物理层完成,关注的是波形和频谱。FDMA 解决的是“多个用户或站点如何接入同一段频谱资源”,它站在资源分配层面,关注的是把频率切分成信道,再把这些信道分配给不同用户。一个典型的 FDMA 系统可以在一段 30kHz 带宽上划分 6 个 5kHz 信道,每个信道就是一个用户的专用资源,用户之间在频率上天然隔离。FDM 是 FDMA 的实现基础,但 FDMA 还包含信道分配策略、信道切换逻辑等系统层面的东西。

做卫星通信项目时我常遇到类似说法:某系统说自己是 FDMA,实际上用户落地时就是每个站点锁定一个载波频率,中心站给每个远端站分配一个频点,这和微波中继里的 FDM 群链路是两套逻辑。区分要点在于:FDM 更接近“复用器”的实现细节,FDMA 更接近“系统资源怎么分”的规划。这个区别放在第 6 章的课后题里经常被考,放在工程里直接影响你提技术方案时怎么描述系统架构。

2.4 频分多址的五个必调参数:带宽、载波间隔、滚降、发射功率和频率稳定度

跑一个 FDMA 链路的链路预算时,核心参数就五样:

参数含义典型取值调错后果
信道带宽每用户占用的标称带宽模拟语音 4kHz / 数字语音 12.5kHz 或 25kHz带宽过窄,接收滤波器截掉有用信号边缘
相邻信道间隔载波频率之差= 信道带宽 + 保护带宽间隔太小,邻路干扰抬底噪
滚降系数 α发射滤波器频谱成形0.2 ~ 0.5α 越大占用带宽越宽,α 太小波形振铃大
发射功率每载波功率取决于链路预算和互调要求功率过大多载波互调干扰严重
频率稳定度收发本振偏差通信系统要求 0.1ppm 以下偏差大于保护带宽就产生邻路泄漏

频率稳定度这个参数最容易在仿真里被忽略。仿真时收发载波频率是完全一致的,保护带宽留一点点就够。到了真实硬件上,两端的晶振各自漂移,如果总偏差超过了保护带宽,接收端的滤波器会把邻路信号一起放进来,结果就是本路信噪比急剧恶化但找不出原因。所以做频分系统,保护带宽的取值公式至少应该写成:载波间隔 ≥ 信号占用带宽 + 2×单边载波最大偏差 + 接收滤波器过渡带宽度。这个公式比教科书里的“信号带宽加个余量”要可靠得多。

3. 时分复用 TDM 与时分多址 TDMA:帧同步是共享时钟的马车

3.1 PCM30/32 帧结构拆解:E1 那条 2.048Mbit/s 是怎么算出来的

时分复用的基本概念一句话:把时间切成周期性的帧,每帧再切成若干时隙,每路信号轮流占用一个时隙。原理简单,但真正动手做 TDM 系统时,第一个关口是帧结构设计。在数字电话网长期实践中,PCM30/32 帧结构是绕不开的基准案例。每帧时长 125 微秒,因为语音采样率 8kHz,每个采样周期对应一帧。每帧分成 32 个时隙,编号 TS0 到 TS31。TS0 做帧同步,用于接收端捕捉帧起点;TS16 做信令传输;剩下 30 个时隙各承载一路 PCM 编码语音。每时隙 8bit,所以总速率是:8000 帧/秒 × 32 时隙 × 8bit = 2.048 Mbit/s,这就是 E1 的由来。

这个帧结构里有三个关键设计逻辑值得仔细琢磨。第一个是同步开销占比:32 个时隙里拨了两个出来,占比 6.25%,换来的是接收端能精确找到每一路信号的起点,这个代价在工程上完全值得。第二个是帧同步字的选择:TS0 里固定发一个特定的同步码型,比如 0011011,接收端拿本地同步码和收到的比特流做相关,只有这个码型周期性出现的位置才是帧头。第三个是信令和数据分离:把 TS16 拨给信令,避免了早期 TDM 系统里在数据比特里插转义符的麻烦。

工程上做 TDM 设备调试时,最常看的定点就是帧同步状态。用误码仪打一个 E1 信号进去,接收端显示“失去帧同步”,问题往往不在帧结构本身,而在时钟精度。

3.2 用 Python 模拟多路语音的时分复用打包

理解帧结构最直接的办法是写一个打包器,把 4 路模拟信号分别采样、打包成 TDM 帧,再写一个解包器还原信号。代码不复杂,但把“时隙轮流插入”这个过程跑一遍,你对 TDM 的理解就从概念变成手感:

import numpy as np # 参数定义 fs = 8000 # 语音采样率 8kHz frame_period = 125e-6 # 一帧 125 微秒 samples_per_slot = 1 # 每个时隙放 1 个采样点 slots_per_frame = 4 # 本仿真用 4 个时隙,对应 4 路输入 # 生成 4 路短语音信号,每路 10ms duration = 0.01 n_samples = int(fs * duration) signals = [] for i in range(slots_per_frame): freq = 300 + 400 * i # 4 路信号频率不同便于区分 sig = np.sin(2 * np.pi * freq * np.arange(n_samples) / fs) signals.append(sig) # TDM 打包:按帧循环,从每路信号依次取一个采样点放入帧中 frame_count = n_samples # 每路 10ms 有 80 个采样点,即 80 帧 tx_stream = [] # 发射比特流(这里直接用浮点值代替 PCM 编码) for f_idx in range(frame_count): frame_data = [] for slot_idx in range(slots_per_frame): sample = signals[slot_idx][f_idx] frame_data.append(sample) # 这就是“时分复用”的核心:轮询插入 tx_stream.extend(frame_data) # TDM 解包:按同样帧结构还原 4 路信号 rx_signals = [[] for _ in range(slots_per_frame)] for f_idx in range(frame_count): base = f_idx * slots_per_frame for slot_idx in range(slots_per_frame): rx_signals[slot_idx].append(tx_stream[base + slot_idx]) # 还原误差检查 for i in range(slots_per_frame): err = np.max(np.abs(np.array(rx_signals[i]) - signals[i])) print(f"第 {i+1} 路最大还原误差: {err:.2e}")

这里最核心的一行是内层循环里frame_data.append(sample),它完成的操作就是每帧依次从每路信号取出一个采样值,构成一个时间上紧凑的帧。解包时按同样的索引规则把每个采样值送回对应的输出序列。如果打包和解包的帧对齐方式差一个采样点,还原出来的信号就是错位的,这在代码里表现为最大还原误差直接变成正常值的量级而不是 1e-15 级别。本仿真没有做 PCM 编码,直接用浮点值,省掉了量化噪声的干扰,让你专注于帧结构的对齐逻辑。

参数说明:fs=8000对应真实语音系统采样率,slots_per_frame=4是复用的路数,samples_per_slot在本仿真里固定为 1,对应真实系统里每个时隙只有 8bit。如果你要做更接近实际的设计,把samples_per_slot改成 8,每帧的数据就不是一个采样点而是一个采样字,帧结构复杂度会立刻上来——这就是真实 E1 系统和本最小仿真之间的差距。

3.3 从 TDM 到 TDMA:帧同步为什么是 TDMA 的命门

TDMA 在概念上几乎就是 TDM 的无线版本:给每个用户分配一个周期性重复的时隙,用户只在属于自己的时隙里发数据。但一到工程实施,TDMA 比 TDM 多出三个麻烦。第一是传播时延不确定,地面 TDM 系统收发两端通过线缆直连,信号到达时间基本固定;TDMA 系统里各用户离基站远近不一,信号到达基站的时刻相差很大,如果不做时隙对齐,后面用户发的信号会踩进前面用户的时隙。第二是帧同步的维持,基站需要周期性发送同步突发,所有用户以此为基准调整自己发信的提前量。第三是保护时隙,两个用户时隙之间要留出一段不发信号的时间,用来吸收残余的同步误差和信号传播时延变化。

做 TDMA 链路设计时,保护时隙的时间长度必须大于最大传播时延差加上用户设备同步误差的两倍。比如一个小区半径 30km 的 TDMA 系统,最大传播时延差约 100 微秒,设备同步误差若为 2 微秒,保护时隙至少要 104 微秒。很多刚开始做系统设计的工程人员只盯着时隙长度和帧效率,把保护时隙压到只有几个符号的时间,结果实测时邻时隙信号相互重叠,误码率永远下不去。保护时隙是 TDMA 系统的必要开销,压它是挤牙膏,不是技术优化。

3.4 时隙分配与同步建立:一个 TDMA 入网过程的四次握手

TDMA 系统里一个用户要开始传数据,不是想发就发。以典型的 TDMA 基站系统为例,用户设备入网要经历四步:先扫描下行控制信道,从基站广播的系统信息里读到时隙结构参数;然后在上行随机接入信道发出接入请求;基站收到请求后计算该用户到基站的传播时延,并在下行控制信道里回复“定时提前量”;用户根据这个提前量调整自己发信号的时刻,进入指定的业务时隙开始传数据。这个过程就是一个简化的四次握手,第二次接入实际发生在随机接入时隙里,可能和其他用户的接入请求碰撞,所以 TDMA 系统都要留一部分时隙专门做随机接入并支持退避重试。

这个流程对做系统设计有直接启示:时隙分配不只是给每个用户一个编号那么简单,还牵涉到接入控制逻辑、定时提前量的闭环调整和碰撞重试策略。相比 FDMA 的频率规划,TDMA 的系统同步机制复杂得多,这也是为什么 TDMA 系统调试时,示波器上看时隙波形、抓同步突发是最高频的操作。第 6 章 PPT 如果只画了 TDMA 的时隙结构图而没有讲同步建立过程,那你就得自己在课外找资料补齐这块——试卷大题里最容易考的恰恰是这个流程。

4. 码分复用与 CDMA 多址:所有用户挤在同一段频率里如何不互相踩脚

4.1 码分复用的本质:扩频之后,用户靠“码字”而不是“频谱位置”区分

在 FDM 和 TDM 之后,CDMA 的思路彻底换了个方向:不切频率,不切时间,让所有用户在同一时间、同一频率上发信号,靠各自携带的扩频码来区分。这个思路听起来违反直觉,能成立的前提是码组满足正交性或伪正交性。具体做法是:每个用户被分配一个唯一的扩频序列,也叫伪随机码,码片速率远高于数据速率;发送时把每个数据比特和扩频码逐位相乘(即扩频),接收时用同一个扩频码做相关运算(即解扩)。只有当接收端的本地码与发送端码完全对齐时,相关输出才是高的;其他用户的码由于互相关性很低,在解扩后留下的只是一个很小的噪声项。

工程上衡量 CDMA 性能有个核心指标叫处理增益 Gp,定义为码片速率除以数据速率。假设数据速率 9.6kbit/s,码片速率 1.2288Mchip/s,Gp 就是 128 倍,换算成 dB 是 21dB。这个值直接告诉你解扩后信号相对噪声被抬高了 21dB,是抗干扰能力的来源。处理增益越高,系统能容忍的干扰越多,能容纳的用户数也越多,但代价是占用带宽变大。

4.2 用 Python 验证 m 序列的相关性与“正交”的真实含义

学习 CDMA 最容易踩的坑是把“正交码”理解成任意两个码字互不影响。实际工程里用的 m 序列并不严格正交,它靠的是互相关在一个较低水平上能够接受。用 Python 跑一段 m 序列自相关和互相关的代码,这个性质会非常直观:

import numpy as np # m 序列生成:使用反馈多项式 x^5 + x^2 + 1(本原多项式) def m_sequence(fb_taps, state, length): seq = [] reg = state for _ in range(length): # 输出当前最高位 seq.append(reg & 1) # 计算反馈:抽头位异或 fb = 0 for tap in fb_taps: fb ^= (reg >> tap) & 1 reg = ((reg << 1) | fb) & 0x1F # 5 级移位寄存器,掩码保留 5 位 return np.array(seq) # 生成两条不同的 m 序列(初始状态不同) seq_a = m_sequence([4, 1], 0x1F, 1024) # 初始状态全 1 seq_b = m_sequence([4, 1], 0x10, 1024) # 初始状态不同 # 转成双极性 chip_a = 2 * seq_a - 1 chip_b = 2 * seq_b - 1 # 自相关:seq_a 与自身平移 0~63 位的相关值 epochs = 64 auto_corr = [] for shift in range(epochs): shifted = np.roll(chip_a, shift) corr = np.sum(chip_a * shifted) / len(chip_a) auto_corr.append(corr) # 互相关:seq_a 与 seq_b 移位相关 cross_corr = [] for shift in range(epochs): shifted_b = np.roll(chip_b, shift) corr = np.sum(chip_a * shifted_b) / len(chip_a) cross_corr.append(corr) print(f"自相关峰值: {np.max(auto_corr):.3f}") print(f"互相关最大值: {np.max(np.abs(cross_corr)):.3f}") print(f"互相关均值: {np.mean(np.cross_corr):.3f}")

这段代码的核心是:对同一个 m 序列做平移相关时,对齐的位置会有一个接近 1 的峰值,其他地方接近 0;而对另一个 m 序列做互相关时,即使你的码字和对方码字碰巧在某个移位上对齐,输出也只能是一个小的随机波动。这个特性就是 CDMA 解扩的基础——接收机只需要把自己的本地码对齐发送端的码相位,就能把目标用户的信号从一堆混合信号里“捞”出来。

注意这里的 m_sequence 实现里,反馈抽头和移位寄存器掩码是按 5 级寄存器写的,你改多项式时需要同时改掩码位数。如果你只是做教学验证,不想深入移位寄存器细节,可以直接用np.random.RandomState(seed).randint(0, 2, 1024)生成伪随机码做同样的相关实验,性质一致,只是失去了 m 序列周期性的验证价值。

4.3 两用户 CDMA 完整收发仿真:扩频、混合、解扩、判决

理解了相关性之后,把两个用户的完整收发过程拼起来。下面这段代码模拟两个用户同时发数据,信号在空中混合、叠加噪声,然后各自用本地码进行解扩并判决:

import numpy as np # 参数定义 data_len = 64 # 数据比特数 chip_rate_per_bit = 63 # 每比特 63 个码片(符合常用 m 序列长度) Gp = chip_rate_per_bit # 处理增益 # 生成用户 1 和用户 2 的数据比特 rng = np.random.default_rng(42) data1 = rng.integers(0, 2, data_len) data2 = rng.integers(0, 2, data_len) # 生成扩频码:用户 1 是 m 序列,用户 2 是同一个序列循环移位出的序列 # 这里用移位版本模拟“不同用户”,虽然不严格正交但互相关可控 chip1 = 2 * m_sequence([4, 1], 0x1F, data_len * chip_rate_per_bit) - 1 chip2 = 2 * m_sequence([4, 1], 0x10, data_len * chip_rate_per_bit) - 1 # 扩频:每个数据比特复制为 chip_rate_per_bit 个码片并相乘 def spread(data, chip_seq): return np.repeat(2 * data - 1, chip_rate_per_bit) * chip_seq spread1 = spread(data1, chip1) spread2 = spread(data2, chip2) # 空中混合并加噪声 snr_db = 0 # 0dB 信噪比,干扰接近信号本身 noise = np.random.normal(0, 1, len(spread1)) * (1 / 2) ** (snr_db / 10) rx = spread1 + spread2 + noise # 解扩:接收端用本地码逐码片相乘并累加判决 def despread(chip_seq, rx_signal): bits = [] for i in range(data_len): seg = rx_signal[i * chip_rate_per_bit : (i+1) * chip_rate_per_bit] decision = np.sum(seg * chip_seq[i * chip_rate_per_bit : (i+1) * chip_rate_per_bit]) bits.append(1 if decision > 0 else 0) return np.array(bits) rx1 = despread(chip1, rx) rx2 = despread(chip2, rx) # 统计误码率 ber1 = np.mean(rx1 != data1) ber2 = np.mean(rx2 != data2) print(f"用户 1 误码率: {ber1:.3f}") print(f"用户 2 误码率: {ber2:.3f}")

分析这段代码可以看到,snr_db=0意味着噪声功率和单路信号功率相当,再加上另一路用户的信号干扰,直接不发扩频的话错误率高得没法用。扩频的作用体现在despread函数里的那个sum:目标用户信号因为本地码对齐,每一比特对应的 Gp 个码片都会同向累加,形成一个大数值;干扰用户的信号因为码片不匹配,累加时正负相消,只剩一个小幅随机量。这就是处理增益起了作用,谁的对齐关系正确,谁就能在噪声里把自己的信号捞出来。

需要留意的是硬判决阈值取 0,这适用于双极性等概率数据。如果信号不对称或有直流偏置,阈值就得用估计出来的均值做软判决。你在实际项目里如果发现某一用户误码率偏高但另一用户正常,大概率不是功率问题,而是扩频码的互相关性不够低造成的交叉干扰。

4.4 功率控制为什么是 CDMA 的生命线:“远-近效应”的数学直觉

CDMA 系统里所有用户共用同一频谱,干扰来自彼此。假设两个用户到达基站的功率相差 20dB,即 100 倍,那么弱信号用户在基站接收端做解扩时,强信号用户留下的残余干扰虽然经过扩频增益被压制了约 21dB,但依然可能高出弱信号本身的水平,导致弱信号完全解不出来。这个问题的专业叫法是“远-近效应”:离基站远的用户信号到达时已经衰减得很厉害,离得近的用户如果不做功率限制,就会把远用户彻底淹没。

解决手段就一个词:功率控制。基站不断测量每个用户接收功率,如果偏高就命令用户降功率,偏低就命令升功率,控制步进一般在 1dB 量级,更新频率可以快到每秒 1500 次甚至更高。这个机制保证了所有用户到达基站的功率大致相等,系统的容量才能按照所有用户等功率的假设来计算。做 CDMA 系统仿真时,如果不加入功率控制,只是给每个手机设一个固定的发射功率,那么系统容量和误码率的结果都会显著偏离真实系统——这是初学者最容易犯的错:拿 CDMA 链路级仿真结果去推断系统级容量行为,但没有功率控制的假设根本不成立。

5. 多路复用落地时的 5 个典型翻车现场与排查

5.1 翻车一:保护带宽没留够,邻路信号串进了本路

现象:多路 FDM 信号接收端解调出来的语音或数据有明显背景噪声,把某一路信号单独发送时一切正常,所有路一起发送时质量明显变差。

原因:相邻两路的载波间隔小于信号带宽加上滤波器过渡带宽之和,发射端带通滤波不彻底,邻路的频谱尾部能量泄漏进本路的通带。频谱仪上能看到两路的谱峰之间没有明显凹陷,而是连成一片。

解决:重新规划频点,确保载波间隔 ≥ 信号占用带宽 + 保护带宽。具体做法是把发射端滤波器从普通 LC 滤波器换成声表面波滤波器,或者放宽载波间隔。我在项目里常用的办法是先拿频谱仪测一下发射信号的 3dB 带宽和 60dB 带宽,如果 60dB 带宽已经接近甚至超过载波间隔,就必须加大间隔,因为 3dB 算出来的保护带宽根本不适用于工程系统。

5.2 翻车二:TDM 帧同步丢失,所有时隙跟着错位

现象:E1 链路接收端报“帧失步”,误码率高到不可用,发射端自环测试(把发端输出直接接回本机收端)完全正常,一对线直连也正常,但经过中继设备后问题出现。

原因:中继设备或远端的时钟精度不够,接收端本地帧同步搜索窗口没有对齐实际帧起点,导致 TS0 里的帧同步码始终对不上,系统反复进入搜索状态。另一个常见原因是链路里插入了一级做异步映射的适配设备,插入了额外的比特填充,破坏了原有帧结构。

解决:先用误码仪分段排查,把中继设备去掉直接端到端测试,确认问题出在某段传输设备上。然后检查所有设备的时钟模式——如果两端都设成了自由振荡模式而不是跟随上级时钟,频率偏差会累积,必须把其中一端设为主时钟,另一端设为从时钟跟踪。帧同步是 TDM 共享时钟链路上的马车,任何一段时钟乱了节奏,整列车厢全部错位。

5.3 翻车三:拿真随机序列当扩频码用,互相关抖动导致系统容量崩塌

现象:CDMA 仿真系统在加性白噪声下表现良好,但把用户数从 2 增加到 5 后,误码率跳变,几个用户的性能差异很大,有的用户几乎全对,有的用户全错。

原因:扩频码组不是用规划好的 m 序列族或 Walsh 码,而是直接拿伪随机数生成器产生的序列。这类序列互相关性能不受控,不同序列之间的互相关峰可能达到 0.3 甚至更高,在用户数多时,这些互相关能量累加后足以淹没部分用户的信号。

解决:用标准 m 序列优选对或 Walsh-Hadamard 码组替换随机码,并且在生成后实际计算一下任意两两码组之间的互相关最大值,确认低于 0.1 再投入使用。如果你在真实系统里用 GPS 同步来让所有用户码相位对齐,可以考虑严格正交的 Walsh 码,但码相位同步一旦有偏差,正交性立刻恶化。

5.4 翻车四:处理增益算错了一个数量级,扩频增益完全失效

现象:仿真里扩频后的误码率和不扩频差不多,处理增益显示有 21dB,但实测抗干扰能力只提升了几 dB。

原因:处理增益的定义是码片速率除以数据速率,即 Gp = Rchip / Rdata。常见错误是把符号速率当数据速率用,或者在扩频时把重复次数算成了码片数但实际数据速率对应的是符号级,导致 Gp 被夸大。例如 16QAM 调制,符号速率只是数据速率的四分之一,用符号速率算出来的 Gp 会虚高 6dB。

解决:统一用“用户数据比特速率”作为分母。如果你的系统里数据速率 9.6kbit/s、码片速率 1.2288Mchip/s,Gp 就是 128,约 21dB。在代码里核对np.repeat的次数是否等于每个数据比特对应的码片数,而不是每个符号对应的码片数。这个参数纠错只用两分钟,但错误的影响会贯穿整轮仿真的结论。

5.5 翻车五:码片速率与符号速率混用,眼图分析彻底失真

现象:在做 CDMA 发射端眼图测试时,示波器上显示的眼图完全张开但杂散噪声大,测试结论是“信号质量差”,而用频谱仪看信号带外泄漏又完全正常。

原因:把码片速率当符号速率去设置示波器的时基和触发,示波器把相邻码片之间的过渡沿也纳入了眼图,自然就产生了大量的交叉轨迹。CDMA 信号的眼图应该按“扩频之前的符号速率”来观察,因为码片的跳变不属于数据眼图的考核范围,而是反映滤波器性能和码片间干扰。

解决:确认示波器触发的时钟信号是符号时钟而不是码片时钟。如果你是做基带算法,更直接的验证方式是直接对比解扩前后的星座图或眼图,而不是在扩频波形上做眼图测试。用错时钟基准,测出来的眼图会给你一个不存在的“滤波器失真”的结论,排查半天最后发现是测试方法的问题。

6. 把课件参数验证成可用参数:一段最小的正交码检测脚本

课件里的理论参数在工程上能不能直接用,最快的验证办法是写一段仿真脚本把关键性质重新算一遍。我平时做通信算法,拿到新项目先干的事情就是跑一段几十行代码验证核心序列的相关性,下面这段脚本可以复用于任意扩频码组的正交性检查:

import numpy as np from itertools import combinations def check_code_family(codes, shifts=range(0, 64)): """ 验证一组扩频码的自相关旁瓣和互相关特性 codes: 二维数组,每行一个扩频码(0/1 格式) """ n_codes = codes.shape[0] chip_len = codes.shape[1] # 转双极性 b = 2 * codes - 1 max_auto_side = 0.0 max_cross = 0.0 for i in range(n_codes): # 自相关:剔除零移位峰值,找最大旁瓣 for s in shifts: if s == 0: continue corr = np.sum(b[i] * np.roll(b[i], s)) / chip_len max_auto_side = max(max_auto_side, abs(corr)) # 互相关 for i, j in combinations(range(n_codes), 2): for s in shifts: corr = np.sum(b[i] * np.roll(b[j], s)) / chip_len max_cross = max(max_cross, abs(corr)) return max_auto_side, max_cross # 示例:Walsh 码(取阶数 8,共 8 个码) N = 8 walsh = np.zeros((N, N), dtype=int) walsh[0] = np.ones(N, dtype=int) for i in range(1, N): walsh[i] = (-1) **((np.arange(N) & i).__and__(1) == 0).astype(int) # 更简洁的生成方式用 Hadamard 矩阵 hadamard = np.array([[1, 1], [1, -1]]) while hadamard.shape[0] < N: hadamard = np.block([[hadamard, hadamard], [hadamard, -hadamard]]) walsh_codes = (hadamard + 1) // 2 auto_side, cross = check_code_family(walsh_codes) print(f"Walsh 码最大自相关旁瓣: {auto_side:.3f}") print(f"Walsh 码最大互相关: {cross:.3f}")

这段代码用哈达马矩阵生成一组 Walsh 码,然后逐一检查任意两码在任意相对移位下的互相关最大值。对完全同步的系统,Walsh 码互相关应当为 0;如果输出接近 0.5,说明码组配置错误或码相位偏移没有被正确处理。这个脚本的价值在于:你在第 6 章 PPT 里看到的“正交码”,在真实系统里到底正不正交、容许多大的相位偏移、旁瓣会不会造成多径干扰,跑出这几个数字心里就有底了。

我的个人习惯是:每个新项目启动第一天就把这段代码跑一遍,并把结果存进仿真文档里作为基线。等到后续系统联调出了问题,先拿基线数据对比——码组的相关系数没变,那就不是码的问题,去找时钟和滤波器;相关系数变了,那一定是收发码表对不上。这套排查逻辑帮我省过不止一次通宵。多路复用和多址技术这一章,PPT 上的每一张频谱图和帧结构图背后都是这类可以动手验证的参数边界,把它们算一遍、跑一遍,才敢说真的吃透了,希望帮到你。

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

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

AI智能体本地运行耗电实测:从功耗估算到降耗优化

如果你也在跑AI智能体&#xff0c;大概率被问过这样一句话&#xff1a;“你小子天天挂个模型&#xff0c;电费是不是爆炸了&#xff1f;”说实话&#xff0c;我第一次被问住的时候真答不上来。后来我花了几周时间把本地智能体耗电量这件事系统测了一遍&#xff0c;才发现网上主…

作者头像 李华
网站建设 2026/9/26 13:02:38

VSCode 扩展插件激活失败排查:从 settings.json 到 TaoToken 配置骨架

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

作者头像 李华
网站建设 2026/9/26 13:02:24

轨道交通GNSS平面控制网布设与数据处理全流程解析

简介&#xff1a;轨道交通工程全球导航卫星系统&#xff08;GNSS&#xff09;平面控制网布设与数据处理是一份专业技术文档&#xff0c;面向测绘、轨道交通及工程测量领域的工程师与研究人员。资源以实际工程为例&#xff0c;系统阐述控制网布设方案与坐标系选择&#xff0c;分…

作者头像 李华
网站建设 2026/9/26 13:02:24

VMware Workstation Pro安装失败深层原因与系统级排错指南

1. 为什么“安装 VMware Workstation Pro”这件事&#xff0c;远比点几下鼠标复杂得多 很多人第一次打开 VMware 官网&#xff0c;看到那个醒目的“Download Now”按钮&#xff0c;心里想的是&#xff1a;“不就是装个软件&#xff1f;下一步、下一步、完成——搞定。”结果三分…

作者头像 李华
网站建设 2026/9/26 13:01:36

最近邻启发式实战:MATLAB实现垃圾收运车辆调度与路径规划

做环卫信息化的朋友应该都遇到过这类需求&#xff1a;几十个垃圾收集点散布在各个片区&#xff0c;手头有几辆收运车&#xff0c;怎么给每辆车分配合适的任务&#xff0c;并规划出一条能落地的收运路线。以前我拿到这种题目&#xff0c;第一反应是上遗传算法、蚁群算法这些大杀…

作者头像 李华
网站建设 2026/9/26 13:01:12

低空云平台:低空监管与飞行服务的一体化数字底座

简介&#xff1a;数字化基础平台是行业数字化转型的核心支撑&#xff0c;通过统一身份认证、消息中心和时空基准&#xff0c;实现多源数据的标准化接入与流程协同。低空经济场景下&#xff0c;低空监管与飞行服务需要同一套底座支撑&#xff0c;平台通过感知、传输、平台、应用…

作者头像 李华