☰
第二类部分响应系统详解:预编码与相关编码的手算推演
2026/10/15 4:52:23 网站建设 项目流程

学通信原理的人多半都有过类似体验:奈奎斯特第一准则让我们对理想低通特性又爱又恨——它能给出极限的频带利用率,物理上却做不出来;升余弦滚降特性可以实现,代价是带宽白白浪费。部分响应系统就夹在两者之间,用一种非常聪明的办法打破了"必须完全消除码间串扰"的执念。第一类部分响应(双二进制)在教材里被讲得很细,第二类部分响应却常常被一笔带过,只说一句"相关间隔变成两个码元"。可真到做题、做仿真,或者被问到"第二类部分响应的预编码为什么这么做"时,很多人就卡壳了。这篇文章就把第二类部分响应的预编码和相关编码从头到尾拆开讲清楚:它解决了什么问题、预编码公式怎么来的、相关编码输出为什么是三电平,以及完整的手算推演和工程中容易踩的坑。

这篇内容适合正在学通信原理的学生,也适合准备面试时临时补课的人。只要你会二进制加减法和一点点"记忆"的概念,就能跟着推完整个链路。

1. 为什么要打破"零码间串扰"的执念:奈奎斯特约束与受控串扰

1.1 理想低通为什么只是纸面上的最优解

数字基带传输里,一个最基本的约束是奈奎斯特第一准则:若码元周期为 T,理想低通特性可以在 1/(2T) 的带宽内实现无码间串扰传输。这个结论看起来非常完美——频带利用率达到 2 Baud/Hz,是理论极限。

问题出在理想低通本身。它的冲激响应是 sinc 函数,拖尾按 1/t 的速度衰减,衰减太慢。实际系统里,抽样时刻稍微偏差一点,相邻码元的尾巴就会叠加出可观的干扰。而且理想低通的幅频特性在截止频率处是陡峭的矩形,物理上无法精确实现。工程上只能逼近,逼近的代价就是让过渡带变宽,或者让滤波器阶数高到不现实。

所以真实系统很少直接去追求理想的矩形低通特性,而是退一步,用升余弦滚降特性。升余弦特性把幅频特性的过渡带设计成余弦形状,拖尾衰减速度变成 1/t^3,对定时偏差友好得多。代价也很明显:滚降系数 α 越大,占用带宽越宽,频带利用率从 2 Baud/Hz 掉到 2/(1+α) Baud/Hz。很多人为了工程可实现性,默认接受了这个带宽损失。

1.2 部分响应的破局逻辑:允许串扰,但必须受控

部分响应系统换了一个思路。它不追求"完全没有码间串扰",而是主动引入一种确定的、已知的码间串扰,让相邻码元之间按照某种规则叠加,再用编码的方式把这个规则告诉接收端。只要接收端知道串扰是怎么来的,就能把它扣除,恢复出原始数据。

这个思路听上去像"制造麻烦再解决麻烦",但它的收益非常大:可以在 1/(2T) 的极限带宽内,用物理可实现的方式传输信号。代价是发送信号从二电平变成多电平,信噪比上会有所损失。

部分响应系统有很多种,分类依据就是"当前码元和哪几个历史码元叠加"。第一类部分响应做相邻码元叠加大,即当前码元与自己往前数一个码元相关;第二类部分响应则做跨码元叠加,当前码元与往前数两个码元的符号相关。用延迟时间来说,第一类延迟一个 T,第二类延迟两个 T。这就是标题里"第二类"的核心特征。

打个比方:第一类部分响应像开会时每个人的发言可以压着前一个人的尾音,只要规则是"压上一个字";第二类则是发言压着"上上个字",中间隔了一个字不受影响。看似更复杂,但在某些信道特性下反而有独特的利用价值。

2. 相关编码的本质:一个延迟两个码元的叠加器

2.1 从数字滤波的角度看相关编码

先规定符号。设发送端原始数据序列为 a_k,取值为 0 或 1(二进制情况)。传输前先经过预编码,得到序列 b_k。预编码的公式后面专门讲,现在先假设 b_k 已经算好。第二类部分响应的相关编码公式是:

c_k = b_k + b_{k-2}

注意,这是一个普通加法,不取模。也就是说,c_k 可能的取值是 0、1、2,输出是三电平信号。

从数字滤波的角度看,相关编码器就是一个抽头系数为 [1, 0, 1] 的横向滤波器。b_k 进来后,当前样值乘以 1,同时推迟两个码元周期的样值也乘以 1,两者相加得到 c_k。中间那个 b_{k-1} 完全不参与运算,这是第二类和第一类最直观的区别:第一类是 [1, 1],相邻相加;第二类是 [1, 0, 1],隔一个码元相加。

2.2 传递函数和冲激响应:为什么带宽还是极限带宽

相关编码器的离散传递函数可以写成:

G2(f) = 1 + e^{-j2ωT} = 2cos(ωT) · e^{-jωT}

其中 ω = 2πf,T 是一个码元的持续时间。这个式子说明:相关编码器本身在频域不是平坦的,它在带内引入了余弦形状的幅度加权。理想低通滤波器截止频率选在 1/(2T),与这个相关编码器级联后,系统总的传递函数就是"理想低通 × G2(f)",带宽依然被限制在 1/(2T),没有额外展宽。

再看时域。理想低通的冲激响应是 sinc(t/T),相关编码器把每个冲激复制一份并延迟 2T,所以第二类部分响应系统的总冲激响应是:

g(t) = sinc(t/T) + sinc((t - 2T)/T)

这是一个有两个相距 2T 的"主峰"的波形。在 t = kT 的整数倍时刻抽样时,由于 sinc 函数在整数倍 T 处只有原点为 1、其余整数点为 0,所以抽样值只会来自当前时刻和两个码元之前的冲激。换句话说,发送波形在抽样点处的值,恰好等于 c_k。

这也就解释了"受控串扰"的含义:一个 b_k 脉冲并没有安静地待在自己的码元时隙里,它把自己的一部分能量延伸到了两个码元之后。接收端在 kT 时刻看到的,是 b_k 留下的当前分量与 b_{k-2} 留下的历史分量之和。这串扰不是随机的,而是编码规则明确规定的,所以可以破解。

2.3 三电平输出:普通加法不取模,取模留给接收端

很多初学者在这里最容易糊涂:预编码用的是模 2 运算,为什么相关编码不用模 2?如果 c_k 也取模 2,输出就永远是 0 或 1,看起来"更干净",但那恰恰破坏了部分响应的意义。

关键要理解:相关编码输出的 c_k 是要送到成形滤波器去形成实际发送波形的幅度电平。只有输出三电平,经过理想低通后的波形才是真正利用了极限带宽的部分响应信号。如果 c_k 取模 2,发到信道里的信号就退化成了普通二进制信号,带宽不可能压缩到 1/(2T)。

接收端做的才是取模操作。因为预编码保证了 a_k ≡ b_k + b_{k-2} (mod 2),所以对收到的 c_k 做模 2 运算,就能直接恢复 a_k。c_k 等于 2 的时候,模 2 结果是 0,也就是说电平 0 和电平 2 在判决意义上都代表原始比特 0。这是部分响应系统的精髓:用多电平承载二进制信息,换取极限带宽。

2.4 第一类与第二类的对照表

为了更直观,把两类放在一起对比:

对比项第一类部分响应第二类部分响应
相关编码公式c_k = b_k + b_{k-1}c_k = b_k + b_{k-2}
抽头系数[1, 1][1, 0, 1]
相关延迟1 个码元 T2 个码元 2T
传递函数2cos(πfT) · e^{-jπfT}2cos(2πfT) · e^{-j2πfT}
冲激响应主峰间隔T2T
输出电平数3(0,1,2)3(0,1,2)
带宽占用1/(2T)1/(2T)

从表里能看出,第二类并不是"更高级",只是相关间隔变了。这个变化导致它的频谱形状完全不一样,也决定了它适合不同的信道环境,后面第 5 节会展开讲。

3. 预编码:把差错扩散变成逐码元独立判决

3.1 不预编码的后果:一个误判传染一串错误

先看一个反例。假设我们不预编码,直接把原始数据做相关编码:c_k = a_k + a_{k-2}。接收端想恢复数据,只能解一个递推方程:

a_k = c_k - a_{k-2}

看起来没问题,麻烦在于递推会累积误差。只要某一个 c_k 因为噪声被误判,这个错误就会通过 a_{k-2} 传递到后面的码元,像多米诺骨牌一样倒下去。

举例最直观。设原始数据:

a = [1, 0, 1, 1, 0, 0, 1, 1, 0]

按 c_k = a_k + a_{k-2} 计算,得到:

c = [1, 0, 2, 1, 1, 1, 1, 1, 1]

现在假设 c_1 在传输中受到噪声干扰,被错误判决为 1(真实值是 0)。接收端从 c_0 开始递推:

  • a_0 = 1,正确
  • a_1 = 1,错误开始
  • a_2 = 2 - 1 = 1,碰巧正确
  • a_3 = 1 - 1 = 0,错误
  • a_4 = 1 - 0 = 1,错误但被抵消掩盖
  • a_5 = 1 - 0 = 1,错误
  • a_6 = 1 - 1 = 0,错误
  • a_7 = 1 - 0 = 1,错误

一个误判导致了一长串错误,这就是差错扩散。实际系统中噪声是连续的,错误扩散起来比这个例子更不可控。所以部分响应系统必须加预编码。

3.2 预编码公式怎么来的:从"想恢复什么"反推

预编码的目标是:让接收端的解调不再依赖递推,每个码元单独判决就能恢复出 a_k。做法是把 a_k 的信息"藏"进 b_k 的产生规则里。

我们希望接收端有:

a_k ≡ c_k (mod L)

把 c_k = b_k + b_{k-2} 代进去,得到:

a_k ≡ b_k + b_{k-2} (mod L)

于是发送端在生成 b_k 时,就可以这样反推:

b_k = (a_k - b_{k-2}) mod L

对于二进制,模 2 相减等于异或:

b_k = a_k XOR b_{k-2}

这样,接收端拿到 c_k 后,只需要做一次模 L 取余,就得到 a_k,根本不需要知道之前判决过什么,差错扩散链路被彻底切断。

这个推导过程值得反复体会:预编码不是凭空发明的技巧,它是从"接收端希望只依赖当前码元"这个需求反推出来的编码约束。通信原理里很多公式,与其死记不如这样反推一遍。

3.3 发射端和接收端的标准处理流程

整个第二类部分响应系统的处理流程可以概括为:

发射端:

  1. 原始数据 a_k 通过预编码器,计算 b_k = (a_k - b_{k-2}) mod L;
  2. 相关编码器计算 c_k = b_k + b_{k-2}(普通加法);
  3. 三电平序列 c_k 送入截止频率为 1/(2T) 的成形低通滤波器,形成实际发送波形。

接收端:

  1. 在码元时刻 kT 抽样,得到含噪声的样值 r_k;
  2. 将 r_k 量化到最近的三电平值(0、1、2);
  3. 对量化结果取模 L,得到 a_k 的估计值。

用伪代码表示发射端核心循环:

b_prev2 = 0; // 初始值 b_{-2} b_prev1 = 0; // 初始值 b_{-1},虽然公式不用,但移位需要 for each a_k: b_k = (a_k - b_prev2) mod L c_k = b_k + b_prev2 transmit(c_k) b_prev1 = b_k b_prev2 = b_prev1

注意第二类部分响应只需要保存两级移位寄存器,但真正参与运算的是相隔两级的那个值,也就是 b_prev2。实际写代码时很容易把 b_prev1 和 b_prev2 搞混,这是第一个容易踩的坑。

4. 手算推演:一组二进制数据走完整个链路

4.1 分步计算:a、b、c 三组序列

理论讲再多,不如亲手推一组数据。设二进制数据序列:

a = [1, 0, 1, 1, 0, 0, 1, 1, 0]

初始状态取 b_{-2} = 0,b_{-1} = 0。预编码用 b_k = a_k XOR b_{k-2},相关编码用 c_k = b_k + b_{k-2}。

一步步来:

ka_kb_{k-2}b_k = a_k XOR b_{k-2}c_k = b_k + b_{k-2}
01011
10000
21101
31011
40000
50112
61011
71101
80012

得到:

a = [1, 0, 1, 1, 0, 0, 1, 1, 0] b = [1, 0, 0, 1, 0, 1, 1, 0, 1] c = [1, 0, 1, 1, 0, 2, 1, 1, 2]

注意观察两点。第一,b 序列看起来和 a 序列没有直接对应关系,这是预编码带来的"记忆"效果。第二,c 序列出现三电平,其中 0 和 2 都对应原始比特 0,1 对应原始比特 1。接收端只要对 c 逐位取模 2:

c mod 2 = [1, 0, 1, 1, 0, 0, 1, 1, 0] = a

完美恢复,没有一个比特依赖递推。

4.2 引入一个噪声:单点误判不会扩散

现在模拟信道噪声。假设 k=5 时刻的 c_5 真实值是 2,但受到干扰后抽样值变成了 1.2,接收端量化到最近的电平 1。此时取模 2 得到:

a_5_hat = 1 mod 2 = 1

这一位判错了,正确值应该是 0。但关键问题是:a_6、a_7、a_8 会不会跟着错?不会。它们各自只依赖自己的 c_k 取模,c_6、c_7、c_8 没有受噪声影响,恢复结果依然正确:

a_hat = [1, 0, 1, 1, 0, 1(错), 1, 1, 0]

错误被隔离在出错的码元内部。这就是预编码最大的工程价值:不需要复杂的维特比译码或反馈判决,就能实现逐码元独立判决。

4.3 反向对照:同样一个噪声,不预编码就全乱

拿前面那组无预编码的例子做对照。同样假设 c_1 被误判为 1,接收端用递推恢复。前面已经看到,错误像滚雪球一样扩散到 a_1、a_3、a_5、a_7 等多个码元。有些位碰巧被抵消掩盖,但整体错误数量远超一个,而且这种扩散无法预测、无法补偿。

表格形式看更清楚:

判决方式误判位置受影响码元最终正确位数
有预编码,取模恢复c_5仅 a_58/9
无预编码,递推恢复c_1a_1、a_3、a_5、a_7 等一串明显劣化

同样是物理信道里一个随机噪声,预编码把损失限制在一个比特,不预编码则可能毁掉半段数据流。这就解释了为什么部分响应系统标准结构里,预编码是不可省略的环节,而不是可选的数学技巧。

5. 工程与学习建议:第二类没那么热门,但弄懂它的价值不小

5.1 第二类频谱形状带来的应用取向

第二类部分响应最常被忽略,但它的频谱特性其实很有特点。相关编码器的幅频特性是 |2cos(2πfT)|:在零频处幅值最大,随着频率升高快速下降,在 f = 1/(4T) 处出现第一个零点,然后在 f = 1/(2T) 处又上升到峰值。

对比一下,第一类部分响应的幅频特性是 |2cos(πfT)|,它在带内是单调下降的,低频能量非常集中,对低频响应很好的信道非常友好。第二类则在带内出现明显的起伏和过零点,低频部分衰减更快,所以它对信道低频响应不良的容忍度比第一类好一些。

不过要注意:第二类并没有根治直流分量问题,它在零频处仍有值。如果信道完全不能传直流,比如通过变压器耦合或者有隔直电容,第二类依然扛不住,那应该选第四类(c_k = b_k - b_{k-2})这类真正无直流分量的方案。选择部分的响应的类别,本质是匹配信道频谱特性,而不是追求"数字越大越先进"。

5.2 实操中几个容易踩的坑

第一个坑是相关编码误取模。有人为了偷懒,把 c_k 也写成 (b_k + b_{k-2}) mod 2,输出变成二进制。表面看接收端照样能恢复数据,但三电平特性没了,频谱整形没了,极限带宽也没了,部分响应系统白做了。

第二个坑是延迟抽头接错。第一类用一级延迟,第二类用两级延迟但中间抽头悬空,也就是系数 [1, 0, 1]。有的实现会把第二级和第一级混淆,导致公式变成 c_k = b_k + b_{k-1},那就变成第一类了,频谱特性完全错误。调试时如果发现输出波形频谱不对,先查延迟线。

第三个坑是接收端判决方式不统一。标准做法是先量化到 0/1/2 三电平,再对 2 取模。有些教材直接画成"三电平判决门限在 0.5 和 1.5",这样也没问题,但一定要意识到电平 0 和电平 2 在模 2 意义下等价。如果接收端只把 2 当成一个"高电平"而忘记取模,恢复出的序列就会整体错位。

第四个坑涉及术语混乱。不同教材对部分响应类别的命名不完全一致,有些文献里的 Class II 对应的多项式是其他形式,比如 (1-D)^2 或者 (1+D)^2。交流时最好直接说抽头系数或相关编码公式,避免只说"第二类"造成误解。

5.3 多进制扩展:从二进制到 L 进制

把预编码公式里的模 2 改成模 L,就是多进制部分响应。比如 L = 4 时:

b_k = (a_k - b_{k-2}) mod 4 c_k = b_k + b_{k-2}

c_k 取值从 0 到 6,共 7 个电平,接收端对 c_k 取模 4 恢复 a_k。每个码元携带 2 比特信息,频带利用率翻倍,但电平数更多,抗噪声能力下降。这个扩展并不复杂,只要理解了二进制的情况,多进制只是把加减法换成更大的模数。

学习时的一个建议:别只盯着第一类。把第一类、第二类、第四类放在一起对比推演,你会发现它们的预编码公式、抽头结构、频谱形状是相互关联的。自己用 MATLAB 或者 Python 写一个小脚本,生成随机二进制序列,按公式做预编码、相关编码、加高斯噪声、取模判决,跑几百个码元就能直观感受到"预编码阻断差错扩散"这一句话的真实含义。

我在实际推导中最大的体会是:第二类部分响应的难点不在数学,而在"预编码和相关编码到底谁先谁后、谁取模谁不取模"这个问题上。只要记住两句话——预编码用模 L 运算,目的是切断记忆;相关编码用普通加法,目的是生成多电平部分响应信号——整个链路就通了。通信原理里很多看似绕的编码结构,其实背后压着的都是这个"记忆与独立判决"的权衡。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询