基于STM32的USB复合设备开发(1/3-USB2.0协议)
全文概述
很少写博客,可能字里行间也不规范吧。
摘要:本文由三个文章组成,其中1/3-USB2.0协议在参考各类文献的基础上,总结了USB2.0协议从硬件物理接口->应用层的基本情况;2/3-USB硬件总结了STM32H7为了实现USB传输所拥有的硬件特性和ST所提供的库函数的基本情况;3/3-设备开发总结了STM32的CDC、MSC和HID的单独开发过程,以及将其综合为复合设备的过程。
主控芯片:STM32H750VBT6。
硬件电路:如附录图所示。
开发目标:基于STM32H7芯片开发一款集成CDC虚拟串口、MSC大容量储存和HID键盘的USB全速复合设备。
文中常用缩写解释:
USB:Universal Serial Bus,通用串行总线。
CDC:Communication Device Class,通信设备类。
MSC: Mass Storage Device Class,大容量储存设备类。
HID:Human Interface Device,人机接口设备。
LS:Low Speed,低速。
FS:Full Speed,全速。
HS:High Speed,高速。
PID:Packet Identifier,包标识。
USB的电气连接与基本识别
USB的主要目的是方便PC主机连接外围设备 ,USB2.0规范1将USB设备分为了LS(Low Speed,低速),FS(Low Speed,低速)和HS(High Speed,高速)。其中LS设备主要用于鼠标、键盘等交互设备,FS设备主要用于音频和压缩视频,HS主要用于视频和存储设备。
- 主机:在任何USB系统中只有一个主机。主机计算机系统的USB接口称为主机控制器。主机控制器可以在硬件、固件或软件的组合中实现。根集线器集成在主机系统中,以提供一个或多个连接点。
- 设备:USB设备是以下设备之一:
- 集线器(Hubs),它为USB功能提供附加的连接点。
- 功能(Functions),为系统提供功能,如鼠标、U盘等。
USB虽然称为总线,但是和电子类中的RS-485、IIC等总线不一样,各个设备都是连接到集线器的连接点的,各个连接点之间并不是直接电气相连的,这点是USB的独特电气连接特性。USB总线拓扑如图1所示。
USB主机和设备通过四线电缆连接,其中包括一对电源线(VBUS、Ground)和一对差分信号线(D-、D+)。下图展示了USB连接点的外观和连接关系,其中,USB Type A用主机,USB Type B用于设备,此处展示的是USB Type B的Micro型号,常常也称为Micro USB。
在不考虑Hub通信的情况下,假设主机和设备是直接相连的,设备通过USB连接点的接口连接到主机控制器。主机开始识别该设备为HS、FS还是LS,区别LS和其它两种的方法是通过连接在D-和D+上的上拉电阻识别的,区别HS和FS的方法是通过协议。
在平常,USB主机的D-和D+分别由15k的下拉电阻保持为低电平,当检测到1.5k上拉电阻给D-提供的高电平时,主机认为一个低速设备连接,随后会开始对低速设备的 枚举过程;当检测到1.5k上拉电阻给D+提供的高电平时,主机认为一个全速或高速设备连接,随后会开始对全速设备的枚举过程。下图展示了高速设备的连接电路。
USB的通信格式
要实现主机和设备的通信,则需要满足USB特定的通信格式。通信格式包括了0/1定义(Signaling Levels)->域定义(Field)->包定义(Packet)->事务定义(Transaction)->传输定义(Transfer),逐次递增。为了形象说明USB的通信过程,以两个人对话过程举个“栗子”,虽然这个例子可能并不准确。这个对话中,主人叫USBH,访客叫USBD,D-和D+线是唯一的通信手段。对话内容使用红色标记
,其它内容只是思考。
USBD插入,进入总线枚举过程。
USBH:(心想:呦,端口(Port)有人来了!也不知道是不是好人,先只能允许他从VBUS上获取100mA的电流吧,默认你是0号地址)。
USBH:(心想:100ms过去了,这个人电流应该稳定了,可以对话了)
发送10ms的复位信号给新来的兄弟。
USBD:(心想:复位信号?那重置所有相关寄存器。)
USBH:(心想:新来的兄弟都是0号地址,这不行,后面还有人要来呢,我得先给他弄个新的地址。这个过程叫传输(transfer),这次传输的目的是设置地址(Set Address),由2个事务(transaction)组成)
·USBH:(事务1)发出设置(SETUP) 令牌(Token)!
USBD:(事务1)(心想:设置令,这是要干嘛?接收接下来的设置数据(DATA)内容看看)
USBH:(事务1)这是个标准请求,0号地址的兄弟,请将你的地址设置为5号!
USBD:(事务1)(心想:好,将地址改成5号)收到老板!
·USBH:(事务2)发出输入(IN) 令牌(Token)!
USBD:(事务2)(心想:这只是要看看我是不是真的改了地址了)发送0长度的数据给你
USBH:(心想:嗯,没有数据就对了,设置地址这事完了,该看看这兄弟是不是骨骼精奇,是不是练武奇才了,这个传输叫获得描述符(Get Descriptor),由多个事务组成)
·USBH:(事务1)发出设置(SETUP) 令牌(Token)&#x