STM32利用CUBEMX建立自定义HID工程,并且完成64字节的IN,OUT传输功能。

STM32 Customed HID开发流程

本文介绍的是STM32的cubeMX自定义HID的开发流程

  1. cubeMX配置customed HID模式。更多详细配置壳查看代码CubeMX的配置文件。

  2. 修改usbd_custome_hid_if.c 里面的CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] 数组。根据填入的数组内容修改宏USBD_CUSTOM_HID_REPORT_DESC_SIZE尺寸为34
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
  /* USER CODE BEGIN 0 */

//#ifdef usga
//0x05, 0x8c, /* USAGE_PAGE (ST Page) */
0x06, 0xFF, 0x00,      /* USAGE_PAGE (Vendor Page: 0xFF00) */
0x09, 0x01,            /* USAGE (Demo Kit)               */
0xa1, 0x01, /* COLLECTION (Application) */
/* 6 */ 

// The Input report
0x09,0x03, // USAGE ID - Vendor defined
0x15,0x00, // LOGICAL_MINIMUM (0)
0x26,0x00, 0xFF, // LOGICAL_MAXIMUM (255)
0x75,0x08, // REPORT_SIZE (8)
0x95,64, // REPORT_COUNT :SendLength
0x81,0x02, // INPUT (Data,Var,Abs)
//19
// The Output report
0x09,0x04, // USAGE ID - Vendor defined
0x15,0x00, // LOGICAL_MINIMUM (0)
0x26,0x00,0xFF, // LOGICAL_MAXIMUM (255)
0x75,0x08, // REPORT_SIZE (8)
0x95,64, // REPORT_COUNT:ReceiveLength
0x91,0x02, // OUTPUT (Data,Var,Abs)
//32
// The Feature report

/* 45 */
0xc0 /* END_COLLECTION */
//#endif 

  /* USER CODE END 0 */  /*     END_COLLECTION               */
};

3.修改usbd_customhid.c 中的如下数组.

__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
  0x09, /* bLength: Configuration Descriptor size */
  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
  USB_CUSTOM_HID_CONFIG_DESC_SIZ,
  /* 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_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
  0x00,         /*bInterfaceNumber: Number of Interface*/
  0x00,         /*bAlternateSetting: Alternate setting*/
  0x02,         /*bNumEndpoints*/
  0x03,         /*bInterfaceClass: CUSTOM_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 *************************/
  /* 18 */
  0x09,         /*bLength: CUSTOM_HID Descriptor size*/
  CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/
  0x11,         /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/
  0x01,
  0x00,         /*bCountryCode: Hardware target country*/
  0x01,         /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/
  0x22,         /*bDescriptorType*/
  USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
  0x00,
  /******************** Descriptor of Custom HID endpoints ********************/
  /* 27 */
  0x07,          /*bLength: Endpoint Descriptor size*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/

  CUSTOM_HID_EPIN_ADDR,     /*bEndpointAddress: Endpoint Address (IN)*/
  0x03,          /*bmAttributes: Interrupt endpoint*/
  CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */
  0x00,
  0x05,          /*bInterval: Polling Interval (5ms)*/ //这边修改的是IN通信的速率,数值越小,速率越快。最快1000hz。
  /* 34 */

  0x07,          /* bLength: Endpoint Descriptor size */
  USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: */
  CUSTOM_HID_EPOUT_ADDR,  /*bEndpointAddress: Endpoint Address (OUT)*/
  0x03, /* bmAttributes: Interrupt endpoint */
  CUSTOM_HID_EPOUT_SIZE,    /* wMaxPacketSize: 2 Bytes max  *///这边修改的是OUT通信的速率,数值越小,速率越快。最快1000hz。
  0x00,
  0x05, /* bInterval: Polling Interval (5 ms) */
  /* 41 */
} ;

/* USB CUSTOM_HID device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALIGN_END =
{
  /* 18 */
  0x09,         /*bLength: CUSTOM_HID Descriptor size*/
  CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/
  0x11,         /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/
  0x01,
  0x00,         /*bCountryCode: Hardware target country*/
  0x01,         /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/
  0x22,         /*bDescriptorType*/
  USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
  0x00,
};

5.修改

   #define CUSTOM_HID_EPIN_SIZE                 0x40
   #define CUSTOM_HID_EPOUT_SIZE                0x40
   #define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE     64
   #define USBD_CUSTOM_HID_REPORT_DESC_SIZE      34

6.这个时候全局编译,下载程序到控制板。接着将控制板USB查到PC电脑端,顺利的话会看到“设备管理器”里面的“人体输入学设备”识别到了“hid-compliant device”。

好!到此为止说明我们的USB HID枚举部分修改成功。下面进行发送和接收的操作。

7.发送数据

发送数据包是最简单的,只要调用USBD_CUSTOM_HID_SendReport函数即可。

8.接收数据

接收数据相对发送要复杂一点。HAL库已经封装了底层的接收数据处理,所以用户主要知道:当芯片完成一组数据接收的时候,中断会调用CUSTOM_HID_OutEvent_FS这样一个回调函数。那本文就在这个回调函数里面设置了一个falg。如下:

static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
{
  /* USER CODE BEGIN 6 */
    //flag设置成SET,代表有数据到来
    USB_Out_Flag=SET;
  return (USBD_OK);
  /* USER CODE END 6 */
}

而在main主循环函数中,我实时判断这个flag是否set了。如果set了就表示中断接收到一组数据,然后我们就可以读数据了。本文读数据函数如下:

/**
  * @brief  接收从USB获取的数据
  * @param  data 数据存储首地址
  * @param  dataNum 准备读取的数据字节数
  * @retval 读取的字节数
  */
uint32_t USB_GetData(uint8_t *data,uint32_t dataNum)
{
    uint32_t len=0;
    USBD_CUSTOM_HID_HandleTypeDef   *hhid;
  hhid = (USBD_CUSTOM_HID_HandleTypeDef*)hUsbDeviceFS.pClassData;//得到接收的地址

    for(len=0;len<dataNum;len++){
        *data=hhid->Report_buf[len];
        data++;
    }
    return dataNum;
}

9.到此,自定义HID基本讲解完毕,本文在main函数中实现一个USB_Mission应用。大体思路如下:判断有没有上位机发送过来的数据,如果有则解码数据,根据解析的数据回送上位机需要的数据。详情请查看代码。完整的代码GitHub地址

-----------------本文作者“智御电子”,期待与电子爱好者交流学习。----------------

原文地址:https://www.cnblogs.com/SC-Electronic/p/9246755.html

时间: 2024-10-12 21:04:55

STM32利用CUBEMX建立自定义HID工程,并且完成64字节的IN,OUT传输功能。的相关文章

利用STM32CubeMX来生成USB_HID_Mouse工程【添加ADC】(1)

现在原来的基础上添加ADC的功能. 现在(利用STM32CubeMX来生成USB_HID_Mouse工程)基础上新增硬件 JoyStick Shield 游戏摇杆扩展板 与STM32F103C8的连接 目前使用 JoyStick Shield   STM32F103C8 X----PA1(ADC1_IN1) Y----PA2(ADC1_IN2) 好了我们现在STM32CubeMX来打开之前的工程 现在我们先设置ADC1_IN1 让我们来看其adc的默认配置 现在直接生成工程. 会发现在原来的工程

如何利用 Visual Studio 自定义项目或工程模板(转载)

在开发项目的时候,由其是商业性质的大型项目时,往往需要在每个代码文件上都加上一段关于版权.开发人员的信息,并且名称空间上都需要带有公司的标志.这个时候,是选择在开发的时候手动添加还是自动生成呢? 我们其实完全可以利用 Visual Studio 提供的模板工具自定义一套专属的模板. 自定义项目模板 假如当我添加一个 .cs 文件后,我希望默认添加的文件要看起来像这个样子: 如何实现 1. 随意新建一个工程或使用一个已经存在的工程,在该项目内新添加一个普通的 class 文件,打开后应该和下图长得

如何利用 Visual Studio 自定义项目或工程模板

原文:如何利用 Visual Studio 自定义项目或工程模板 在开发项目的时候,由其是商业性质的大型项目时,往往需要在每个代码文件上都加上一段关于版权.开发人员的信息,并且名称空间上都需要带有公司的标志.这个时候,是选择在开发的时候手动添加还是自动生成呢? 我们其实完全可以利用 Visual Studio 提供的模板工具自定义一套专属的模板. 自定义项目模板 假如当我添加一个 .cs 文件后,我希望默认添加的文件要看起来像这个样子: 如何实现 1. 随意新建一个工程或使用一个已经存在的工程,

利用WPF建立自己的3d gis软件(非axhost方式)(十)SDK中一些自带的展示面板应用

原文:利用WPF建立自己的3d gis软件(非axhost方式)(十)SDK中一些自带的展示面板应用 先下载SDK:https://pan.baidu.com/s/1M9kBS6ouUwLfrt0zV0bPew密码:1te1 地图数据包(sqlserver2008R2版本,也可以不下载):??https://pan.baidu.com/s/1PjcNamad7OVpCrsVJ7dwFQ 密码:uw9r 下载 核心SDK升级包:https://pan.baidu.com/s/1Q3dlM-Va-R

利用WPF建立自己的3d gis软件(非axhost方式)(一)

原文:利用WPF建立自己的3d gis软件(非axhost方式)(一) 先下载SDK:https://pan.baidu.com/s/1M9kBS6ouUwLfrt0zV0bPew 密码:1te1 地图数据包(sqlserver2008R2版本,也可以不下载):? https://pan.baidu.com/s/1PjcNamad7OVpCrsVJ7dwFQ 密码:uw9r 完整的视频演示:http://v.youku.com/v_show/id_XMTU4MTI5NTE4NA==.html 下

利用开源软件搭建JAVA工程CI&CD自动化工具链

JAVA传统项目交付流程的问题 开发和运维间环境有明显差异 代码缺乏统一质量度量 客户要求上线时间紧,人工测试慢,导致测试不充分,时常做线上BUG修复 打造工具链 ● 源码管理Gitlab● 持续集成Jenkins● 代码扫描SonarQube● 接口测试PostMan+NewMan● 制品管理ArtifactoryOSS版本(仅支持Maven)● 自动部署Ansible GitLab安装 vim /etc/yum.repos.d/gitlab-ce.repo [gitlab-ce] name=

利用TortoiseSVN建立本地SVN库

Svn有很多常用功能,比如代码比较,回退,还原,归档等等,很多时候我们想使用到这些svn功能,但又不想大费周章建立服务端SVN库.其中,建立svn库主要有两种办法,一种就是装服务端版svn软件,另一种就是文章所讲的,利用TortoiseSVN建立本地SVN库. 前提是你已安装了TortoiseSVN这个客户端版本的svn工具,下载地址猛击这里 建立一个新的文件夹,这里命名为local_svn,然后,右键这个文件夹,选择TortoiseSVN菜单,选择 Create repositiory her

使用Eclipse建立一个JAVA工程和WEB工程

Eclipse 是一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境.Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK),这是进行Java开发的必不可少的Java开发环境. 启动Eclipse,第一次启动软件时,会提示选择工作空间(WorkSpace),可在硬盘上新建一个文件夹作为工作空间,这个文件夹将会保存你所编写的所有的源代码. 如何建立java工程参见 : htt

利用 Project Lombok 自定义 AST 转换

转自 http://www.ibm.com/developerworks/cn/java/j-lombok/ 利用 Project Lombok 自定义 AST 转换 何时以及如何为自定义代码生成扩展 Lombok Alex Ruiz 在本文中介绍了 Project Lombok,探讨了它的一些独特的编程特色,包括注释驱动代码生成,以及简洁.紧凑.可读的代码.然后,他会提示大家关注 Lombok 更有价值的用途:利用自定义 AST(Abstract Syntax Tree,抽象语法树)转换来对其