STM32 自定义HID USB设备的实现

最近需要使用STM32开发一个设备通过HID协议与主机通信,于是开始学习USB,发现USB这个体系实在太庞大了,直接看USB的例程根本看不懂,完全找不到突破口,最后在网上找到一本不错的书《圈圈教你玩USB》,这本书能够很好地带你入门。枚举过程,请求,令牌,数据包,端点,描述符,这些知识都讲的很清楚,只有清楚了这些,再去看代码就能明白是怎么回事了。

接下来总结一个我个人的理解:对于HID设备,STM32有例程,但是怎么修改成符合自己要求的HID设备呢?首先,HID设备必需有报告描述符,报告描述符描述的是数据的长度以及用途,所以最重要的就是修改报告描述符,如我现在只是需要用来传数据,一次最大16字节长度;修改后的报告描述符如下:

const u8 CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
  {   
    //这是一个全局(bType为1)条目,将用途页选择为普通桌面Generic Desktop Page。

 //后面跟1字节数据(bSize为1),后面的字节数就不注释了,自己根据bSize来判断。

 0x05, 0x01, // USAGE_PAGE (Generic Desktop)

 

 //这是一个局部(bType为2)条目,用途选择为0x00。在普通桌面页中,

 //该用途是未定义的,如果使用该用途来开集合,那么系统将不会把它

 //当作标准系统设备,从而就成了一个用户自定义的HID设备。

 0x09, 0x00, // USAGE (0)

 

 //这是一个主条目(bType为0)条目,开集合,后面跟的数据0x01表示

 //该集合是一个应用集合。它的性质在前面由用途页和用途定义为

 //用户自定义。

 0xa1, 0x01, // COLLECTION (Application)

 

 //这是一个全局条目,说明逻辑值最小值为0。

 0x15, 0x00, //     LOGICAL_MINIMUM (0)

 

 //这是一个全局条目,说明逻辑值最大为255。

 0x25, 0xff, //     LOGICAL_MAXIMUM (255)

 

 //这是一个局部条目,说明用途的最小值为1。

 0x19, 0x01, //     USAGE_MINIMUM (1)

 

 //这是一个局部条目,说明用途的最大值8。

 0x29, 0x08, //     USAGE_MAXIMUM (8) 

 

 //这是一个全局条目,说明数据域的数量为16个。

 0x95, 0x10, //     REPORT_COUNT (16)

 

 //这是一个全局条目,说明每个数据域的长度为8bit,即1字节。

 0x75, 0x08, //     REPORT_SIZE (8)

 

 //这是一个主条目,说明有16个长度为8bit的数据域做为输入。

 0x81, 0x02, //     INPUT (Data,Var,Abs)

 

 //下面这个主条目用来关闭前面的集合。bSize为0,所以后面没数据。

 0xc0        // END_COLLECTION
  }; /* CustomHID_ReportDescriptor */

另外,别忘了去端点描述符修改数据长度

/* USB Configuration Descriptor */
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const u8 CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
  {
    0x09, /* bLength: Configuation Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    CUSTOMHID_SIZ_CONFIG_DESC,
    /* wTotalLength: Bytes returned */
    0x00,
    0x01,         /* bNumInterfaces: 1 interface */
    0x01,         /* bConfigurationValue: Configuration value */
    0x00,         /* iConfiguration: Index of string descriptor describing
                                 the configuration*/
    0xC0,         /* bmAttributes: Bus powered */
    0x32,         /* MaxPower 100 mA: this current is used for detecting Vbus */

    /************** Descriptor of Custom HID interface ****************/
    /* 09 */
    0x09,         /* bLength: Interface Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */
    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, 1=keyboard, 2=mouse */
    0,            /* iInterface: Index of string descriptor */
    /******************** Descriptor of Custom HID HID ********************/
    /* 18 */
    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,
    /******************** Descriptor of Custom HID endpoints ******************/
    /* 27 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */

    0x81,          /* bEndpointAddress: Endpoint Address (IN) */
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x10,          /* wMaxPacketSize: 16 Bytes max */
    0x00,
    0x20,          /* bInterval: Polling Interval (32 ms) */
    /* 34 */
    	
    0x07,	/* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,	/* bDescriptorType: */
			/*	Endpoint descriptor type */
    0x01,	/* bEndpointAddress: */
			/*	Endpoint Address (OUT) */
    0x03,	/* bmAttributes: Interrupt endpoint */
    0x10,	/* wMaxPacketSize: 16 Bytes max  */
    0x00,
    0x20,	/* bInterval: Polling Interval (20 ms) */
    /* 41 */
  }
  ; 

剩下的就根据自己需要去修改数据OUT处理和数据IN处理函数,来进行自己的数据处理,从而实现自定义HID。

 

当然使用HID进行数据传输并不是好的办法,USB有专门用于数据传输的协议,CDC,想要实现肯定是有办法的,但是因为我主机要求使用HID通信,我也只能使用HID来做了,什么CDC等要用到的时候再研究了。

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32自定义USB设备开发流程详解 自定义USB设备的开发需要对USB协议有一定的了解,同时需要熟练掌握STM32开发工具、相关硬件知识和USB协议栈。下面主要介绍STM32自定义USB设备开发的详细流程。 1. 硬件支持 开发过程中需要选择一种支持USBSTM32芯片,并与所需要的外设相匹配。常见的如STM32F1、STM32F4等系列。除了硬件芯片,还需要一些外设进行测试,比如USB口、示波器等。 2. USB协议栈 为了让STM32设备与PC之间进行通讯,需要在芯片上实现USB协议栈。开发者可以使用ST公司提供的USB协议栈,也可以选择其他第三方协议栈。 3. 开发工具 开发环境需要支持USB设备的开发,推荐使用Keil或者IAR作为开发工具,搭配相应的调试器完成代码的编写、烧写和运行。 4. 代码实现 在硬件准备就绪、协议栈选择完毕、开发环境搭建完成之后,开发者可以使用STM32提供的API函数库进行代码实现,完成USB设备的功能开发。 5. 测试和调试 完成开发后,开发者需要进行测试和调试。测试过程可以使用USB测试仪或者HID测试工具进行。调试需要通过仿真器和示波器等工具进行。 总结: STM32自定义USB设备开发需要掌握一定的USB协议知识,熟练掌握硬件相关知识和USB协议栈的选择和实现,使用Keil或者IAR等开发工具进行编写、调试和测试,并且需要注意保护设备的安全性,及时更新和修正程序进行升级。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值