来源:公众号【鱼鹰谈单片机】

作者:鱼鹰Osprey

ID   :emOsprey

昨天发了一通牢骚《不接广告行不行?不接广告你养我吗?》,感谢各位道友的支持与理解,不过牢骚归牢骚,还是需要继续更新的,不管外界如何,这个系列鱼鹰肯定要更新完的。

前两周,我们知道了为什么要学 USB,还有介绍了 USB 的整体情况:

《为什么说你要学习USB?(一)》

《USB 之概述》

今天,鱼鹰再介绍一下USB是如何通信的,即如何通过两根数据线完成通信呢(也就是上图中的最底层通信)?

USB通信格式

前面简单提到过,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 (Non-Return-to-Zero Inverted Code)编码(关于这个编码感兴趣的可以看次条文章)。

看下图进行理解:

USB不通信时,数据线处于闲置状态(类似于串口的高电平闲置),一旦需要开始通信,首先切换到K状态(类似串口的起始位),再进行实际的数据传输,在这里传输的数据为 000011,实际的数据线状态为差分101000,传输完毕后需要发送结束信号EOP:2位的 SE0,再加 1 位的J状态(类似串口的停止位)。

这里只是简单的说明,实际上的数据传输比这个还要复杂一些,但大体是一致的(上述可能会有误,毕竟鱼鹰没有使用示波器查看过,通过资料进行理解的)。

并且需要注意的是,上述描述的闲置状态和J、K等状态和设备类型有关,即全速设备和低速设备这些状态的定义不同(这个可能和设备数据线的上拉电阻位置相关)。

(来源于cypress  AN57294)

采用 NRZI 编码的好处是可以不需要时钟线进行同步,但是为了实现准确的采样,需要两个条件:

1、数据传输前需要发送同步域(SYNC),这个域固定为 0000 0001,通过NRZI编码后就是一串方波信号,接收者可以通过方波信号确定采样率(可以认为是串口的波特率)。

2、因为数据中有大量的0,可以让接收者通过信号的变化不断调整采样频率,但是如果刚好数据中没有0怎么办?

一旦有大量的1存在于数据线上,那么数据线的电平将长时间不会发生变化,也就无法进行速率的同步,一旦接收者和发送者各自的时钟频率存在误差,那么很可能因为长时间没有电平变化而导致采样失败(误差长时间累积),所以  bit-stuffing 出现了,即所谓的强制插 0。

USB规定,6个连续的逻辑 1 之后需要插入一个逻辑0来实现位填充,这样D+和D-就会发生变化,从而让接收者实现时钟同步。

在接收时,只要将6个逻辑1后的0删除就可以恢复数据。

(来源于cypress  AN57294)

可以看到,6个连续的1之后强制插入了一个0进去,这样即使接收方和发送方各自的时钟存在误差,也可以通过信号的变化实时同步,从而准确的进行采样。

以上内容就是 USB 为什么只需要两根线就能进行快速进行数据传输的关键。

USB 数据包

下面再来聊聊数据包:

前面这张图介绍了如何通过 USB 数据线传输000011 数据,事实上在 USB 中,所有的数据都是以包(Packet)的形式进行传输的,而数据包是有一定的格式,也就是说,为了传输00011,需要按照包的格式才能正确传输。

数据包有如下组成部分:

(来源于 ST 资料)

首先是 SOP(即从闲置状态到K状态),然后是 SYNC,即前面提到的同步域,用于接收方的时钟同步,其次才是我们需要传输的数据内容,最后是 EOP(2位 SE0,1位J状态)。

如此,你的数据(PacketContent)才能被接收方正确接收。

数据包分为四大类:

令牌 (Token) Packet

帧首 (Start of Frame) Packet

数据 (Data) Packet

握手 (Handshake) Packet

每一类又可能分为多种具体的数据包,比如令牌包分为OUT、IN、SETUP等数据包,

每一类中的 Packet Content 内容可能是不一样的,比如:

令牌 (Token) Packet

(灰色部分代表不存在)

帧首 (Start of Frame) Packet

(灰色部分代表不存在)

数据 (Data) Packet

(灰色部分代表不存在)

握手(Handshake) Packet

(灰色部分代表不存在)

为什么要缺斤少两呢?或许和数据包的功能有关,毕竟有些内容在有些包中是不需要存在的,那为什么还要加入传输增加总线的负担呢。

以上具体的内容可以查看鱼鹰提供的资料,比如 CRC 是怎么计算的,帧号里面的内容是怎样的?

对于软件开发而言,我们可以不必关心这么多,只要我们能正确的从相关寄存器中获取我们想要的数据即可,也就是我们需要知道当前令牌是什么,传输的数据是什么就可以了,其他的可以在学完整个 USB 后自行深入了解。

下一章节,鱼鹰将介绍 USB 的四大传输,即控制、中断、同步、批量传输,同时介绍四大传输和数据包的关系,半双工的通信是如何工作的。

敬请期待!

推荐阅读:

嵌入式系统优先级详解

KEIL 调试经验总结

线程CPU使用率到底该如何计算?

许久以后,你会感谢自己写的异常处理代码

终极串口接收方式,极致效率

延时功能进化论(合集)

如何写一个健壮且高效的串口接收程序?

打了多年的单片机调试断点到底应该怎么设置?| 颠覆认知

-THE END-


如果对你有帮助,记得转发分享哦

微信公众号「鱼鹰谈单片机」

每周一更单片机知识

长按后前往图中包含的公众号关注

USB 到底是如何通信的(三)?相关推荐

  1. Android10.0 Binder通信原理(三)-ServiceManager篇

    摘要:本节主要来讲解Android10.0 Binder中守护进程ServiceManager是如何启动.注册.获取服务 阅读本文大约需要花费35分钟. 文章首发微信公众号:IngresGe 专注于A ...

  2. 【新书速递】你想知道的通信“灵魂三问”都在这里……(福利再现)

    更多精彩内容请关注我们 来源丨知书通礼(ID:xintongzstl) 作者丨杨波 每次遇到刚入行又爱思考的年轻人,经常被问及有关通信的"灵魂三问". "通信是什么?&q ...

  3. 基于Linux的USB主/从设备之间的三种通信方式-转

    随着简单易用的接口日益流行,在中添加对USB接口的支持已成为大势所趋.本文通过介绍中支持USB的各种模块和库,分析了在Linux上利用USB实现高速串口和以太网连接等通信方式的具体方法. 通用串行总线 ...

  4. 一篇读懂:Android手机如何通过USB接口与外设通信(附原理分析及方案选型)

    更多技术干货,欢迎扫码关注博主微信公众号:HowieXue,共同探讨软件知识经验,关注就有海量学习资料免费领哦: 目录 0背景 1.手机USB接口通信特点 1.1 使用方便 1.2 通用性强 1.3 ...

  5. linux配置usb主从_基于Linux的USB主/从设备之间的三种通信方式

    随着简单易用的USB接口日益流行,在嵌入式系统中添加对USB接口的支持已成为大势所趋.本文通过介绍Linux中支持USB的各种模块和库,分析了在Linux上利用USB实现高速串口和以太网连接等通信方式 ...

  6. USB、USB转串口、串口通信的区别与实现

    Android如何监听USB插拔 全网独一无二的USB.USB转串口二合一通信SDK USB通信使用系统api,USB转串口通信使用第三方库usb-serial-for-android,串口通信使用G ...

  7. Android 通过USB与PLC设备通信(USB转串口)

    经朋友介绍接的一个外包,要求用USB和PLC设备通信,于是乎就有了本文.内容不深,权当做个记录整理一下当时的思路. 一.解决思路 1. 首先,PLC设备通常都是用串口进行通讯,走的Modbus协议.这 ...

  8. linux+Qt 下利用D-Bus进行进程间高效通信的三种方式

    linux+Qt 下利用D-Bus进行进程间高效通信的三种方式 原文链接: https://www.cnblogs.com/wwang/archive/2010/10/27/1862552.html ...

  9. HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)

    摘要:本节主要来讲解Android10.0 Native层的HIDL服务创建和Native层的Client验证 阅读本文大约需要花费18分钟. 文章首发微信公众号:IngresGe 专注于Androi ...

最新文章

  1. oracle增量备份如何恢复,【Oracle】增量备份和全库备份怎么恢复数据库
  2. 数据分析系列:绘制折线图(matplotlib)
  3. jqGrid的autoencode参数设置为true在客户端可能引发的编码问题
  4. yum 安装mysql 5.0_CentOS 通过 yum 安装 Mysql 5.0
  5. 20155229 2017-2018-1 《信息安全系统设计基础》课程总结
  6. iso硬盘安装 凤凰os_X86平台国产OS 对比评测 | 凤凰os安装教程_什么值得买
  7. 【Unity性能优化】ASTC压缩格式(Android)
  8. 缠中说禅:三个买点和三个卖点(修改版)
  9. conda 环境复制
  10. 怎样给证件照快速改底色?告诉大家一个简单方法
  11. 多目标优化算法:多目标黄金搜索优化算法MOGSO(提供MATLAB代码)
  12. 搭建Windows下Android应用开发环境——Eclipse/Android/ADT
  13. MAC 合并多个jpg文件为PDF
  14. 01-邂逅Vuejs
  15. 面向对象之关键字 this
  16. 简单介绍一下CAD做三维图的REVOLVE指令
  17. 5G毫米波有源阵列封装天线技术研究
  18. 等保二级和等保三级有哪些区别
  19. DELL G15 5511突然开不了机情况解决办法及求助
  20. 哔哩哔哩推荐策略分析与思考

热门文章

  1. 声学——声源定位阅读笔记
  2. 【机器学习】 随机森林(Random Forest)
  3. 以自己的电脑作为服务器,搭建网站,外网可访问
  4. 单精度浮点数(float)与双精度浮点数(double)的区别如下:
  5. python---打包exe文件运行自动化
  6. 将Python代码制作成exe程序
  7. 基于 HTML5 WebGL 的故宫人流量动态监控系统
  8. 信息量、信息熵、条件熵、KL散度、交叉熵
  9. KALI中Arping的使用方法(2023)
  10. 如何从github上下载源代码