用STM32讲解USB通信原理及应用

一、什么是USB

USB接口是我们日常生活中最常见到的一种接口了,在电脑,手机,键盘,鼠标上都会见到。现常用的是USB2.0USB3.0规格的。
USB接口全家桶
VCC(一般+5V)、GND、D+、D-。而D+、D-是两个数据线,学过模电的我们都知道差分电路的好处是可以抑制共模信号也就是抑制干扰,以保证信号传输的质量。而USB就是采用差分传输模式,所以D+D-也叫USB-DPUSB-DM
接入主机的设备又有分为低速全速高速,可用来控制功耗等,那么主机怎么去判断接入的是什么设备呢。

二、USB 接口的识别

主机端的USB接口的D+和D-都接有15K下拉电阻
全速USB设备的数据线D+接有1.5K的上拉电阻,一旦接入主机,主机的D+被拉高。
低速USB设备的数据线D-接有1.5K的上拉电阻,一旦接入主机,主机的D-会被拉高。
因此,主机就可以根据检测到自己的D+为高还是D-为高,从而判断接入的设备是一个全速
还是低速设备。
全速(Full Speed)和低速(Low Speed)很好区分。而高速设备初始是以一个全速设备的身份出现的,即和全速设备一样,D+线上有一个1.5k的上拉电阻。USB2.0的hub把它当作一个全速设备,之后,hub和设备通过一系列握手信号确认双方的身份。在这里对速度的检测是双向的,比如高速的hub需要检测所挂上来的设备是高速、全速还是低速,高速的设备需要检测所连上的hub是USB2.0的还是1.x的,如果是前者,就进行一系列动作切到高速模式工作,如果是后者,就以全速模式工作。(整个识别的过程有些复杂非本文重点,有兴趣可以自查资料不再赘述)
查看手上这块stm32f103c8t6最小系统板的电路原理图可以知道它将作为一个全速设备去连接主机。
电路原理图

三、USB设备类型定义


依附在总线上的设备可以是需要特定的驱动程序的完全定制的设备,也可能属于某个设备类别。这些类别定义设备的行为接口描述符,这样一个驱动程序可能用于所有此种类别的设备。一般操作系统都支持这些设备类别,为其提供通用驱动程序
上面是鼠标的一个设备分类,由上面表格可知鼠标属于HID设备,对应0x03h

上面是U盘的一个设备分类,由上面表格可知鼠标属于Mass Storage设备,对应0x08h
那么为什么要分设备类型呢?区分设备类型一个重要原因就是因为不同设备需要的数据传输模式不同。

USB支持四种基本的数据传输模式控制传输等时传输中断传输及数据块传输。每种传输模式应用到具有相同名字的终端,则具有不同的性质。
控制传输类型:
支持外设与主机之间的控制,状态,配置等信息的传输,为外设与主机之间提供一个控制通道。每种外设都支持控制传输类型,这样主机与外设之间就可以传送配置和命令/状态信息。
等时(lsochronous)传输类型(或称同步传输):
支持有周期性,有限的时延和带宽且数据传输速率不变的外设与主机间的数据传输。该类型无差错校验,故不能保证正确的数据传输,支持像计算机-电话集成系统(CTI)和音频系统与主机的数据传输。
中断传输类型
支持像游戏手柄,鼠标和键盘等输入设备,这些设备与主机间数据传输量小,无周期性,但对响应时间敏感,要求马上响应。
数据块(Bulk)传输类型:
支持打印机,扫描仪,数码相机等外设,这些外设与主机间传输的数据量大,USB在满足带宽的情况下才进行该类型的数据传输。
USB采用分块带宽分配方案,若外设超过当前带宽分配或潜在的要求,则不能进入该设备。同步和中断传输类型的终端保留带宽,并保证数据按一定的速率传送。集中和控制终端按可用的最佳带宽来传输传输数据。

四、描述符详解

USB是通过USB描述符来对USB设备进行属性的说明,包括使用的协议、接口数目、端点和传输方式等等。当USB设备插入主机后,主机要对其进行总线枚举,配置该设备所需的驱动等信息。主机通过标准请求Get Descriptor来读取USB的描述符,从而得到设备的相关信息,根据这些信息,然后建立通信。因此说,只有正确设置USB的描述符,才能使USB设备正常工作起来。

标准的USB设备有5种USB描述符:设备描述符配置描述符字符串描述符接口描述符端点描述符。下面详解:

1、设备描述符

一个设备只有一个设备描述符。

  typedef struct _USB_DEVICE_DESCRIPTOR_
  {
      BYTE       bLength,            描述符大小.固定为0x12.
      BYTE       bDescriptorType,    设备描述符类型固定为0x01.
      WORD       bcdUSB,             规范发布号.表示了本设备能适用于哪种协议,如2.0=0200,1.1=0110等.
      BYTE       bDeviceClass,       类型代码(由USB指定)
      BTYE       bDeviceSubClass,    子类型代码(由USB分配)
      BYTE       bDeviceProtol,      协议代码(由USB分配)
      BYTE       bMaxPacketSize0,    端点0最大分组大小
      WORD       idVenderI,          供应商ID(由USB分配)
      WORD       idProduct,          产品ID(由厂商分配)
      WORD       bcdDevice,          设备出产编码.
      BYTE       iManufacturer,      厂商描述符字符串索引
      BYTE       iProduct,           产品描述符字符串索引.
      BYTE       iSerialNumber,      设备序列号字符串索引
      BYTE       iNumConfiguations   可能的配置数.指配置字符串的个数
  }USB_DEVICE_DESCRIPTOR;

以下是摘取的STM32的鼠标(HID)设备里的实例代码里的一个设备描述符

2、配置描述符

配置描述符定义了设备的配置信息,一个设备可以有多个配置描述符

typedef struct _USB_CONFIGURATION_DESCRIPTOR_
{
   BYTE      bLength,              描述符大小.固定为0x09.
   BYTE      bDescriptorType,      配置描述符类型.固定为0x02.
   WORD      wTotalLength,         返回整个数据的长度.指此配置返回的配置描述符,接口描述符以及端点描述符的全部大小
   BYTE      bNumInterfaces,       配置所支持的接口数.指该配置配备的接口数量,也表示该配置下接口描述符数量.
   BYTE      bConfigurationValue,  作为Set Configuration的一个参数选择配置值.
   BYTE      iConfiguration,       用于描述该配置字符串描述符的索引.
   BYTE      bmAttributes,         供电模式选择.Bit4-0保留,D7:总线供电,D6:自供电,D5:远程唤醒.
   BYTE      MaxPower              总线供电的USB设备的最大消耗电流.以2mA为单位.
}USB_CONFIGURATION_DESCRIPTOR;

以下是摘取的STM32的鼠标(HID)设备里的实例代码里的一个配置描述符

3、接口描述符

一个配置支持至少一个接口。接口只要定义了实现功能的硬件的集合。每一个能够与USB实现数据交换的硬件叫做端点。也就是说接口是端点的集合。接口描述符说明了接口所提供的配置,一个配置所拥有的接口数量通过配置描述符的bNumInterfaces决定。

typedef struct _USB_INTERFACE_DESCRIPTOR_
{
    BYTE      bLength,               描述符大小.固定为0x09。
    BYTE      bDescriptorType,       接口描述符类型.固定为0x04 。
    BYTE      bInterfaceNumber,      该接口的编号。
    BYTE      bAlternateSetting,     用于为上一个字段选择可供替换的位置。即备用的接口描述符标号。
    BYTE      bNumEndpoint,          使用的端点数目.端点0除外。
    BYTE      bInterfaceClass,       类型代码(由USB分配)。
    BYTE      bInterfaceSubClass,    子类型代码(由USB分配)。
    BYTE      bInterfaceProtocol,    协议代码(由USB分配)。
    BYTE      iInterface             字符串描述符的索引。
}USB_INTERFACE_DESCRIPTOR;

以下是摘取的STM32的鼠标(HID)设备里的实例代码里的一个接口描述符

4、端点描述符

每一个能够与USB实现数据交换的硬件叫做端点。USB设备中的每个端点都有自己的端点描述符,由接口描述符中的bNumEndpoint决定其数量。

typedef struct _USB_ENDPOINT_DESCRIPTOR_
{
   BYTE        bLength,              描述符大小.固定为0x07.
   BYTE        bDescriptorType,      接口描述符类型.固定为0x05.
   BYTE        bEndpointAddress,     USB设备的端点地址.Bit7,方向,对于控制端点可以忽略,1/0:IN/OUT.Bit6-4,保留.BIt3-0:端点号。
   BYTE        bmAttributes,         端点属性.Bit7-2,保留.BIt1-0:00控制,01同步,02批量,03中断。
   WORD        wMaxPacketSize,       本端点接收或发送的最大信息包大小。
   BYTE        bInterval             轮训数据传送端点的时间间隔.对于批量传送和控制传送的端点忽略.对于同步传送的端点,必须为1,对于中断传送的端点,范围为1-255.
}USB_ENDPOINT_DESCRIPTOR

以下是摘取的STM32的鼠标(HID)设备里的实例代码里的一个端点描述符

5、字符串描述符

其中字符串描述符是可选的.如果不支持字符串描述符,其设备,配置,接口描述符内的所有字符串描述符索引都必须为

typedef struct _USB_STRING_DESCRIPTION_
{
    BYTE      bLength,              描述符大小.由整个字符串的长度加上bLength和bDescriptorType的长度决定。
    BYTE      bDescriptionType,     接口描述符类型.固定为0x03。
    BYTE      bString[1];           Unicode编码字符串.
}USB_STRING_DESCRIPTION;

以下是摘取的STM32的鼠标(HID)设备里的实例代码里的一个字符串描述符

物联沃分享整理
物联沃-IOTWORD物联网 » 用STM32讲解USB通信原理及应用

发表评论