STM32 自定义HID USB设备的实现

发布者:BlossomWhisper最新更新时间:2019-03-24 来源: eefocus关键字: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等要用到的时候再研究了。


关键字:STM32  自定义HID  USB设备 引用地址:STM32 自定义HID USB设备的实现

上一篇:STM32F103C8T6驱动ov2640拍照串口传输到上位机
下一篇:STM32高级教程之USB HID双向数据传输

推荐阅读最新更新时间:2024-03-16 16:26

STM32状态监测功能包可简化机器学习过程
意法半导体发布一款免费的STM32软件功能包,让用户可以用微控制器探索套件快速创建、训练、部署工业状态监测智能边缘设备。 FP-AI-NANOEDG1软件包由意法半导体与机器学习专业开发科技公司、ST授权合作伙伴Cartesiam共同开发,包含捕获传感器数据,集成和运行Cartesiam的NanoEdge库所需的全部驱动程序、中间件、文档和代码示例。即使用户没有专业的AI技能,也能在Windows®10或Ubuntu PC机上,用Cartesiam NanoEdge™AI Studio工具快速创建并导出自定义机器学习库。功能包可简化在STM32开发板上的原型开发和确认测试过程,而且是免费使用,当客户在硬件上部署软件包时,
[单片机]
<font color='red'>STM32</font>状态监测功能包可简化机器学习过程
STM32实现CDC虚拟串口
1.CUBEMX配置 2.安装驱动 自己百度一下,CSDN传不上来 或者加群 3.生成工程 接收到数据,数据会传到接收缓存区 发送: 接收:
[单片机]
<font color='red'>STM32</font>实现CDC虚拟串口
stm32的KEY控制LED
stm32的学习就是弄懂是怎么进行软件配置,先明白硬件连接,再结合起来; #include stm32f4xx.h #include led.h #define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) // 这里读取IO的状态,将stm32的IO口作为输入使用 #define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) #define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) #define LED0 PFout(9) //D
[单片机]
STM32 ST-LINK Utility介绍、下载、安装、使用方法
Ⅰ、写在前面 本文讲述的内容是STM32 ST-LINK Utility介绍、下载、安装、使用方法,如需要了解更多关于STM32相关的文章,可以到我博客,或微信公众号查看并下载。 STM32 ST-LINK Utility这个软件工具其实主要就是配套“ST-LINK”这个下载工具一起使用的上位机软件。因此使用STM32 ST-LINK Utility上位机软件需要有一个ST-LINK工具才行。它的功能和J-Link对应的工具类似,用于烧写代码。 STM32 ST-LINK Utility工具在产品开发过程中测试一些其他版本的代码,可以直接下载hex,而不用打开工程再编译去下载。 当你开发完一个STM32产品,需要量产的
[单片机]
<font color='red'>STM32</font> ST-LINK Utility介绍、下载、安装、使用方法
STM32 独立看门狗IWDG 与窗口看门狗WWDG
独立看门狗Iwdg 有独立时钟(内部低速时钟LSI---40KHz),所以不受系统硬件影响的系统故障探测器。主要用于监视硬件错误。 窗口看门狗wwdg 时钟与系统相同。如果系统时钟不走了,这个狗也就失去作用了,主要用于监视软件错误。 一,独立看门狗 看门狗定时时限= IWDG_SetReload()的值 / 看门狗时钟频率 看门狗时钟频率=LSI(内部低速时钟)的频率(40KHz)/ 分频数 1.STM32 独立看门狗IWDG的时限定为280微秒。这个时限可能会随着LSI(内部低速时钟)的频率漂移而产生微小的变化。 /* IWDG timeout equal to 280 ms (the timeout may varies
[单片机]
STM32串口1重映射到PB6、PB7
void uart_init(u32 bound) { //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
[单片机]
STM32学习笔记--NVIC中断
朋友们,如果你需要在STM32上移植RTOS,那么首先必须深入理解它的中断系统。什么是NVIC?即嵌套向量中断控制器(Nested Vectored Interrupt Controller)。STM32的中有一个强大而方便的NVIC,它是属于Cortex内核的器件,不可屏蔽中断 (NMI)和外部中断都由它来处理,而SYSTICK不是由 NVIC来控制的。   特性: ● 60个可屏蔽中断通道(不包含16个Cortex™-M3的中断线); ● 16个可编程的优先等级(使用了4位中断优先级); ● 低延迟的异常和中断处理; ● 电源管理控制; ● 系统控制寄存器的实现; 1.中断优先级分组   STM32(Cortex-M3)中
[单片机]
STM32常见的串行通信接口
通信接口背景知识 设备之间通信的方式 一般情况下,设备之间的通信方式可以分成并行通信和串行通信两种。并行与串行通信的区别如下表所示。 串行通信的分类 1、按照数据传送方向,分为: 单工:数据传输只支持数据在一个方向上传输; 半双工:允许数据在两个方向上传输。但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;它不需要独立的接收端和发送端,两者可以合并一起使用一个端口。 全双工:允许数据同时在两个方向上传输。因此,全双工通信是两个单工通信方式的结合,需要独立的接收端和发送端。 2、按照通信方式,分为: 同步通信:带时钟同步信号传输。比如:SPI,IIC通信接口。 异步通信:不带时钟同步信号。比
[单片机]
<font color='red'>STM32</font>常见的串行通信接口
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved