当前位置:网站首页>USB中用NRZI来编码数据

USB中用NRZI来编码数据

2022-08-11 05:25:00 Emily_rong_2021

USB中用NRZI来编码数据
 

USB所传输的数据,用的数据编码方式是NRZI(Non-Return-to-Zero Inverted),其具体的含义解释,看到有位网友已经非常清晰的分析过了,我就不重复造轮子了。

USB 的 NRZI 编码

(5条消息) 从零开始学USB(六、USB通讯的数据格式)_To_run_away的博客-CSDN博客_usb数据icon-default.png?t=LBL2https://to-run-away.blog.csdn.net/article/details/85038393

为了防止这位网友的服务器出问题,下面我再复制一份。

这两天继续看 USB 相关的内容,准备用纯软件实现一下 USB 设备传输,为将来的项目打好基础。

首先碰到的就是这个 NRZI 编码的问题了,基础太薄弱,看了一上午总算明白了大概。

首先,USB 的数据是串行发送的,就像 UART、I2C、SPI 等等,连续的01 信号只通过一根数据线发送给接受者。

但是因为发送者和接收者运行的频率不一样,信号的同步就是个问题,比如,接受者接收到了一个持续一段时间的低电平,无法得知这究竟是代表了5个0 还是1000个0。

一个解决办法,就是在传输数据信号的同时,附加一个时钟信号,用来同步两端的传输,接受者在时钟信号的辅助下对数据信号采样,就可以正确解析出发送的数据了,比如 I2C 就是这样做的,SDA 来传输数据,SCL 来传输同步时钟:


图为I2C数据编码格式

 

虽然这样解决了问题,但是却需要附加一根时钟信号线来传输时钟。有没有不需要附加的时钟信号,也能保持两端的同步呢?

有的,这就是 RZ 编码(Return-to-zero Code),也叫做归零编码。

在 RZ 编码中,正电平代表逻辑 1,负电平代表逻辑 0,并且,每传输完一位数据,信号返回到零电平,也就是说,信号线上会出现 3 种电平:正电平、负电平、零电平:
归零编码

从图上就可以看出来,因为每位传输之后都要归零,所以接收者只要在信号归零后采样即可,这样就不在需要单独的时钟信号。实际上, RZ 编码就是相当于把时钟信号用归零编码在了数据之内。这样的信号也叫做自同步(self-clocking)信号。

这样虽然省了时钟数据线,但是还是有缺点的,因为在 RZ 编码中,大部分的数据带宽,都用来传输“归零”而浪费掉了。

那么,我们去掉这个归零步骤,NRZ 编码(Non-return-to-zero Code)就出现了,和 RZ 的区别就是 NRZ 是不需要归零的:


图为非归零编码

这样,浪费的带宽又回来了,不过又丧失宝贵的自同步特性了,貌似我们又回到了原点,其实这个问题也是可以解决的,不过待会儿再讲,先看看什么是 NRZI:

NRZI 编码(Non-Return-to-Zero Inverted Code)和 NRZ 的区别就是 NRZI 用信号的翻转代表一个逻辑,信号保持不变代表另外一个逻辑。

USB 传输的编码就是 NRZI 格式,在 USB 中,电平翻转代表逻辑 0,电平不变代表逻辑1:


图为NRZ和NRZI

翻转的信号本身可以作为一种通知机制,而且可以看到,即使把 NRZI 的波形完全翻转,所代表的数据序列还是一样的,对于像 USB 这种通过差分线来传输的信号尤其方便~

现在再回到那个同步问题:

的确,NRZ 和 NRZI 都没有自同步特性,但是可以用一些特殊的技巧解决。

比如,先发送一个同步头,内容是 0101010 的方波,让接受者通过这个同步头计算出发送者的频率,然后再用这个频率来采样之后的数据信号,就可以了。

在 USB 中,每个 USB 数据包,最开始都有个同步域(SYNC),这个域固定为 0000 0001,这个域通过 NRZI 编码之后,就是一串方波(复习下前面:NRZI 遇 0 翻转遇 1

此外,因为在 USB 的 NRZI 编码下,逻辑 0 会造成电平翻转,所以接收者在接收数据的同时,根据接收到的翻转信号不断调整同步频率,保证数据传输正确。

但是,这样还是会有一个问题,就是虽然接收者可以主动和发送者的频率匹配,但是两者之间总会有误差。

假如数据信号是 1000个逻辑1,经过 USB 的 NRZI 编码之后,就是很长一段没有变化的电平,在这种情况下,即使接受者的频率和发送者相差千分之一,就会造成把数据采样成 1001个或者 999个了。

USB中用Bit-Stuffing来同步时钟信号
USB对这个问题的解决办法,就是强制插0,也就是传说中的bit-stuffing,如果要传输的数据中有6个连续的1,发送前就会在第6个1后面强制插入一个0,让发送的信号强制出现翻转,从而强制接受者进行频率调整。这就使得接收器,逻辑上至少每7个位会出现一次电平转换,用来保证数据和时钟同步。接受者只要删除6个连续 1 之后的0,就可以恢复原始的数据了。

当然在协议中,这两点说的也比较清晰,对着协议看一下就可以知道NRZI的编码规则。

————————————————
版权声明:本文为CSDN博主「奔跑的小刺猬」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_16777851/article/details/85038393

 

 

 

 

原网站

版权声明
本文为[Emily_rong_2021]所创,转载请带上原文链接,感谢
https://blog.csdn.net/Emily_rong_2021/article/details/122405451