☰
RZ、NRZ、NRZI与曼彻斯特编码:数字信号传输的底层逻辑与工程选型
2026/10/6 9:40:52 网站建设 项目流程

1. 先搞清楚一件事:比特到底怎么变成"看得见"的信号

1.1 一条网线或者一根PCB走线里,1和0的本质是什么

做嵌入式、通信或者网络底层开发的工程师,迟早会跟RZ、NRZ、NRZI、曼彻斯特编码这些词打交道。第一次看协议文档的时候,满屏都是"归零码""非归零码""翻转""位中间跳变"之类的术语,感觉像在看天书。我当时也是硬着头皮啃,后来被几回现场问题教育过,才明白这些编码方式其实都是在解决同一个问题:怎么让一串抽象的01数据,在真实的导线、光纤、空气中被可靠地传输过去。

先别急着背规则,先想想底层:一根导线里只有电压和电流,没有"1"和"0"。所谓数字信号,不过是把电压高低约定成逻辑值。高电平代表1,低电平代表0,这是最朴素的编码思想。可一旦到了实际工程,事情就没那么简单。接收端怎么知道一个bit什么时候结束、下一个bit什么时候开始?如果发送端连着发出100个0,接收端看到的是一整段平静的低电平,它怎么判断这是100个0还是50个0?再比如,发送端如果长时间输出高电平,变压器之类的耦合器件会不会被"憋死"?编码方式本质上是"怎样用电压波形,把比特流里的时间信息和数据信息一起打包好"。

我当年调试SPI总线时就吃过这个亏。示波器上明明是漂亮的方波,主从设备却偶尔错一位,查了半天也找不到逻辑漏洞。后来才意识到,问题不在波形漂不漂亮,而在接收端有没有可靠的采样时钟。SPI有独立的时钟线,所以问题不大;但很多串行总线没有单独的时钟线,接收端只能从信号本身的跳变里去恢复时钟。哪种编码能提供更多有规律的跳变,哪种就更容易让接收端"跟上节奏"。RZ、NRZ、NRZI、曼彻斯特这四种方案,本质上就是一套比一套更舍得用跳变,同时也在用带宽和复杂度换可靠性。

1.2 三个绕不开的核心矛盾:时钟、直流、带宽

要把编码方式讲透,先得建立三个评价维度,后面所有对比都围绕这三件事展开。

第一是时钟同步能力。数字接收端的采样时刻如果和发送端漂移,就会采错电平。解决办法是从信号自身的跳变沿里恢复采样时钟,跳变越多、越规律,恢复越容易。这就像两个人对话,如果说话的人每说几个字就停顿一下,听的人很容易跟上节奏;如果一口气匀速念一大段,听的人稍微走神就不知道说到哪了。RZ、曼彻斯特就属于"每几个字都停顿"的类型,NRZ则是"一口气念到底"的类型。

第二是直流分量。一段信号的长时间平均电压如果明显偏离0V,就叫有直流分量。直流分量对很多场景是致命的:变压器无法传直流,所以网口PHY通过变压器耦合时,信号里带直流会让磁芯趋向饱和,波形直接被拉坏。光纤通信里,直流分量高意味着平均光功率偏高,影响激光器寿命和接收机灵敏度。另外,某些协议里长时间传输连续0或连续1,线路上的平均电平会漂移,接收端比较器的判决阈值也会跟着漂,最终把有效信号采错。

第三是带宽效率。信号的跳变越频繁,高频分量越高,在同样的物理线路上占用的带宽越大。带宽是硬资源:铜线长了会衰减,射频有频谱限制,总线寄生电容也摆在那里。所以"能用一个固定电平持续多久就持续多久"的NRZ类方案带宽最省,"每个bit都要跳变"的曼彻斯特最费带宽。工程上没有免费的午餐,所谓好的编码方式,就是在这三者之间找到适合自己场景的平衡点。

2. RZ和NRZ:一对"勤快"与"偷懒"的兄弟

2.1 RZ(归零码):每个比特都回零,时钟藏在跳变里

RZ的全称是Return-to-Zero,归零码。它的规则很"勤快":表示逻辑1时,先把电平拉高,但只保持半个位周期,然后必须回到零电平;表示逻辑0时,整个位周期保持零电平。也就是说,只要数据里出现1,信号就会有一次清晰的高脉冲,这个脉冲自带"开始"和"结束"两个边沿,接收端看到边沿就能恢复时钟。

举个例子,发送比特流1011,RZ的波形会是这样:第一个bit是1,前半个周期高电平,后半个周期回0;第二个bit是0,整个周期都是0;第三个bit是1,高半个周期再回0;第四个bit是1,又高半个周期再回0。你会发现,波形里高电平都是"一小段一小段"的,看起来就像脉冲串。这种脉冲串结构让解码变得很直观,只要检测到高电平就算1,没有就算0,而且跳变事件足够多,锁相环很容易锁定。

但RZ的代价也很明显。第一,带宽消耗大。同一比特率下,RZ波形里最高的信号成分频率相当于比特率的2倍,因为每个bit内部都多来一次"高到低"的跳变,线路实际需要的带宽比NRZ高出一截。第二,平均电压偏低。大量时间是零电平,信号的能量主要靠那半拍高电平维持,长距离传输时信噪比不如NRZ。第三,它对电平判决阈值比较敏感。如果回零阶段和逻辑0都共用零电平,那接收端要分辨"高脉冲"和"零"两个状态,比纯粹的高/低两态判决更容易受噪声影响。

有人可能会问:RZ是不是就被淘汰了?并没有。光通信里的PAM4、PAM8这类多电平调制,从"脉冲后回到基准电平"这个意义上看,就是广义的RZ思路;一些传感器输出的单总线协议、早期的磁记录设备也用类似归零结构,主要图它自带时钟、解码简单。只是在普通铜线上的高速数字传输里,RZ确实不是主流,因为它太"浪费"电平状态了。

2.2 NRZ(非归零码):电平保持一个位周期,效率最高但最"懒"

NRZ全称Non-Return-to-Zero,非归零码。最常见的理解就是:1对应高电平,0对应低电平,整个bit周期内电平保持不变,不回到零。这也是大家在逻辑分析仪上最熟悉的波形,几乎下意识认为数字信号就该长这样。

NRZ的优点非常实在:简单、直接、带宽最省。同样的比特率,NRZ的信号基波频率最低,对高频衰减和串扰不敏感,所以在同等物理条件下,NRZ往往能把速率推到更高。这也是为什么几乎所有高速SerDes内部的核心数据通路,在均衡和预加重之后,最终跑在线上仍然是一种NRZ形态的信号——不是说工程师不想用别的编码,而是NRZ的带宽效率最高,能省一点是一点。

但NRZ的毛病是结构性的:如果连续出现多个相同bit,信号长时间没有任何跳变,接收端就无法从信号里恢复时钟。比如发送100个连续的1,线上就是一条平坦的高电平,接收端只能靠自己的本地时钟硬撑。只要两端晶振稍有偏差,或者噪声导致PLL失锁,马上就会采错。此外,长串相同电平意味着信号平均值严重偏向一侧,直流分量很大,变压器耦合、交流耦合的直接没法用。

为了解决这两个病,工程上一般不会让NRZ裸奔。8B/10B编码、64B/66B编码、还有各种扰码器(scrambler),本质都是先把数据流"打散",保证线路上的信号有足够多的跳变,同时让0和1出现的几率尽量接近。所以你看到的PCIe、SATA、千兆以太网物理层,虽然线路上跑的波形可以叫NRZ,但其实是经过编码、扰码后的数据,绝不是把CPU给的原始数据直接怼上去。这个细节很重要,很多人调高速链路时以为"NRZ就是简单高/低电平",结果忽略了对数据流的预处理,最后眼图惨不忍睹。

3. NRZI:不关心"是高是低",只关心"变没变"

3.1 从"电平"到"跳变"的思路转变

NRZI的全称是Non-Return-to-Zero Inverted,非归零反向码。它和NRZ的核心区别在于:NRZ把"电平高低"当信息,NRZI把"电平有没有变化"当信息。最常见的USB方案约定是:遇到逻辑0,电平保持不变;遇到逻辑1,电平翻转一次。有些资料也会写"1不变、0翻转",那是另一种约定,不同协议里定义不一样,看文档时务必先确认是哪家的规矩。

为什么会有这种思路?因为在很多差分传输的场景里,接收端真正关心的是"有没有发生翻转"这个事件,而不是"当前电压是高是低"。比如USB就用一对差分线D+和D-,接收端比较两线电压,具体哪根线高、哪根线低其实没那么重要,重要的是有没有跨越阈值的事件发生。NRZI把1对应为翻转,那么数据流里只要1出现得够多,信号就不断在翻,接收端就能获得持续的时钟参考。

NRZI的另一个好处是带宽效率高。它不像RZ那样每个bit回零,也不像曼彻斯特那样每个bit都强制跳变,电平可以在整个位周期内保持,所以同等比特率下,线路上的高频率成分跟NRZ基本相当。这在USB那个年代是很宝贵的:低速USB才1.5Mbps,全速12Mbps,但当时的MCU主频和线缆质量都不高,用曼彻斯特会让线路波特率翻倍,压力会大不少。

3.2 位填充(bit stuffing)是如何救场的

NRZI有一个绕不开的弱点:连续的0依然没有跳变。如果数据流里出现一长串0,NRZI和NRZ一样无能为力,接收端时钟照样失锁。所以NRZI几乎从不单独使用,必须搭配"保跳变"机制,最典型的就是位填充(bit stuffing)。

USB低速/全速的做法很有代表性:发送端在数据流中如果检测到连续6个1,就强制插入一个0,使线路上的实际bit流变成连续7个1中间必然夹一个0的结构。为什么是6个1?因为按USB的NRZI约定,1会引发翻转,连续6个1意味着信号已经翻了6次,如果能保证在这之后不出现太长的无跳变区间,接收端的PLL就可以在短时间里维持锁定。插入0是为了打断"长时间不跳变"的危险区间。

位填充的本质,是用极小比例的带宽冗余,换掉信号长时间静止的风险。代价是接收端必须做解填充:收到连续6个1之后,要判断第7个bit到底是填充的0还是真实数据。接口控制器里的位填充/解填充电路就是干这个活的。如果实现有误,就会出现经典的"插0丢0"错误,抓包时看到USB帧错乱,很多时候根子就在这。

还有一个容易忽略的细节:位填充不能随意延迟,它要求硬件在发送路径上实时扫描bit流并插入,这会影响发送延迟和吞吐。USB全速模式名义12Mbps,经过位填充后实际线路速率会稍微高于名义值,所以用协议分析仪观察时,实际波形速率和标称速率不完全一样,别大惊小怪。我自己写FPGA USB控制器时,位填充逻辑的仿真case一定要覆盖"最长连续1"的边界,否则上板后会出现偶发断帧,那种问题极难查。

3.3 为什么USB偏偏选NRZI

很多人会问:USB明明可以选曼彻斯特编码,连位填充都省了,为什么偏要选NRZI?原因主要有三点。

第一是带宽效率。低速USB只有1.5Mbps,全速12Mbps,但当时MCU性能有限,线缆质量也很一般。NRZI接近NRZ的带宽效率,而曼彻斯特会让线路波特率翻倍,对廉价USB线缆和普通IO来说压力更大。第二是收发器复杂度。NRZI只需要一个差分驱动器和比较器,翻转逻辑非常简单;曼彻斯特则需要精确的双沿生成电路,对晶振稳定度和时序约束要求更高,成本自然上去。第三是历史延续性。USB设计时参考了大量成熟的串行总线经验,NRZI加位填充的组合在硬盘接口、网络接口里已经验证过,风险和不确定性最小。

当然,NRZI也不是没有缺点。它没有曼彻斯特那种"每位必有跳变"的强保证,时钟恢复完全依赖位填充兜底;同时它对"1"和"0"翻转不对称,长期来看DC平衡不如曼彻斯特。所以USB后来在高速模式(480Mbps)转用了更复杂的方案,NRZI只在低速和全速的历史舞台上保留。这不是NRZI不行,而是在越来越高的速率下,需要更先进的编码来兼顾带宽和同步。

4. 曼彻斯特编码:把"变化"本身变成信息

4.1 编码规则:每位中间必须跳变,方向定0/1

曼彻斯特编码(Manchester Encoding)的规则,所有教材里都差不多:每个bit周期正中间,必定有一次电平跳变;用这次跳变的方向来区分0和1。最常用的IEEE 802.3里10BASE-T的定义是:位中间从高到低跳变表示逻辑1,从低到高跳变表示逻辑0。但请注意,很多RFID标准用的就是相反约定,所以看资料时先确认是哪家定义,再对波形,否则会把0和1全部读反。

这里要特别强调"位中间必有跳变"这句话,它不只是说"大多数时候有跳变",而是每一位都有。这意味着曼彻斯特信号在任何位置都能提供一个边沿事件,接收端锁相环锁定的难度极低,哪怕数据流是清一色的0或1,同步也完全不会丢。这个特性在低速、长距离、时钟精度不高的场合极其珍贵。

同时,在位与位的交界处,电平可能保持不变,也可能再次跳变,边界处的跳变只是为了衔接相邻bit的电平状态,并不承载数据。所以看波形时别搞混:只有位中间的跳变才是"信息",边界跳变是"附属品"。用示波器观察的时候,你数一下每个bit格子里,必然至少有一个中间沿,多出来的那些是边界沿。这也是曼彻斯特信号和普通NRZ最直观的区别:它永远不可能静静地保持一个电平静止一个完整位周期。

4.2 为什么说它"自带时钟"且没有直流分量

自带时钟很好理解,每位一跳动,相当于在数据流里嵌入了时钟信号。接收端可以直接从信号沿恢复采样时钟,不需要额外的时钟线。这也是曼彻斯特适合"只有两根线(信号+地)、又不方便传时钟"的场景的原因。典型例子是RFID:标签没有独立电源,也没有时钟线,读卡器发过来的载波和被调制的曼彻斯特信号,对方直接从边沿里恢复工作时钟,整个握手才能进行。

直流分量方面,曼彻斯特的每位中间跳变,意味着每个bit内高电平时间和低电平时间基本各占一半,长时间平均电压非常接近0,信号里几乎没有低频直流成分。这就让它可以轻松通过变压器、电容耦合,不会因为连续长时间高电平把隔直电容充到饱和。老式10BASE-T以太网用曼彻斯特信号,经过变压器送到双绞线上,靠的就是这种DC平衡特性。变压器不传直流,如果信号有直流分量,磁芯会被单向磁化到饱和,波形直接畸变,后端的均衡器根本救不回来。

但DC平衡不是免费的。前面说了,曼彻斯特的基波频率等于比特率的2倍,实际需要的信道带宽比NRZ大一倍。10Mbps以太网用曼彻斯特,线上等效波特率是20Mbaud,这就是为什么10BASE-T只能停留在10Mbps,而百兆以太网必须换用4B5B加MLT-3等新方案来节省带宽。编码在"自带时钟、DC平衡"和"带宽翻倍"之间,没有回头路可走。

4.3 差分曼彻斯特编码:抗干扰的升级版

曼彻斯特还有个变体叫差分曼彻斯特编码(Differential Manchester Encoding)。它的规则是:每个bit中间依然必有一次跳变,但0和1不是靠跳变方向区分,而是靠位起始处有没有额外跳变来区分。通常约定是:位起始处有跳变表示0,没有跳变表示1,或者反过来,各标准不一。

差分版本的最大好处是抗极性和抗地电位漂移。如果两根信号线接反了,普通曼彻斯特会把0和1全部对调,解码结果完全错乱;差分曼彻斯特只看"跳变有无"而不是"电平高低",极性反了也照样判断。同理,它对共模噪声、地电位差异也更钝感。在很多工业总线、RFID系统里,差分曼彻斯特至今还在用,拼的就是这个鲁棒性。

不过它的波形边界跳变更密集,硬件判断逻辑稍微复杂一点,解码时需要同时跟踪"上一个状态"和"当前bit起始处有没有翻转"。新手容易在状态机的状态转换上出错,调试时先给固定数据比如0x55,一眼就能从示波器波形上验证有没有写反。

5. 同一根示波器下看四种波形:关键指标横向对比

5.1 效率、自同步、直流、抗干扰一览表

光讲规则容易晕,列个表就清楚了。这里统一按"相同的逻辑比特率"来比较各种编码在物理链路上的表现:

编码方式跳变密度线路等效波特率自同步能力直流分量硬件复杂度典型应用
RZ每个1有跳变,0没有最高约2倍依赖1的密度低中早期磁记录、部分传感器总线
NRZ依赖数据,长0/长1时无跳变1倍差高,易基线漂移极低UART、SPI、SerDes内部
NRZI每个1翻转,0无跳变1倍依赖1密度,需位填充兜底中低USB低速/全速
曼彻斯特每位1次,100%2倍极好极低,DC平衡中高10BASE-T、RFID

表格里"线路等效波特率"指的是物理信号实际翻转速率相对于bit率的倍数。曼彻斯特和RZ都需要更宽的带宽,NRZ/NRZI在这一点上最"省钱"。但这不是说NRZ一定好,而是不同应用对同步稳定性和带宽代价的权重不一样。你要传几十公分PCB走线,NRZ完全够用;你要传几十米隔离链路还想省一根时钟线,曼彻斯特的价值立刻体现。

5.2 从波形看"误码扩散"现象

四种编码还有一个容易被忽略的差异:单个bit错误之后,错误会不会"传染"给后面的bit。NRZI是重灾区,因为它用"翻转与否"来解信息,一旦某一位采样错误,接收端得到的当前电平状态就是错的,之后所有bit再基于这个错误状态去判断"变没变",结果就是这个错误会一路滚下去,直到下一次能够"重新对齐"的同步事件出现。所以NRZI系统往往在数据头部放同步码序列,同时配合CRC校验,一旦出错就整帧重传,不让错误一路蔓延。

曼彻斯特则相反,它有比较强的错误自检倾向。传统曼彻斯特编码中,每一位都应当满足"中间必有跳变"和"高/低占空比接近一半"这两个约束,一旦噪声破坏了其中一个,接收端可以立刻判断这不符合合法码型,从而打出错误标志。这也是为什么一些用曼彻斯特的协议,误码检测可以做得相对简单,不需要帧尾大量CRC兜底。

RZ和NRZ的表现取决于具体实现。RZ因为每个1后面紧跟零电平,对毛刺的容忍度稍好;NRZ一旦采样点落在错误的判定位上,通常是一个整bit错,但由于没有状态记忆,错误不会扩散到后续bit。归纳成一句话:编码里的高频跳变能换来自同步和自检测能力,代价是带宽;带宽省了,就得用填充、校验机制去弥补同步和检测的缺失。

6. 项目选型实战:这些编码在真实设备里都怎么用

6.1 串口为什么不直接用曼彻斯特

很多人学完曼彻斯特会觉得它"完美",然后产生一个经典疑问:为什么我天天用的UART还是"裸"的NRZ?关键在"异步"两个字。UART根本不去信号里恢复时钟,它靠通信双方预先约定波特率,然后在每个字节前面加起始位来"对表"。字节内部只有8个bit,时间很短,只要两端晶振误差在允许范围内,接收端用本地时钟采样完全够用,不需要每位都携带时钟边沿。所以在短距离、低速率、双方晶振可靠的场景,NRZ加起始位/停止位就是最划算的方案。

如果硬改成曼彻斯特,意味着RS-232线路的波特率要翻倍,电平还要严格对称,旧式MCU的IO根本跑不动,成本完全划不来。反过来,如果传输距离很长、接收端无法保证时钟精度、或者线路要过变压器,UART那种裸NRZ就力不从心了,曼彻斯特的优势才能真正体现。选什么编码,从来不是"哪个更先进",而是"哪个刚好够用且最便宜"。

6.2 CAN、USB、以太网各自的选择逻辑

把这些编码放到真实协议里看,选型逻辑非常清晰:

  • CAN总线用的是NRZ加位填充。CAN的位时间本身就有同步段和相位段,节点通过帧起始和填充位保持同步,同时差分信号提供共模抗扰。它没用曼彻斯特,是因为现场总线在乎波特率效率,而且CAN协议自带非常强的错误处理机制,已经能兜住NRZ的同步弱点。
  • USB低速/全速用NRZI加位填充,核心诉求是省带宽、省硬件,前面已经细说了。
  • 老式以太网10BASE-T用曼彻斯特,为的是变压器隔离下的DC平衡和自时钟;百兆以太网改用4B5B加MLT-3,是因为100Mbps下曼彻斯特需要200Mbaud带宽,双绞线实在扛不住;千兆以太网干脆用PAM5多电平调制。每一代升级,本质上都是在带宽效率、DC平衡、时钟恢复之间重新找平衡。

看多了会发现一个规律:低速、低成本、可靠性优先的总线,偏爱带自同步的编码;高速、带宽紧张的链路,偏爱NRZ类加编码表或扰码器;对直流敏感、要过变压器的场景,一定优先考虑DC平衡方案。

6.3 我的踩坑记录与调试建议

最后分享几个实际项目中踩过的坑,都是常规文档里不会写的。

第一个坑:DC不平衡导致的变压器饱和。有段时间我想做一个私有协议,直接把基于NRZ的串行数据怼进带变压器的以太网PHY前端,结果示波器上看到的信号眼图一塌糊涂。后来才意识到,NRZ长时间出0或出1会让变压器磁芯进入饱和,波形被拉得变形,根本不是后端均衡能救的。解决办法要么换DC平衡编码,要么做8B/10B或者加扰码,让平均电平稳住。

第二个坑:时钟容差被忽视。设计一条长距离RS-485链路时,选了普通NRZ,两端晶振都是20ppm,理论上完全够用。实际线缆一长、地电位有差异,接收端采样点抖动变大,偶尔就整包错。后来我在接收端用了边沿触发再配合软件重采样,并在数据帧前面加了更长的前导码,问题才缓解。NRZ不是不能用,但你的系统必须给它足够的同步预处理。

第三个坑:示波器上判断编码方式时,别只盯着高低电平看。NRZI和NRZ的波形长得几乎一模一样,区别只在"翻转代表什么"。如果你不知道USB协议头部有同步序列,抓到的波形很容易被当成普通NRZ来读,然后得出完全错误的逻辑电平。我的建议是,调试任何新总线前,先找到协议文档里的同步码型,比如USB的SYNC字段,用示波器做触发条件,一下子就能看清编码规则和边界跳变。

我在实际项目里体会最深的一点是:编码方式决定的不只是波形好不好看,而是整个系统的误码率、成本和设计复杂度。搞懂RZ、NRZ、NRZI、曼彻斯特编码的取舍,比背下再多定义都有用。下次画原理图或写FPGA逻辑时,多问一句"这个信号走的是什么编码,它的时钟和直流靠什么保证",很多底层问题就能提前规避。

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

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

立即咨询