USB的NRZI编码机制和位填充机制

1.数据传输前的准备工作

USB是串行总线,数据是一位一位的传送,LSB(最低位)在前,MSB(最高位)最后。

USB 数据传输在发送前要先做一系列编码(NRZI、位填充、Sync、EOP 等),根本目的只有一个:把"纯数据比特流"变成"自带时钟、不怕抖动、还能在线缆里抗干扰的电气波形"。因为 USB总线只有4根线,Vbus(5V电源线)、GND地线,D+、D-:USB差分数据线:没有时钟线,只有数据差分线。

2. 数据传输格式

USB总线上传输数据是以包为基本单位,一个包被分成不同的域。

不同类型的包,包含的域不同。不同包的共同点:

【同步域】开始------【PID】包标识符------【。。。】------【EOP】包结束符

2.1 同步域

告诉USB的串行接口引擎SIE,数据要开始传输了,请做好准备。

同步域就是一串特定的字符串,如同步域为00000001时,而0在USB总线上就被编码为电平翻转,经过NRZI编码后形成方波提供时钟信息。因此同步域还可以用来同步主机端和设备端的数据时钟。

图解:前7个0产生7次电平翻转(规则见下述3.2章节),形成完美的方波,接收方可以通过这个方波精确计算出时钟频率,最后一个1(保持不变)标志着同步域结束

对于全速和低速设备,同步域使用的是00000001(二进制数,总线上的发送顺序),

对于高速设备,同步域使用的是31个0后面跟1个1(这是发送端的要求,接收端解码时0的个数可以少于这个数。)

3. USB数据编码序列

USB原始数据 ----> 位填充 ------> NRZI编码

USB原始数据,先经过位填充,由串行接口引擎SIE将数据串行化,再经过NRZI编码形成数据序列。在接收端,刚好是一个反过程:PLL同步:使用同步域的方波锁定时钟,接收端采样数据线,NRZI解码:根据电平变化恢复原始数据,由SIE将数据并行化(反串行化),去位填充:删除6个连续1后面的填充0,恢复出原来的数据,CRC校验:验证数据完整性。

3.1 位填充机制 - Bit Stuffing

位填充机制规则很简单:

每6个连续1后强制插入一个0,这个0会强制产生电平翻转; 接收方检测到6个1后,自动删除后面的0。

原始数据: 11111111111

位填充后: 1111110 1111110

↑ ↑

插入0 插入0

上图7.1.9章节为USB协议种关于Bit Stuffing的具体描述。大意为:

确保信号具有足够的跳变,发送端在 USB 上发送数据包时必须使用位填充。

做法:对原始数据流进行 NRZI 编码之前,只要遇到连续 6 个 1 ,就在其后插入 1 个 0

目的:在 NRZI 波形中强制产生一次电平翻转,使接收端每 7 个位周期内至少能见到一次跳变,从而维持时钟同步。

位填充从同步字段(Sync Pattern) 开始生效;同步字段末尾的那个"1"算作第一个连续 1。

除高速模式的 EOP(包结束)段外,发送端必须严格执行位填充;即使插入的 0 紧邻 EOP 信号,也不能省略。

接收端在 NRZI 解码后,必须识别并丢弃这些被填充的 0 位,以还原原始数据。

全速/低速设备的usb总线在整个数据包内无一例外地 执行位填充。

若接收端在包内任何位置检测到连续 7 个"1",则判定为位填充错误,该包必须被丢弃。

在 EOP(包结束)之前的那段时间是特例:

由于集线器开关切换会引入抖动(称为 dribble),最后一个数据位可能被拉长,从而出现图 7-33 所示的情况------dribble 导致第 6 个"1"出现,但并不 需要再插入填充 0。因此,接收端必须允许在 EOP 前出现最多 6 个完整位周期内无任何跳变 的现象,而不得将其视为违规。

3.2 NRZI编码

核心编码规则 USB使用NRZI(Non-Return-to-Zero Inverted)编码:

编码规则体现在波形上:

  • 遇到 数据1 → 电平保持

  • 遇到 数据0 → 电平翻转 (J→K 或 K→J)

上图为USB协议中的数据编解码解析:USB 在发送数据包时使用 NRZI 编码。在 NRZI 编码中,逻辑"1"用电平保持不变 表示,逻辑"0"用电平发生变化表示。图 7-31 展示了一组数据流及其对应的 NRZI 波形。图中高电平代表数据线上的 J 状态;后续所有 NRZI 波形图均沿用此约定。连续的 0 会使 NRZI 波形在每个位周期都翻转一次,而连续的 1 则会导致长时间无电平跳变。

3.3 NRZI解码

接收端只要检测边沿就能恢复时钟,再按"有边沿=0,无边沿=1"解出原始数据。

问题1. 为什么需要"翻转"?

A1.1 主要原因:时钟恢复的根本需求

嵌入式时钟:USB没有单独的时钟线,时钟信息必须嵌入在数据信号中

边沿检测:接收方通过检测电平跳变来恢复时钟频率

同步需求:连续的0提供频繁的边沿,帮助接收方同步本地时钟

这种设计让USB在没有单独时钟线 的情况下,实现了高速、可靠的串行数据传输

A1.2 解码的唯一性

NRZI解码必须可逆,规则必须绝对确定:如果有些0不翻转,解码器就无法区分这是0还是1,整个协议就会崩溃!

编码规则:0→翻转, 1→保持

解码规则:翻转→0, 保持→1

问题2. 是所有的数据0 全部进行数据翻转吗?

在USB的NRZI编码中,所有的数据0都会引起电平翻转,没有例外!没有例外!

在USB的NRZI编码中,每一个数据0都会强制电平翻转 ,这是USB协议的铁律!

问题3.数据0 什么时候J->K, 什么时候K->J?

这是个关键细节问题!

数据0的翻转方向完全取决于"当前电平状态" ,而不是0本身有什么特殊属性。

如果当前是J状态 → 翻转后变成K状态

如果当前是K状态 → 翻转后变成J状态

相关推荐
peterhunter03202 小时前
CONFIG_CPU_SW_DOMAIN_PAN
linux
zfj3212 小时前
Linux 系统 I/O 监控命令大全
linux·服务器·数据库·io·监控
___波子 Pro Max.2 小时前
Linux下的posix_spawn接口使用场景及与fork区别
linux
oMcLin2 小时前
Linux 系统服务器的 KVM 虚拟化实战:搭建、配置与管理
linux·运维·服务器
飞Link2 小时前
【Hive】Linux(CentOS7)下安装Hive教程
大数据·linux·数据仓库·hive·hadoop
TPBoreas2 小时前
清理服务器日志空间
linux·运维·服务器
Howrun7772 小时前
Linux进程通信---1---匿名管道
linux
天骄t3 小时前
HTML入门:从基础结构到表单实战
linux·数据库
大聪明-PLUS3 小时前
了解 Linux 系统中用于流量管理的 libnl 库
linux·嵌入式·arm·smarc