USB通信格式
USB接口最少有四根线连接,其中有两根是数据线,而所有的USB数据传输都是通过这两根线完成的,那么它是怎么做到的?
我们知道,串口为了实现通信,规定了起始位、停止位,有时候也可能增加奇偶校验位,如果你知道了串口的波特率,那么你就可以正确的接收到发送方发来的数据。那么USB应该也有相应的通信格式要求才对,那它的格式是怎么样的?
串口中高电平代表1,低电平代表0,并且是全双工通信,即可以同时发送和接收数据。而 USB 有所不同,它虽然也有两根数据线,但它们却是采用差分传输,即需要两根数据线配合才能传输一个bit,因此是半双工通信,同一时间只能发送或者接收。
首先我们需要了解一下差分 0 和差分 1 这两种状态:差分1:数据线 D 为高电平, D- 为低电平时为差分 1;差分0:数据线 D 为低电平, D- 为高电平时为差分 0。
但是要注意的是,这里的差分0、差分1可不是代表数据0和1,而仅仅只是数据线表现的状态,和真正的数据还有距离。USB 规定,如果电压电平不变,代表逻辑1;如果电压电平变化,则代表逻辑0,这就是 NRZI 。
看下图进行理解:
USB不通信时,数据线处于闲置状态(类似于串口的高电平闲置),一旦需要开始通信,首先切换到K状态(类似串口的起始位),再进行实际的数据传输,在这里传输的数据为 000011,实际的数据线状态为差分101000,传输完毕后需要发送结束信号EOP:2位的 SE0,再加 1 位的J状态(类似串口的停止位)。
这里只是简单的说明,实际上的数据传输比这个还要复杂一些,但大体是一致的。并且需要注意的是,上述描述的闲置状态和J、K等状态和设备类型有关,即全速设备和低速设备这些状态的定义不同(这个可能和设备数据线的上拉电阻位置相关)。
AN57294采用 NRZI 编码的好处是可以不需要时钟线进行同步,但是为了实现准确的采样,需要两个条件:
1、 数据传输前需要发送同步域(SYNC),这个域固定为 0000 0001,通过NRZI编码后就是一串方波信号,接收者可以通过方波信号确定采样率(可以认为是串口的波特率)。
2、 因为数据中有大量的0,可以让接收者通过信号的变化不断调整采样频率,但是如果刚好数据中没有0怎么办?
一旦有大量的1存在于数据线上,那么数据线的电平将长时间不会发生变化,也就无法进行速率的同步,一旦接收者和发送者各自的时钟频率存在误差,那么很可能因为长时间没有电平变化而导致采样失败(误差长时间累积),所以 bit-stuffing 出现了,即所谓的强制插 0。USB规定,如果有7个连续的逻辑 1 ,需要在第 6 个 1 之后插入一个逻辑0来实现位填充,这样D 和D-就会发生变化,从而让接收者实现时钟同步。在接收时,只要将6个逻辑1后的0删除就可以恢复数据。