STM32实现自定义HID复合设备

本文介绍如何使用STM32Cube_FW_F1_V1.6.0开发一个基于STM32F103XF的USB复合设备,实现HID功能。通过修改报告描述符和接口,无需报告ID区分,利用两个独立端点实现两个不同功能。步骤包括修改控制端点上拉电阻、增加串口调试、注册USB设备、定制desc以及添加USBD_COMPOSITE相关文件并进行配置。
摘要由CSDN通过智能技术生成

复合设备是啥,通俗讲就是一个USB物理设备可以实现多个功能,在主机端可以看到多个设备。通常实现HID复合设备有两种方式。第一种是使用同一个接口,修改报告描述符,增加一个功能集合,同时需要使用报告ID来区分哪一个设备,这样主机端和设备端需要增加报告ID处理,但只需要两个端点来实现功能,对于端口资源较少的MCU可以使用;第二种是使用两个接口,每个接口对应不同的报告描述符,不需要特意使用报告ID来区分,但不同接口使用独立的端点。
本文章使用不同接口来实现,基于stm32 cube例程开发。

  1. 开发准备
    使用官方STM32Cube_FW_F1_V1.6.0,使用STM32F103XF,因此使用
    STM32Cube_FW_F1_V1.6.0\Projects\STM3210E_EVAL\Applications\USB_Device\CustomHID_Standalone
    这个工程

  2. 移植代码
    2.1 修改控制控制USBDP上拉电阻引脚,(内部无法直接控制上下拉,因此增加此电路,否则主机不会枚举设备)
    DP控制电路
    2.2 增加串口1输出调试信息,main函数里添加:
    /* uart configuration */
    MX_USART1_UART_Init();
    添加如下代码实现printf功能

   PUTCHAR_PROTOTYPE
{

  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);

  return ch;
}

2.3 修改usb注册函数,main函数里修改如下代码

USBD_Init(&USBD_Device, &HID_Desc, 0);
/* Add Supported Class /
USBD_RegisterClass(&USBD_Device, &USBD_COMPOSITE);
/
Start Device Process */
USBD_Start(&USBD_Device);

2.4 修改desc
在usbd_desc.c,定义自己的desc
#define USBD_VID 0x0483
#define USBD_PID 0x5750
#define USBD_LANGID_STRING 0x409
#define USBD_MANUFACTURER_STRING “man”
#define USBD_PRODUCT_FS_STRING “HID in FS Mode”
#define USBD_CONFIGURATION_FS_STRING “HID Config”
#define USBD_INTERFACE_FS_STRING “HID Interface”
2.5 添加USBD_COMPOSITE
增加如下文件
usbd_composite.c,usbd_composite.h,usbd_customhid_if.c
usbd_customhid_if.h,usbd_keyboard.c,usbd_keyboard.h,usbd_keyboard_if.c,usbd_keyboard_if.h

usbd_composite.c具体内容如下,关键修改为USBD_Composite_CfgFSDesc。

/**
* @file        usbd_composite.c
* @author     
* @version    
* @date        
* @brief       KB + HID 复合设备
* @note
* @attention  
*/

#include "usbd_composite.h"
#include "usbd_customhid.h"
#include "usbd_customhid_if.h"
#include "usbd_keyboard.h"
#include "usbd_keyboard_hid_if.h"

static USBD_CUSTOM_HID_HandleTypeDef *pHIDData;
static USBD_CUSTOM_HID_HandleTypeDef *pKBData;


static uint8_t  USBD_Composite_Init (USBD_HandleTypeDef *pdev,
                                     uint8_t cfgidx);

static uint8_t  USBD_Composite_DeInit (USBD_HandleTypeDef *pdev,
                                       uint8_t cfgidx);

static uint8_t  USBD_Composite_EP0_RxReady(USBD_HandleTypeDef *pdev);

static uint8_t  USBD_Composite_Setup (USBD_HandleTypeDef *pdev,
                                      USBD_SetupReqTypedef *req);

static uint8_t  USBD_Composite_DataIn (USBD_HandleTypeDef *pdev,
                                       uint8_t epnum);

static uint8_t  USBD_Composite_DataOut (USBD_HandleTypeDef *pdev,
                                        uint8_t epnum);

static uint8_t  *USBD_Composite_GetFSCfgDesc (uint16_t *length);

static uint8_t  *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length);

USBD_ClassTypeDef  USBD_COMPOSITE =
{
  USBD_Composite_Init,
  USBD_Composite_DeInit,
  USBD_Composite_Setup,
  NULL, /*EP0_TxSent*/
  USBD_Composite_EP0_RxReady,
  USBD_Composite_DataIn,
  USBD_Composite_DataOut,
  NULL,
  NULL,
  NULL,
  NULL,
  USBD_Composite_GetFSCfgDesc,
  NULL,
  USBD_Composite_GetDeviceQualifierDescriptor,
};

/* USB composite device Configuration Descriptor */
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
__ALIGN_BEGIN uint8_t USBD_Composite_CfgFSDesc[USBD_COMPOSITE_DESC_SIZE]  __ALIGN_END =
{
  0x09, /* bLength: Configuration Descriptor size */
  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
  USBD_COMPOSITE_DESC_SIZE,
  /* wTotalLength: Bytes returned */
  0x00,
  0x02,         /*bNumInterfaces: 2 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*
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值