STM32 USB HID详解.doc_第1页
STM32 USB HID详解.doc_第2页
STM32 USB HID详解.doc_第3页
STM32 USB HID详解.doc_第4页
STM32 USB HID详解.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

STM32 USB HID详解1、USB简介2、USB描述符USB只是一个总线,只提供一个数据通路而已。USB总线驱动程序并不知道一个设备具体如何操作,有哪些行为。具体的一个设备实现什么功能,要由设备自己来决定。那么,USB主机是如何知道一个设备的功能以及行为呢?这就要通过描述符来实现了。描述符中记录了设备的类型、厂商ID和产品ID(通常依靠它们来加载对应的驱动程序)、端点情况、版本号等众多信息。标准的USB设备有5种USB描述符:设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符。下面详解:2.1、设备描述符一个USB设备只有一个设备描述符。设备描述符主要记录的信息有:设备所使用的USB协议版本号、设备类型、端点0的最大包大小、厂商ID(VID)和产品ID(PID)、设备版本号、厂商字符串索引、产品字符串索引、设备序列号索引、可能的配置数等。偏移量域大小/字节说明0bLength1该描述符的长度(0x12=18字节)1bDescriptorType1描述符类型(0x01设备描述符)2bcdUSB2本设备使用的USB协议版本4bDeviceClass1类代码5bDeviceSubClass1子类代码6bDeviceProtocol1协议码7bMaxPacketSize1端点0最大包长8idVendor2厂商ID10idProduct2产品ID12bcdDevice2设备版本号14iManufacturer1描述厂商的字符串索引15iProduct1描述产品的字符串索引16iSerialNumber1产品序列号的字符串索引17bNumConfigurations1可能的配置数2.2、配置描述符设备描述符里决定了该设备有多少种配置,每种配置都有一个配置描述符。配置描述符主要记录的信息有:配置所包含的接口数、配置的编号、供电方式、是否支持远程唤醒、电流需求量等。偏移量域大小/字节说明0bLength1该描述符的长度(0x09字节)1bDescriptorType1描述符类型(0x02配置描述符)2wTotalLength2配置、接口、端点和类描述符字节总和4bNumInterfaces1支持接口数5bConfigurationValue1本配置描述符标识6iConfiguration1配置描述符说明字符串索引7bmAttributes1电源及唤醒8MaxPower1设备耗电电流2.3、接口描述符在每个配置描述符中又定义了该配置有多少个接口,每个接口都有一个接口描述符。接口描述符主要记录的信息有:接口的编号、接口的端点数、接口所使用的类、子类、协议等。偏移量域大小/字节说明0bLength1该描述符的长度(0x09字节)1bDescriptorType1描述符类型(0x04接口描述符)2bInterfaceNumber1本接口描述符标识3bAlternateSetting14bNumEndpoints1接口端点数5bInterfaceClass1接口类代码6bInterfaceSubClass1启动类型1=BOOT, 0=No BOOT7bInterfaceProtocol10=None, 1=Keyboard, 2=Mouse8iInterface1接口描述符说明字符串索引2.4、类描述符该描述符不是必须的,如果配置的USB类型有类特殊描述符(如HID类),它跟在相应的接口描述符之后。2.5、端点描述符在接口描述符里又定义了该接口有多少个端点,每个端点都有一个端点描述符。端点描述符主要记录的信息有:端点号及方向、端点的传输类型、最大包长度、查询时间间隔等。偏移量域大小/字节说明0bLength1该描述符的长度(0x07字节)1bDescriptorType1描述符类型(0x5端点描述符)2bEndpointAddress1端点地址3bmAttributes1端点类型4wMaxPacketSize2端点发送接收最大包长6bInterval1中断端点轮训时间间隔2.6、字符串描述符字符串描述符主要是提供一些方便人们阅读的信息,它不是必需的。偏移量域大小/字节说明0bLength1该描述符的长度(0x04/0xXX字节),第一个字符串描述符0x041bDescriptorType1描述符类型(0x3字符串描述符)2wLANGID2/XX第一个字符串描述符时2字节,表示语言编码,其他自定义3、USB HID为了把一个设备识别为HID类别,设备在定义描述符的时候必须遵守HID规范。除了USB标准定义的一些描述符外,HID设备还必须定义HID描述符。另外设备和主机的通信是通过报告的形式来实现的,所以还必须定义报告描述符;而物理描述符不是必需的。还有就是HID描述符是关联于接口(而不是端点)的,所以设备不需要为每个端点都提供一个HID描述符。详情参看USB HID协议中文版_USB HID 设备3.1、HID描述符HID描述符是HID类特有的描述符,保证设备正确识别,遵循规定的格式。偏移量域大小/字节说明0bLength1该描述符的长度(0x09字节)1bDescriptorType1描述符类型(0x21 HID描述符)2bcdHID2HID规范版本4bCountryCode1国家代码5bNumDescriptors1支持的描述符个数6bDescriptorType1支持的描述符类别0x22报表7wItemLength2支持的描述符长度3.2、报告描述符报告描述符比较复杂,它是以item形式排列组合而成,无固定长度。为了准确描述来自一个控制管道的数据,一个报告描述符必须包括以下内容:偏移量域大小/字节说明0USAGE_PAGE22USAGE24COLLECTION26USAGE ID28LOGICAL_MINIMUM210LOGICAL_MAXIMUM313REPORT_SIZE215REPORT_COUNT217INPUT/OUTPUT2上述重复XXEND_COLLECTION3.3、物理描述符该描述符不是必须的。4、STM32 USB HID在STM32上实现USB HID的功能,首先芯片选择要选则带有USB接口的系列。正确搭建硬件环境,添加使用官方USB库。4.1、USB库简介详细正确内容请参看深入解析STM32_USB-FS-Device_Lib库V0.2以下仅个人整理。包含官方库文件,及自己封装的一些函数。1、hw_config其他工程摘的USB配置(IO、中断等)函数,也可自行实现在其他文件中。2、usb_core.c这个c文件是个庞大的文件,主要是定义了usb2.0的标注协议处理函数。3、usb_desc.c描述符相关4、usb_endp.c这个文件很简单,就是定义了结果几个端点输入输出函数。5、usb_init.c这个文件是主要是初始化。6、usb_int.c一看就知道跟中断相关。在该文件中定义了两个函数,分别为低优先级的端点正确传输中断服务程序CTR_LP()和高优先级端点正确传输的中断服务程序CTR_HP()。7、usb_io.c自己封装USB操作函数,初始化、发送数据等。8、usb_istr.c这个c文件,主要是注册一些端点响应函数,如上面的端点输入输出回电函数,还有就是ISTR中断状态状态寄存器的中断处理。9、usb_mem.c从文件名就能知道跟内存有关,这个文件主要定义了两个函数,一个读双缓冲区PMA的数据PMAToUserBufferCopy(),另一个是写数据到双缓冲区PMA,UserToPMABufferCopy。如果,当你的usb设备接收到了数据,当然数据存放在PMA中了,我们要读出数据就要用到PMAToUserBufferCopy()函数了,如果我们想要发送数据给usb主机,就要将你要发送的数据拷贝到PMA缓冲区中了,这样才能发送出去,原理跟串口类似。10、usb_prop.cusb_prop.c文件可以说是一个蛮重要的文件,因为USB的许多处理函数都在这里定义。在无论是在USB的建立阶段、数据阶段还是状态阶段的一些处理都在这个文件,USB标准函数请求的函数也在这个文件里。11、usb_pwr.c这个文件看文件名就知道跟功耗有关了,有很多的状态:上电、掉电、挂起、恢复。12、usb_regs.c13、usb_sil.c这个文件主要是简单接口层的初始化,和端点的读写操作函数。总共有3个函数:USB_SIL_Init();USB_SIL_Write();USB_SIL_Read()。14、platform_config.h其他工程摘的USB上拉IO定义。4.2、USB HID设备自定义在各种STM32学习板自带的演示例程中,都有几个USB的例程。如果我们想实现一个USB功能,可以拿里面的例子来改。那么具体要改哪些地方呢?首先要改各种描述符,然后是具体的数据处理。1、更改设备描述符描述符在文件usb_desc.c中。设备描述符的结构都标准的,长度也是固定的。更改如下:const uint8_t DeviceDescriptorSIZ_DEVICE_DESC = 0x12, /*bLength */ USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/ 0x00, /*bcdUSB */ 0x02, 0x00, /*bDeviceClass*/ 0x00, /*bDeviceSubClass*/ 0x00, /*bDeviceProtocol*/ 0x40, /*bMaxPacketSize40*/ 0x83, /*idVendor (0x0483)*/ 0x04, 0x50, /*idProduct = 0x5750*/ 0x57, 0x00, /*bcdDevice rel. 2.00*/ 0x02, 0x01, /*Index of string descriptor describing manufacturer */ 0x02, /*Index of string descriptor describing product*/ 0x03, /*Index of string descriptor describing the device serial number */ 0x01 /*bNumConfigurations*/;2、更改配置描述符集合配置描述符集合包括配置描述符、接口描述符、类特殊描述符(这里是HID描述符)、以及端点描述符。const uint8_t ConfigDescriptorSIZ_CONFIG_DESC =/*配置描述符*/ 0x09, /* bLength: Configuation Descriptor size */ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bConfigurationType */ CUSTOMHID_SIZ_CONFIG_DESC, /* wTotalLength: Bytes returned */ 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration */ 0xC0, /* bmAttributes: Bus powered */ 0x96, /* MaxPower 0x96*2=300 mA */ /*接口描述符*/ 0x09, /* bLength: Interface Descriptor size */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bInterfaceType */ 0x00, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints */ 0x03, /* bInterfaceClass: HID */ 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ 0x00, /* nInterfaceProtocol : 0=none */ 0, /* iInterface: Index of string descriptor */ /*HID描述符*/ 0x09, /* bLength: HID Descriptor size */ HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ 0x10, /* bcdHID: HID Class Spec release number */ 0x01, 0x00, /* bCountryCode: Hardware target country */ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ 0x22, /* bDescriptorType */ CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */ 0x00, /*端点描述符*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */ 0x82, /* bEndpointAddress: Endpoint Address (IN) */ / bit 3.0 : the endpoint number / bit 6.4 : reserved / bit 7 : 0(OUT), 1(IN) 0x03, /* bmAttributes: Interrupt endpoint */ 0x40, /* wMaxPacketSize: 64 Bytes max */ 0x00, 0x02, /* bInterval: Polling Interval (2 ms) */ 0x07, /* bLength: Endpoint Descriptor size */ USB_ENDPOINT_DESCRIPTOR_TYPE,/* bDescriptorType: */ 0x01,/* bEndpointAddress: */*Endpoint Address (OUT) */ 0x03,/* bmAttributes: Interrupt endpoint */ 0x40,/* wMaxPacketSize: 64 Bytes max */ 0x00, 0x02,/* bInterval: Polling Interval (2 ms) */ ;3、更改字符串描述符字符串描述符主要是设备的显示名称等。const uint8_t StringLangIDSIZ_STRING_LANGID = CUSTOMHID_SIZ_STRING_LANGID, USB_STRING_DESCRIPTOR_TYPE, 0x09, 0x04; /* LangID = 0x0409: U.S. English */const uint8_t StringVendorSIZ_STRING_VENDOR = CUSTOMHID_SIZ_STRING_VENDOR, /* Size of Vendor string */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType*/ M, 0, y, 0, U, 0,S, 0,B, 0, _, 0, H, 0,I,0,D,0;const uint8_t StringProductSIZ_STRING_PRODUCT = CUSTOMHID_SIZ_STRING_PRODUCT, /* bLength */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ C, 0, S, 0, C, 0, , 0, R, 0, e, 0,a,0,d,0,e,0,r,0, ,0;uint8_t StringSerialCUSTOMHID_SIZ_STRING_SERIAL = CUSTOMHID_SIZ_STRING_SERIAL, /* bLength */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ x, 0, x, 0, x, 0,x, 0,x, 0, x, 0, x, 0;4、更改报告描述符报告描述符比较复杂,这里就不详述了const uint8_t ReportDescriptorSIZ_REPORT_DESC = /0x05, 0x8c, /* USAGE_PAGE (ST Page) */ 0x09, 0x01, /* USAGE (Demo Kit) */ 0xa1, 0x01, /* COLLECTION (Application) */ / The Input report 0x09,0x03, / USAGE ID - Vendor defined 0x15,0x00, / LOGICAL_MINIMUM (0) 0x26,0x00, 0xFF, / LOGICAL_MAXIMUM (255) 0x75,0x08, / REPORT_SIZE (8bit) 0x95,0x40, / REPORT_COUNT (64Byte) 0x81,0x02, / INPUT (Data,Var,Abs) / The Output report 0x09,0x04, / USAGE ID - Vendor defined 0x15,0x00, / LOGICAL_MINIMUM (0) 0x26,0x00,0xFF, / LOGICAL_MAXIMUM (255) 0x75,0x08, / REPORT_SIZE (8bit) 0x95,0x40, / REPORT_COUNT (64Byte) 0x91,0x02, / OUTPUT (Data,Var,Abs) 0xc0 /* END_COLLECTION */ ;5、更改端口初始化对应描述符中的端口设置对端口初始化。在usb_prop.c文件中,找到void CustomHID_Reset (void)函数,该函数是负责初始化端点的。/* Initialize Endpoint 1 */SetEPType(ENDP1, EP_INTERRUPT);SetEPRxAddr(ENDP1, ENDP1_RXADDR);SetEPRxCount(ENDP1, REPORT_COUNT);SetEPRxStatus(ENDP1, EP_RX_VALID); /* Initialize Endpoint 2 */SetEPType(ENDP2, EP_INTERRUPT);SetEPTxAddr(ENDP2, ENDP2_TXADDR);SetEPTxCount(ENDP2, REPORT_COUNT);SetEPTxStatus(ENDP2, EP_TX_NAK);设置端点1接收,端点2发送。6、更改数据接收函数在usb_conf.h中找到#define EP1_OUT_Callback NOP_Process 一行,将它屏蔽。在usb_endp.c中增加void EP1_OUT_Callback(void)回调函数void EP1_OUT_Callback(void)u16 count

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论