ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

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

多路复用与多址技术详解:从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第 {i1} 路最大还原误差: {err:.2e})这里最核心的一行是内层循环里frame_data.append(sample)它完成的操作就是每帧依次从每路信号取出一个采样值构成一个时间上紧凑的帧。解包时按同样的索引规则把每个采样值送回对应的输出序列。如果打包和解包的帧对齐方式差一个采样点还原出来的信号就是错位的这在代码里表现为最大还原误差直接变成正常值的量级而不是 1e-15 级别。本仿真没有做 PCM 编码直接用浮点值省掉了量化噪声的干扰让你专注于帧结构的对齐逻辑。参数说明fs8000对应真实语音系统采样率slots_per_frame4是复用的路数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/sGp 就是 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 : (i1) * chip_rate_per_bit] decision np.sum(seg * chip_seq[i * chip_rate_per_bit : (i1) * 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_db0意味着噪声功率和单路信号功率相当再加上另一路用户的信号干扰直接不发扩频的话错误率高得没法用。扩频的作用体现在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/sGp 就是 128约 21dB。在代码里核对np.repeat的次数是否等于每个数据比特对应的码片数而不是每个符号对应的码片数。这个参数纠错只用两分钟但错误的影响会贯穿整轮仿真的结论。5.5 翻车五码片速率与符号速率混用眼图分析彻底失真现象在做 CDMA 发射端眼图测试时示波器上显示的眼图完全张开但杂散噪声大测试结论是“信号质量差”而用频谱仪看信号带外泄漏又完全正常。原因把码片速率当符号速率去设置示波器的时基和触发示波器把相邻码片之间的过渡沿也纳入了眼图自然就产生了大量的交叉轨迹。CDMA 信号的眼图应该按“扩频之前的符号速率”来观察因为码片的跳变不属于数据眼图的考核范围而是反映滤波器性能和码片间干扰。解决确认示波器触发的时钟信号是符号时钟而不是码片时钟。如果你是做基带算法更直接的验证方式是直接对比解扩前后的星座图或眼图而不是在扩频波形上做眼图测试。用错时钟基准测出来的眼图会给你一个不存在的“滤波器失真”的结论排查半天最后发现是测试方法的问题。6. 把课件参数验证成可用参数一段最小的正交码检测脚本课件里的理论参数在工程上能不能直接用最快的验证办法是写一段仿真脚本把关键性质重新算一遍。我平时做通信算法拿到新项目先干的事情就是跑一段几十行代码验证核心序列的相关性下面这段脚本可以复用于任意扩频码组的正交性检查import numpy as np from itertools import combinations def check_code_family(codes, shiftsrange(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), dtypeint) walsh[0] np.ones(N, dtypeint) 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(fWalsh 码最大自相关旁瓣: {auto_side:.3f}) print(fWalsh 码最大互相关: {cross:.3f})这段代码用哈达马矩阵生成一组 Walsh 码然后逐一检查任意两码在任意相对移位下的互相关最大值。对完全同步的系统Walsh 码互相关应当为 0如果输出接近 0.5说明码组配置错误或码相位偏移没有被正确处理。这个脚本的价值在于你在第 6 章 PPT 里看到的“正交码”在真实系统里到底正不正交、容许多大的相位偏移、旁瓣会不会造成多径干扰跑出这几个数字心里就有底了。我的个人习惯是每个新项目启动第一天就把这段代码跑一遍并把结果存进仿真文档里作为基线。等到后续系统联调出了问题先拿基线数据对比——码组的相关系数没变那就不是码的问题去找时钟和滤波器相关系数变了那一定是收发码表对不上。这套排查逻辑帮我省过不止一次通宵。多路复用和多址技术这一章PPT 上的每一张频谱图和帧结构图背后都是这类可以动手验证的参数边界把它们算一遍、跑一遍才敢说真的吃透了希望帮到你。本文还有配套的精品资源点击获取
返回列表