目录
前言
在嵌入式场景的具体体现
USB通信协议
总结
前言
在这之前,我们需要认识USB是什么东西,它是一种通信协议,协议只是规定数据的,在物理层面上,它可以有多种表现形式。在我们日常生活中也非常常见,包括电脑的USB接口Type-C接口,这都是USB的物理接口,具体参考以下文章,建议看完。
USB学习(1):USB基础之接口类型、协议标准、引脚分布、架构、时序和数据格式
这篇文件介绍的非常详细,在日常生活中我们常见的一些接口都是属于USB的接口,可能大部分人没有关注过并不知道,可以先把概念过一遍,至于时序我下面会讲解。
在嵌入式场景的具体体现
不管是在学习过程中用的开发板还是研发产品时用的开发板,在设计电源电路的时候,都是考虑用USB供电的,USB总线除了通信外,还可以进行供电,这是它的特性。
mrico usb,一种老式的接口,具体参考stm32f103c8t6最小系统板
type-c 这个接口我就不多说了 这是我自己画的开发板的电源电路
我们可以知道,我们整个系统的供电都来源于USB总线,而USB总线的引脚分布也没有你想象的那么复杂,接口不同引脚的分布和数量也不一样。
这里以USB2.0标准为例
我们通信最终用到的无非就是两根信号线 :D+ (数据正极或DP) D-(数据负极或DM)
所以在信号引脚上是比较简洁的,但是它的速度可不慢,根据标准,USB可以分为低速(LS)、全速(FS)、高速设备(HS)。
低速(1.5Mbps)
全速(12Mbps)
高速(480Mbps)。
上述文章中提到了USB的时序,它采用的是反向不归0编码(可以了解一下),而且D+和D-这对信号线是属于差分信号线,差分信号的特点就是抗干扰能力强,所以通信稳定。看到这里,可能有人的会迫不及待的分析时序了,但是其实没必要,因为这种东西你不可能用IO去模拟的,没有意义,而且编码的完成是完全由硬件完成,比如你告诉硬件你要发送字节0xAE,然后硬件它自己编码,然后去跳动这两根线。
所以我们只要知道就好了,这两根线的编码和我们之前的UART,SPI,I2C这种类型传输本质一样,按位传输(固定低位先发),但是差分信号是根据两根线来编码
逻辑1:D+ 为高电平 D-为低电平
逻辑0:D+ 为低电平 D-为高电平
空闲或未连接:D+ 和 D-电平相同
我们知道了差分信号,是根据D+ D- 这两根信号的电压差来检测编码的,当受到干扰时,两根线的跳变方向是一致的,所以不会对数据有影响。
讲到这里,我们可以发现,USB传输好像没有时钟线,那它是怎么同步速度的?很简单,因为USB的通信本质是 异步串行半双工。在总线上可以挂载多个设备,但是同一时间主机只能和一个设备通信,而且方向只能是单向的,要么主机到设备,要么设备到主机。至于速度的同步,很简单,就是发送脉冲信号,收到之后计算速度,原理和串口类似,大家约定好速度,收到开始的信号就开始计算,以达到同步。
到这里,我们就从物理层建立上了通信,但是这个通信并不是USB通信协议,只是说简单由(NRZI)编码根据差分信号线传输的通信。
USB通信协议
通信协议的本质是抽象的规定,它并非实体,它只是一个规定,规定你的数据要以什么表现形式才能在它的规定中算有效数据或特定数据,否则它就不认或直接算你错误,USB通信协议也是如此,如果你想和一个有通信协议的设备通信,那么你就必须按它的协议来。
如果你控制硬件发送了一些不属于USB协议的数据,通过USB接口发送到了主机电脑,电脑有可能会死机或者蓝屏(PS:我们部门的老师傅告诉我的),所以一般从0实现USB通信的要么有一台特定电脑以及USB分析仪(这个很贵)。但是我们是在硬件USB外设的基础上,所以你想控制它发出不属于USB协议的数据是不可能的,因为它是被设计好的,除非你拿D+ D-去IO控制,可能会有上述异常。
在USB协议中,我们需要为我们的数据证明,它是USB协议的数据,所为我们需要发送特定的数据来声明 (我的数据是合法合规的)
以下这段为转载文章开头挂载的链接文章中 USB数据格式的介绍
我们可以知道,它的数据格式是以数据包形式进行的,数据包有不同的类型
令牌数据包
数据数据包
握手数据包
起始帧数据包
而数据包又有不同的字段,具体的字段根据类型又不一样。不同的字段由不同的数据组成。
SYNC:同步字段,用于同步数据的信号,每个包的头必须是这个字段
EOP: 结束字段,用于表示一个包的结束,每个包的结束必须是这个字段
还有一系列字段等等,具体看上述图片中的文章,大概过一遍。
接下来我们看一个令牌数据包(setup)实际波形。信号的时间轴从左往右流逝。
我们看 PID字段 8位
在USB规范中,PID值是低位 ,补码是高位,所以setup的值为 10110100 (左为低位)
看信号分析值 左到右也是 10110100 ,由于在传输中是反正不归零编码,1为上一个电平,0是翻转电平,所以在电压上表现为 低高高高低低高低,逻辑值为(01110010)(左为低位)
逻辑值为(01110010)
D+: 低高高高低低高低
D-:高低低低高高低高
所以到这里就非常清晰了,因为上述文章中的博主在说字段值的时候,没有说明是左为低位高位,而且我这里是以实际信号和官方规范为准,这样就说的通了。
基本解析到这就应该很清楚,我们学习的时候过一遍时序就可以了,我上面拿一个字段来练习,因为这些东西硬件都会帮我们完成,我们根本不用操心,只需要知道什么时候发令牌包,什么时候发什么包就可以了,比如在一次传输中 一般先发令牌数据包 在发数据数据包若干个,最后发握手数据包,只有数据数据包的数据才是真正意义上的数据。
总结
USB通信协议本质上就是在搭建好的通信物理层上,一层又一层的规定,根据应用特性扩展的复杂规定,其复杂程序已经出过不少书籍。但是对我们而言,很多东西有规律可循,而且我们也不需要关心这么多。
在USB协议中一层又一层数据包中包含的数据数据包,就是真正意义上发送的数据,但是当主机解开USB协议(正确找到接收到数据数据包中的数据字段)拿到真正的数据后,它怎么知道这个数据是拿来干嘛的?它怎么知道这个数据该怎么用,所以又引出了子协议的概念,也就是设备类的概念。这个我们在下一章再说。