NRZI (Non-Return-to-Zero Inerted code) 非归零翻转编码,之前,我先稍微记录一下他的前身
RZ 编码(Return- to - zero coding)
RZ 编码,简单的来说,就是在每一位普通的编码后面加了一个零电平。所以叫做归零编码,正电平代表1,后面再接一个0电平,告诉接收器该同步了,负电平代表0,然后又接一个0电平。 如下图所示。
可以看到,每一位后面都接了一位0电平,所以接收器在接收到 0 以后采样即可,这样就不用单独的时钟信号,实际上,RZ编码就相当于把时钟信号用 0 编码在数据之内,这样的信号也叫自同步(self-clocking)信号。 这样的做法虽然在物理上少了一根时钟线,但是在带宽上确有一大部分都用在归零上面了。
第二种演变,去掉归零 NRZ (Non - Return - to - Zero - code)编码,就是讲 RZ 编码的归零去掉
NRZ编码既是将逻辑1编码作为一个DC电平,逻辑0做为另一个DC电平。它与RZ码的区别就是它不用归零,也就是说,一个周期可以全部用来传输数据,这样传输的带宽就可以完全利用。一般常见的带有时钟线的传输协议都是使用NRZ编码或者差分的NRZ编码。因此,使用NRZ编码若想传输高速同步数据,基本上都要带有时钟线,因为本身NRZ编码无法传递时钟信号。但在低速异步传输下可以不存在时钟线,但在通信前,双方设备要约定好通信波特率,例如UART。
NRZ一般用于设备内的信号传输,对于串行传输,它有许多缺点:
(1)数据本身不携带时钟信息,因此不能自定时(即这样做虽然我们带宽不浪费了,但是我们的时钟线的同步信号又要另外给。);此外,一个全是1或全是0的长串编码结果就是一个固定的电平,没有跳变。
(2)它的DC分量随着数据流内容的变化而变化,低频内容往往占主导地位。
由于这些原因,除了低速短距离通讯,比如SPI等 外,NRZ很少用于串行传输。
第三种演变,NRZI(Non - Return - to - Zero - Inverted - code) 非归零反相编码
和NRZ 编码不同的是,NRZI 编码利用的电平的翻转来代表一个逻辑,当前电平相对于前一个电平不变代表0,当前电平相对于前一个电平相反代表1, USB 的传输就是用的 NRZI 编码格式,在USB 中,电平翻转代表逻辑1,电平不变代表逻辑0。限定最大0的数目,NRZI就可以实现自定时能力。比如,将全0的同步码反向,于是产生连续的跳变,这样便于PLL锁定。NRZI频谱依然有一个相对较高的低频分量,且它的直流分量也不是自由的(反转用0或是1,并不是一定的)。
数据同步问题
NRZ 和 NRZI 都没有同步的特性,但是,可以用一些比较特殊的技巧来解决,比如,先发送一个同步头,内容是0101010, 让接收着通过这个同步头来计算发出的频率,然后再用这个频率去接收之后的数据信号。
在USB 中,每一个USB的数据包,最开始的时候都有一个同步域,这个域定义为 0000 0001,这个域通过 NRZI 编码后,就是一个正负正负的方波,接收者可以通过这个方波计算频率,然后同步后面的数据。
此外,因为在USB的NRZI编码下,逻辑1会造成电平翻转,所以接受者在接收数据时,根据接收的翻转信号调整频率,保证数据传输正确。
但是,这样还会有一个问题,接收者可以主动和发送者之间频率匹配,但是两者之间总会有误差,假如数据是1000个逻辑0,经过 NRZI 编码后,很长时间都是同一个电平,这种情况下,即是接收者和发送者之间的频率相差千分之一,就是造成采样 999 个0或者是1001 个0。
USB 对这种问题的解决方法就是强制插一个1,规定为传输6个0后在数据中插入一个1,即发送前就会在第6个0后面强制插入一个1,就让发送的信号强制出现翻转,从而强制接受者调整频率,接受者只要删除6个1之后的那个0,就可以恢复原有的数据。