LV16-34-USB-01-USB基础
本文主要是STM32开发——USB 基础知识的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
Windows | windows11 |
Ubuntu | Ubuntu16.04的64位版本 |
VMware® Workstation 16 Pro | 16.2.3 build-19376536 |
SecureCRT | Version 8.7.2 (x64 build 2214) - 正式版-2020年5月14日 |
开发板 | 正点原子 i.MX6ULL Linux阿尔法开发板 |
uboot | NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03) |
linux内核 | linux-4.15(NXP官方提供) |
STM32开发板 | 正点原子战舰V3(STM32F103ZET6) |
点击查看本文参考资料
- 通用
分类 | 网址 | 说明 |
官方网站 | https://www.arm.com/ | ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档 |
https://www.st.com/content/st_com/zh.html | ST官方网站,在这里我们可以找到STM32的相关文档 | |
https://www.stmcu.com.cn/ | 意法半导体ST中文官方网站,在这里我们可以找到STM32的相关中文参考文档 | |
http://elm-chan.org/fsw/ff/00index_e.html | FatFs文件系统官网 | |
教程书籍 | 《ARM Cortex-M3权威指南》 | ARM公司专家Joseph Yiu(姚文祥)的力作,中文翻译是NXP的宋岩 |
《ARM Cortex-M0权威指南》 | ||
《ARM Cortex-M3与Cortex-M4权威指南》 | ||
开发论坛 | http://47.111.11.73/forum.php | 开源电子网,正点原子的资料下载及问题讨论论坛 |
https://www.firebbs.cn/forum.php | 国内Kinetis开发板-野火/秉火(刘火良)主持的论坛,现也做STM32和i.MX RT | |
https://www.amobbs.com/index.php | 阿莫(莫进明)主持的论坛,号称国内最早最火的电子论坛,以交流Atmel AVR系列单片机起家,现已拓展到嵌入式全平台,其STM32系列帖子有70W+。 | |
http://download.100ask.net/index.html | 韦东山嵌入式资料中心,有些STM32和linux的相关资料也可以来这里找。 | |
博客参考 | http://www.openedv.com/ | 开源网-原子哥个人博客 |
http://blog.chinaaet.com/jihceng0622 | 博主是原Freescale现NXP的现场应用工程师 | |
cortex-m-resources | 这其实并不算是一个博客,这是ARM公司专家Joseph Yiu收集整理的所有对开发者有用的官方Cortex-M资料链接(也包含极少数外部资源链接) |
点击查看相关文件下载
分类 | 网址 | 说明 |
STM32相关 | STM32F103xx英文数据手册 | STM32F103xC/D/E系列的英文数据手册 |
STM32F103xx中文数据手册 | STM32F103xC/D/E系列的中文数据手册 | |
STM32F10xxx英文参考手册(RM0008) | STM32F10xxx系列的英文参考手册 | |
STM32F10xxx中文参考手册(RM0008) | STM32F10xxx系列的中文参考手册 | |
Arm Cortex-M3 处理器技术参考手册-英文版 | Cortex-M3技术参考手册-英文版 | |
STM32F10xxx Cortex-M3编程手册-英文版(PM0056) | STM32F10xxx/20xxx/21xxx/L1xxxx系列Cortex-M3编程手册-英文版 | |
STM32 HAL库开发实战 | 野火STM32开发教程在线文档——基于F103系列开发板 | |
STM32库开发实战指南 | 野火STM32开发教程在线文档——基于野火霸道开发板 | |
SD卡相关 | SD卡相关资料——最新版本 | 有关SD卡的一些资料可以从这里下载 |
SD卡相关资料——历史版本 | 有关SD卡的一些历史版本资料可以从这里下载,比如后边看的SD卡2.0协议 | |
SD 2.0 协议标准完整版 | 这是一篇关于SD卡2.0协议的中文文档,还是比较有参考价值的,可以一看 | |
ESP32 | SD卡相关资料——最新版本 | 这个⼿册介绍了 ESP8266EX 的产品参数。 |
ESP8266 系列入门教程 | 一个入门手册(安信可官网) | |
ESP8266 AT 指令集 | 这是一篇关于ESSP8266的AT指令集的文档(安信可官网) | |
ESP8266 AT 指令使用实例 | 这是一篇关于ESSP8266的AT指令集使用实例的文档(安信可官网) | |
ESP-AT 用户指南 | 本指南详细介绍 ESP-AT 是什么、如何连接硬件、以及如何下载和烧录 AT 固件(乐鑫官网) | |
乐鑫官方技术文档 | 这里是乐鑫官方技术文档的入口,文档都可以来这里找(乐鑫官网) |
USB,即通用串行总线(Universal Serial Bus),包括 USB 协议和 USB 硬件两个方面,支持热插拔功能。现在日常生活的很多方面都离不开 USB 的应用,如充电和数据传输等场景。
USB 经过多次修改, 1996 年确定了初始规范版本 USB1.0,目前由非盈利组织 USBIF(Front Page | USB-IF)管理。 STM32 自带的 USB 符合USB2.0 规范,故 2.0 版本仍是学习的重点。
一、USB简介
USB 本身的知识体系非常复杂,这里就简单介绍一下,想更系统地学习 USB 的知识可以参考《圈圈教你玩 USB》、塞普拉斯提供的《USB101:通用串行总线 2.0 简介》等文献 。
1. USB 的硬件接口
USB 协议有漫长的发展历程,为的不同的场合和硬件功能而发展出不同的接口: Type-A、Type-B、 Type-C, Type-C 规范碰巧是跟着 USB3.1 的规范一起发布的。常见的接口类型列出如下图:

USB 发展到现在已经有 USB1.0/1.1/2.0/3.x/4 等多个版本。目前用的最多的就是版本USB1.1 和 USB2.0, USB3.x/USB4 目前也在加速推广。从图中可以发现不同的版本的 USB 接口内的引脚数量是有差异的。 USB3.0 以后为了提高速度,采用了更多数量的通讯线,比如同样的是 Type A 接口, USB2.0 版本内部只有四根线,采用半双工式广播式通讯, USB3.0 版本则将通讯线提高到了 9 根,并可以支持全双工非广播式的总线,允许两个单向数据管道分别处理一个单向通信。
USB2.0 常使用四根线: VCC(5V)、 GND、 D+(3.3V)和 D-(3.3V) (注:五线模式多了一个DI 脚用于支持 OTG 模式, OTG 为 USB 主机+USB 设备双重角色),其中数据线采用差分电压的方式进行数据传输。在 USB 主机上, D-和 D+都是接了 15K 的电阻到地的,所以在没有设备接入的时候, D+、 D-均是低电平。而在 USB 设备中,如果是高速设备,则会在 D+上接一个 1.5K的电阻到 3.3V,而如果是低速设备,则会在 D-上接一个 1.5K 的电阻到 3.3V。这样当设备接入主机的时候,主机就可以判断是否有设备接入,并能判断设备是高速设备还是低速设备。
关于 USB 硬件还有更多具体的细节规定,硬件设计时需要严格按照 USB 的器件的使用描述和 USB 标准所规定的参数来设计。
2. USB 速度
USB 规范已经为 USB 系统定义了以下四种速度模式:低速(Low-Speed)、全速(Full-Speed)、高速(Hi-Speed)和 超高速(SuperSpeedUSB)。接口的速度上限与设备支持的 USB 协议标准和导线长度、阻抗有关,不同协议版本对硬件的传输线数量、阻抗等要求各不相同,各个版本的能达到的理论速度上限对应如图:

USB 端口和连接器有时会标上颜色,以指示 USB 规格及其支持的功能。这些颜色不是 USB规范所要求的,并且在设备制造商之间不一致。例如,常见的支持 USB3.0 的 U 盘和电脑等设备使用蓝色指示,英特尔使用橙色指示充电端口等。
3. USB 系统
USB 系统主要包括三个部分:控制器(Host Controller)、集线器 (Hub) 和 USB 设备。
控制器(Host Controller),主机一般可以有一个或多个控制器,主要负责执行由控制器驱动程序发出的命令。控制器驱动程序(Host Controller Driver)在控制器与 USB 设备之间建立通信信道。
集线器(Hub)连接到 USB 主机的根集线器,可用于拓展主机可访问的 USB 设备的数量。
USB 设备(USB Device)则是我们常用的如 U 盘, USB 鼠标这类受主机控制的设备。
4. USB 通讯
USB 针对主机、集线器和设备制定了严格的协议。概括来讲,通过检测、令牌、传输控制、数据传输等多种方式,定义了主机和从机在系统中的不同职能。USB 系统通过“管道”进行通讯,有“控制管道”和“数据管道”两种, “控制管道”是双向的,而每个“数据管道”则是单向的,这种关系如图:

USB 通讯中的检测和断开总是由主机发起。 USB 主机与设备首次进行连接时会交换信息,这一过程叫“USB 枚举”。枚举是设备和主机间进行的信息交换过程,包含用于识别设备的信息。此外,枚举过程主机需要分配设备地址、读取描述符(作为提供有关设备信息的数据结构),并分配和加载设备驱动程序,而从机需要提供相应的描述符使主机知悉如何操作此设备。整个过程需要数秒时间。完成该过程后设备才可以向主机传输数据。数据传输也有规定的三种类型,分别是: IN/读取/上行数据传输、 OUT/写入/下行数据传输、控制数据传输。
USB 通过设备端点寻址,在主机和设备间实现信息交流。枚举发生前有一套专用的端点用于与设备进行通信。这些专用的端点统称为控制端点或端点 0,有端点 0 IN 和端点 0 OUT 两个不同的端点,但对开发者来说,它们的构建和运行方式是一样的。每一个 USB 设备都需要支持端点 0。因此,端点 0 不需要使用独立的描述符。除了端点 0 外,特定设备所支持的端点数量将由各自的设计要求决定。简单的设计(如鼠标)可能仅要一个 IN 端点。复杂的设计可能需要多个数据端点。
USB 规定的数据 4 种数据传输方式也是通过管道进行,分别是控制传输(Control Transfer)、中断传输(Interrupt Transfer)、批量传输或叫块传输(Bulk Transfer)、实时传输或叫同步传输(Isochronous Transfer ),每种模式规定了各自通讯时使用的管道类型。
关于 USB 还有很多更详细的时序和要求,像 USB 描述符、 VID/PID 的规定、 USB 类设备和调试等,因为 USB2.0 和之后的版本有差异,这里就不再详细描述了, ST 对 USB2.0 也有专门的培训资料,可以去官网查一查。
二、STM32F1的USB
1. 特性
STM32F1 系列芯片自带了 USB FS(FS,即全速, 12Mbps),支持从机(Slave/Device),但其 USB 与 CAN 不能同时使用,因为硬件共享同一个 SRAM。STM32F1 的 USB 外设实现了 USB2.0 的接口和 APB1 总线间的接口。它有以下特性:
- 符合 USB2.0 全速设备的技术规范
- 可配置 1 到 8 个 USB 端点
- CRC(循环冗余校验)生成/校验,反向不归零(NRZI)编码/解码和位填充
- 支持同步传输
- 支持批量/同步端点的双缓冲区机制
- 支持 USB 挂起/恢复操作
- 帧锁定时钟脉冲生成
2. USB设备框图
STM32F1 的 USB 外设使用标准的 48Mhz 时钟,允许每个端点有独立的缓冲区,每个端点最大为 512 字节缓冲,最大 16 个单向或 8 个双向端点。 USB 的传输格式由硬件完成,状态可以由寄存器标记,可以很大程度上简化我们的程序设计。USB模块启动时间tSTARTUP最大为1us,这个需要在编程时注意。下图引用了 STM32F1 的 USB 设备框图,方便我们理解 USB 这个外设。

三、USB协议栈
到这里我们已经对 USB 的硬件有了一定的了解,但由于 USB 协议的庞杂性,便得直接编写 USB 驱动的上手难度很大。故暂时我们可以从移植 ST 官方的 USB例程入手,学会使用 USB 驱动库。
ST 官方 Cube 库中提供的官方 USB 协议栈,主要是包含了 USBD 内核与 USB 各种类。USBD 内核一般是固定的,用户一般不需要修改,但 USBD 类,如果用户需要修改或者扩展,比如复合设备或者用户自定义设备,则需要用户自行修改。
USB 协议栈将所有 USB 类都抽象成一个数据结构: USBD_ClassTypeDef, USBD 内核与USBD 类之间的纽带就是 USBD_ClassType 这个结构体。这个结构体是一个抽象类,定义了一些虚拟函数,比如初始化,反初始化,类请求指令处理函数,端点 0 发送完成,端点 0 接收处理,数据发送完成,数据接收处理, SOF 中断处理,同步传输发送未完成,同步传输接收未完成处理等等;用户在实现自己具体的 USB 类的时候需要将它实例化, USBD_ClassTypeDef 结构体是 USBD 内核提供给外部定义一个 USB 设备类的窗口,而 USB 类文件实际就是实现这个结构体具体实例化的过程。最后将这个具体实例化的对象注册到 USBD 内核的同时, USBD 内核与 USBD 类也进行了关联。