m序列与Walsh码:CDMA扩频序列的正交性原理与工程实践

发布时间:2026/10/24 18:34:50
m序列与Walsh码:CDMA扩频序列的正交性原理与工程实践

简介:这份文档面向通信、电子与信号处理方向的学习者,系统梳理扩频通信中两类核心序列——m序列与Walsh码的生成原理与应用要点,帮助读者理解码分多址系统中扩频码的设计逻辑。压缩包内为1个doc文件,大小约355KB,内容涵盖m序列的线性移位寄存器结构与反馈系数选择、Walsh码基于Hadamard矩阵的排列转换方法,并附有walshf1等生成函数的实现代码,便于对照理解矩阵变换过程。文中还延伸讨论了Gold序列的模2加构造方式,以及多径与异步到达导致正交性下降、多址干扰难以完全消除的实际问题。已有636人学习该资料,适合作为扩频序列入门与课程复习的参考,也可为CDMA相关实验提供算法思路与代码借鉴。

1. 从一场“多人同时说话”的饭局说起:m序列和Walsh码到底是什么

想象一桌人同时聊天,如果大家各说各的、音量还一样大,结果就是谁也听不清——这就是无线通信里最头疼的“多址干扰”。扩频序列要解决的,就是让每个人用一套独特的“说话节奏”,即使同时开口,接收方也能把每句话单独拎出来。m序列和Walsh码就是两套最经典的“节奏方案”:前者像一段极长、极难预测的伪随机口哨,后者像一组彼此严格错开的正交节拍。搞懂这两者,你就摸到了CDMA系统里“码分多址”这四个字的门槛,也才能明白为什么工程上既要追求正交、又不得不接受“正交并不彻底”这个现实。

2. 先拆开看:两种序列各自的脾气从哪来

2.1 m序列:用移位寄存器“摇”出来的最长伪随机串

m序列的全称是最长线性移位寄存器序列,名字已经把它的出身说清楚了——它由 n 级线性移位寄存器产生,周期是 2^n - 1。通俗地说,你可以把它想成一排 n 个灯泡,每个时钟节拍整体往左挪一格,最右边新补进来的那一位,由前面若干位的“异或”结果决定。哪些位参与异或,就是所谓的反馈系数;反馈系数选得对,序列才会跑到最长周期,选错了周期就短一截。

打个比方,这就像一台老式摇奖机:摇臂的连接方式(反馈系数)决定了小球能跑出多少种不重复的组合,起始时小球摆的位置(初始状态)只决定你从哪一颗开始看。所以同一组反馈系数下,换一个起始状态,得到的只是同一条长序列的某个平移版本,而不是另一条新序列。

m序列最值钱的地方在于它的统计特性:自相关函数在零延迟处是一个尖峰,偏离零点后迅速掉到很低的水平;不同 m 序列之间的互相关也普遍偏低。这让它非常像一段真正的随机噪声,却又完全可复现——接收端只要知道反馈系数和起始状态,就能一模一样地再摇一遍。正因如此,m序列常被用作伪随机噪声序列,在扩频系统里承担“把窄带信号摊到宽频带上”的角色。

用一段极简的 Python 示意,能更直观看到“移位 + 反馈”这个动作:

# 以 4 级寄存器、反馈抽头为第 4 位和第 3 位为例(仅示意结构) def m_sequence(seed, taps, length): reg = list(seed) # 初始状态,决定序列起点 out = [] for _ in range(length): out.append(reg[-1]) # 当前最右位输出 fb = 0 for t in taps: # 反馈系数决定哪些位参与异或 fb ^= reg[t] reg = [fb] + reg[:-1] # 整体右移,新位补到最左 return out

这段代码里,taps就是反馈系数的位置集合,seed是起始状态,length是你要取多长。真正决定“是不是 m 序列”的是taps的选取——选对了,输出长度达到 2^n - 1 才开始重复;选错了,周期会明显变短。实际工程里不会手算抽头,而是查本原多项式表,这一点初学者最容易忽略。

2.2 Walsh码:从Hadamard矩阵里“排”出来的正交节拍

Walsh码的出身完全不同。它来自 Hadamard 矩阵——一个只由 +1 和 -1 构成的方阵,任意两行之间做内积结果都是零,也就是严格正交。但 Hadamard 矩阵的行序并不是拿来就能用的,需要按“符号交变次数”重新排列,排完之后才得到 Walsh 矩阵。这个重排动作,就是把数学上的正交矩阵翻译成工程上“按频率高低排队”的序列。

为什么非要重排?因为 Walsh 序列在 CDMA 前向链路里是按编号分配给不同物理信道的,编号 W0 到 W63 对应 64 阶 Walsh 序列,码片速率 1.2288 Mc/s。如果行序混乱,相邻编号的序列交变次数忽高忽低,会给系统设计带来麻烦;按交变次数排好之后,序列的“翻转频率”随编号单调变化,分配和调度都更规整。

正交带来的好处非常直接:理论上,只要各信道用的 Walsh 序列彼此正交,多址干扰可以被压到零。这就是码分多址的底气——大家在同一频段、同一时刻发,靠“正交的码”把彼此分开,而不是靠时间片或频率段。

项目正文里给出的生成函数,核心就是三段排列:先用hadamard生成原始矩阵,再按 Paley 序重排得到Hp,接着按 Walsh 序重排得到Wg,最后再做一个逆序得到Hm。函数返回的X = Wg就是 N 阶 Walsh 序列矩阵。这里有个容易看漏的细节:函数开头N=ceil(log2(N)),意思是无论你传进来什么阶数,它都会向上取到 2 的整数次幂——因为 Hadamard 矩阵的阶数必须是 2 的幂,传 60 进去实际会按 64 处理。

N = ceil(log2(N)); % 阶数向上取到 2 的幂,这是硬约束 H = hadamard(2^N); % 先生成原始 Hadamard 矩阵 % 后续按 Paley 序、Walsh 序、逆序三次重排 % Hp 为 Paley 序,Wg 为 Walsh 序(即最终输出),Hm 为逆 Walsh 序

参数上要盯住两点:一是输入阶数会被悄悄“向上取整”,调试时如果发现矩阵维度和你预期不符,先回头检查这里;二是三个中间矩阵Hp、Wg、Hm各自对应一种排序,工程上真正拿去扩频的是Wg,另外两个更多是变换核,用来在几种排序之间换算。

3. 为什么正交不等于万事大吉:理想与现实的落差

3.1 正交性在纸面上能消掉多址干扰

把 Walsh 码的正交性说透,只需要一个类比:两个人分别用两把齿形完全互补的钥匙去开同一把锁,只要齿形严格互补,两把钥匙的“作用”互不干扰。数学上就是任意两条 Walsh 序列逐位相乘再求和等于零。于是当多个信道同时发送时,接收端用对应的 Walsh 序列做一次相关运算,其他信道的贡献理论上被乘成了零,只剩自己要的那一路。

这也是为什么 64 阶 Walsh 序列能支撑 64 个前向物理信道:每个信道分一条序列,编号 W0 到 W63,码片速率 1.2288 Mc/s,彼此正交,容量看起来是“白送”的。m序列在这里扮演的是另一层角色——它负责把信号摊开到宽频带上,Walsh 码负责在摊开之后把不同用户区分开,两者一个管“扩”,一个管“分”。

3.2 多径和异步到达,让正交性打了折扣

现实很快泼来冷水。多径信号经过不同路径到达,延迟和衰减都不一样,异步到达的副本与同步到达的原始信号已经不再严格对齐,正交的前提——逐位对齐——被破坏了。来自其他小区的信号同样既不同步也不正交,干扰照样漏进来。所以工程上 Walsh 码能“消除或抑制”多址干扰,但抑制不到零。

项目正文里那句评注说得很实在:如果 Walsh 真的完全正交,多用户检测这门学问就没必要研究了。这句话点破了整个领域的现实——正交是设计目标,不是物理保证。理解这一点,你才不会在仿真里看到误码率降不下去时一头雾水。

提示:评估 Walsh 码方案时,别只看理想正交下的容量数字,要把多径时延扩展和其他小区干扰一起算进去,否则结论会偏乐观。

3.3 生成函数里的三次重排,各自解决什么问题

回到那段生成代码,三次重排不是炫技。Paley 序解决的是“从 Hadamard 原始行序到一种有规律序”的过渡;Walsh 序按交变次数排队,让序列编号和翻转频率挂钩,方便信道分配;逆 Walsh 序则是把排序再翻回去,用于变换核的闭环。三个矩阵Hp、Wg、Hm加上对应的变换矩阵Ep、Eg、Em,构成了一套可逆的排序工具链。

对使用者来说,最需要记住的是:不同排序下“第几条序列”指的不是同一条物理波形。如果你从别处拿到一组按 Paley 序编号的序列,直接塞进按 Walsh 序设计的系统里,正交性还在,但编号对不上,信道映射就全乱了。这是移植代码时最常见的翻车点之一。

4. 别把这几组概念搅在一起:常见易混点拆解

4.1 m序列与Gold序列:一个是“单摇”,一个是“双摇相加”

易混点在于两者都常被叫作伪随机序列,名字里还都带“序列”。为什么混?因为 Gold 序列确实是用一对周期和速率相同的 m 序列优选对模 2 加得到的,血缘上就是 m 序列的扩展。怎么区分:m 序列由单个移位寄存器产生,周期 2^n - 1;Gold 序列由一对 m 序列优选对逐位模 2 加得到,好处是同一对优选对能派生出整族互相关可控的序列,适合多用户场景。记法上可以想成“m 序列是单摇奖机,Gold 是两台摇奖机的结果再叠加”。

4.2 Walsh码与m序列:一个管正交分区,一个管伪随机扩频

易混点在于两者都出现在扩频系统里,初学者容易以为随便挑一个就能扩频。为什么混?因为它们在系统里经常同时出现,角色却被混为一谈。怎么区分:Walsh 码的核心卖点是严格正交,用来在同步条件下区分不同信道;m 序列的核心卖点是长周期、低自相关旁瓣、难预测,用来做伪随机扩频和扰码。一个偏“分”,一个偏“扩”,职责不同,不能互换。

4.3 正交与不相关:数学上不是一回事

易混点在于“正交”和“不相关”常被当成同义词。为什么混?因为在零均值且等概率取 ±1 的序列里,两者数值上经常表现一致。怎么区分:正交是内积为零这个确定性的代数关系;不相关是统计意义上的协方差为零。Walsh 序列是确定性正交,m 序列的互相关是统计意义上的低值,两者不是同一层次的保证。把 m 序列的低互相关直接说成“正交”,在严格讨论里是站不住的。

4.4 阶数与序列条数:64阶不等于只有64条可用

易混点在于“64 阶 Walsh 序列”被理解成“总共 64 条序列”。为什么混?因为 W0 到 W63 的编号确实只到 63。怎么区分:64 阶 Walsh 矩阵是 64×64,行数就是 64,所以确实对应 64 条序列,这一点没错;但要注意阶数必须是 2 的幂,传 60 会被ceil(log2())抬到 64,此时你拿到的仍是 64 条,而不是 60 条。调试时矩阵维度对不上,多半是这里被悄悄改了。

4.5 理论正交与实际正交:仿真和现网差在哪

易混点在于仿真里误码率曲线漂亮,就以为现网也能照搬。为什么混?因为仿真常默认各用户符号级同步、单径信道。怎么区分:现网存在多径时延扩展、小区间异步、定时偏差,正交性被逐步侵蚀。判断一套参数能不能用,要看它在“非同步 + 多径”条件下的表现,而不是理想正交下的容量上限。

5. 什么时候该用哪一套:边界判断与一个具体取舍

把边界说清楚,比背定义有用。Walsh 码适合“同步条件较好、需要严格区分信道”的场合,典型就是前向链路里按编号分配物理信道;一旦同步被破坏、多径严重,它的正交红利就快速缩水。m序列适合“需要长周期伪随机、低自相关旁瓣”的场合,比如扩频和扰码;但它本身不提供严格正交,多用户区分不能单靠它。Gold 序列则落在中间地带——用一族互相关可控的序列换取多用户场景下的灵活性。

序列类型核心特性典型角色主要局限
m序列周期 2^n - 1,自相关旁瓣低伪随机扩频、扰码不提供严格正交
Walsh码严格正交,阶数为 2 的幂前向信道区分依赖同步,多径下正交退化
Gold序列由 m 序列优选对模 2 加得到多用户互相关可控互相关非零,需优选对

举个具体取舍:某实验室做一套多用户仿真 Demo,前向链路要分 64 个逻辑信道,同时又要模拟多径。合理的做法是 Walsh 码负责信道划分、m序列负责扩频,然后在信道模型里显式加入时延扩展,观察正交退化后的误码率。如果只跑理想单径,曲线会好看到失真,后面一上多径就全盘翻车。

反过来,什么时候别用?当系统里各用户根本不同步、且多径时延接近甚至超过一个码片周期时,硬堆 Walsh 码的正交假设没有意义,此时更该考虑互相关可控的序列族,或者直接上多用户检测。另一个别用的场景是:把 m 序列当正交码去做信道划分——它的低互相关是统计意义上的,不是代数正交,多用户一多,干扰会明显抬头。

我自己踩过的坑是:早期做仿真时图省事,默认所有用户符号级对齐,Walsh 正交性完美,结果容量算出来漂亮得离谱;后来把多径和定时偏差加进去,同一套参数直接崩掉。从那以后我每次评估扩频方案,都强制先把“非同步 + 多径”这两个条件打开再跑一遍,确认退化幅度在可接受范围内才继续。希望这套思路能帮到你,少走一段我走过的弯路。

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