目的:完成一个HID + MIDI的组合设备

准备工作:

·用CUBE生成HID工程;

·复制一份工程修改为MIDI工程;(参考之前博客已完成这两个工程)

·新建USB_User文件夹,将USB相关配置文件放到这里,并新建usbd_composite.c,usbd_composite.h文件;

·修改:

·分配端点号

#define HID_EPIN_ADDR                 0x81

#define HID_EPIN_SIZE                    0x40

#define HID_EPOUT_ADDR             0x01

#define HID_EPOUT_SIZE                0x40

#define MIDI_EPIN_ADDR                0x82

#define MIDI_EPOUT_ADDR            0x02

#define MIDI_EPIN_SIZE                   0x40

#define MIDI_EPOUT_SIZE               0x40

·添加usbd_composite.c,usbd_composite.h文件内容:

<<usbd_composite.c>>

#include "usbd_composite.h"
#include "usbd_hid_if.h"
#include "usbd_midi_if.h"

static USBD_HID_HandleTypeDef *pHIDData;
static USBD_MIDI_HandleTypeDef *pMIDIData;

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_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);

static uint8_t USBD_Composite_EP0_RxReady(USBD_HandleTypeDef *pdev);

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, /*EP0_RxReady*/
  USBD_Composite_DataIn,
  USBD_Composite_DataOut,
  NULL,
  NULL,
  NULL,
  USBD_Composite_GetFSCfgDesc,
  USBD_Composite_GetFSCfgDesc,
  USBD_Composite_GetFSCfgDesc,
  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 =
{
    /*Configuration Descriptor*/
    0x09,                        /* bLength: Configuration Descriptor size */
    USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
    USBD_COMPOSITE_DESC_SIZE,
    0x00,
    USBD_MAX_NUM_INTERFACES,   /* bNumInterfaces: 2 interface */
    0x01,   /* bConfigurationValue: Configuration value */
    0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
    0xC0,   /* bmAttributes: self powered */
    0x00,   /* MaxPower 0 mA */

/*--HID 1-------------------------------------------------------------------------*/

/* 9 */
    /*******************接口描述符*********************/
    //bLength字段。接口描述符的长度为9字节。
    0x09,
    //bDescriptorType字段。接口描述符的编号为0x04。
    0x04,
    //bInterfaceNumber字段。该接口的编号,第一个接口,编号为0。
    USB_INTERFACE_HID_INDEX,
    //bAlternateSetting字段。该接口的备用编号,为0。
    0x00,
    //bNumEndpoints字段。非0端点的数目。本实例需要二个
    //中断端点(一个输入一个输出),因此该值为2。
    0x02,
    //bInterfaceClass字段。该接口所使用的类。本实例是HID类,
    //HID类的编码为0x03。
    0x03,
    //bInterfaceSubClass字段。该接口所使用的子类。在HID1.1协议中,
    //只规定了一种子类:支持BIOS引导启动的子类。
    //USB键盘、鼠标属于该子类,子类代码为0x01。
    //但这里我们是自定义的HID设备,所以不使用子类。
    0x00,
    //bInterfaceProtocol字段。如果子类为支持引导启动的子类,
    //则协议可选择鼠标和键盘。键盘代码为0x01,鼠标代码为0x02。
    //自定义的HID设备,也不使用协议。
    0x00,
    //iConfiguration字段。该接口的字符串索引值。这里没有,为0。
    0x00,

/* 18 */
    /******************HID描述符************************/
    //bLength字段。本HID描述符下只有一个下级描述符。所以长度为9字节。
    0x09,
    //bDescriptorType字段。HID描述符的编号为0x21。
    0x21,
    //bcdHID字段。本协议使用的HID1.1协议。注意低字节在先。
    0x10,
    0x01,
    //bCountyCode字段。设备适用的国家代码,这里选择为美国,代码0x21。
    0x21,
    //bNumDescriptors字段。下级描述符的数目。我们只有一个报告描述符。
    0x01,
    //bDescritporType字段。下级描述符的类型,为报告描述符,编号为0x22。
    0x22,
    //bDescriptorLength字段。下级描述符的长度。下级描述符为报告描述符。
    USBD_HID_REPORT_DESC_SIZE,
    0,

/* 27 */
    /**********************输入端点描述符***********************/
    //bLength字段。端点描述符长度为7字节。
    0x07,
    //bDescriptorType字段。端点描述符编号为0x05。
    0x05,
    //bEndpointAddress字段。端点的地址。我们使用D12的输入端点1。
    //D7位表示数据方向,输入端点D7为1。所以输入端点1的地址为0x81。
    HID_EPIN_ADDR,//IN 1
    //bmAttributes字段。D1~D0为端点传输类型选择。
    //该端点为中断端点。中断端点的编号为3。其它位保留为0。
    0x03,
    //wMaxPacketSize字段。该端点的最大包长。端点1的最大包长为16字节。
    //注意低字节在先。
    HID_EPIN_SIZE,
    0x00,
    //bInterval字段。端点查询的时间,我们设置为10个帧时间,即1ms。
    0x01,

/* 34 */
    /**********************输出端点描述符***********************/
    //bLength字段。端点描述符长度为7字节。
    0x07,
    //bDescriptorType字段。端点描述符编号为0x05。
    0x05,
    //bEndpointAddress字段。端点的地址。我们使用D12的输出端点1。
    //D7位表示数据方向,输出端点D7为0。所以输出端点1的地址为0x01。
    HID_EPOUT_ADDR,
    //bmAttributes字段。D1~D0为端点传输类型选择。
    //该端点为中断端点。中断端点的编号为3。其它位保留为0。
    0x03,
    //wMaxPacketSize字段。该端点的最大包长。端点1的最大包长为16字节。
    //注意低字节在先。
    HID_EPOUT_SIZE,
    0x00,
    //bInterval字段。端点查询的时间,我们设置为10个帧时间,即1ms。
    0x01,

/* 41 */
#if 1
    /*--MIDI-------------------------------------------------------------------------*/
    /******************* Standard AC Interface Descriptor *********************/
    /* 00 */
    0x09,         /*bLength: Interface Descriptor size*/
    USB_DESC_TYPE_INTERFACE, /*bDescriptorType: Interface descriptor type*/
    USB_INTERFACE_MIDI_CONTRL_INDEX,         /*bInterfaceNumber: Number of Interface*/
    0x00,         /*bAlternateSetting: Alternate setting*/
    0x00,         /*bNumEndpoints*/
    0x01,         /*bInterfaceClass: Audio*/
    0x01,         /*bInterfaceSubClass : Audio Control*/
    0,            /*nInterfaceProtocol*/
    0,            /*iInterface: Index of string descriptor*/

/**************** Class-specific AC Interface Descriptor ******************/
    /* 9 */
    0x09,         /*bLength: Interface Descriptor size*/
    0x24,         /*bDescriptorType: Class-specific interface descriptor type*/
    0x01,         /*bDescriptorSubType: Header*/
    0x00,         /*bcdADC: Revision of class specification - 1.0*/
    0x01,
    0x09,         /*wTotalLength: Total size of class specific discriptor*/
    0x00,
    0x01,         /*bInCollection: Number of streaming interfaces*/
    USB_INTERFACE_MIDI_INDEX,         /*baInterfaceNr : MIDIStreaming interface 1 belongs to 
                                this AudioControl interface*/
                                
    /******************* Standard MS Interface Descriptor *********************/
    /* 18 */
    0x09,         /*bLength: Interface Descriptor size*/
    USB_DESC_TYPE_INTERFACE, /*bDescriptorType: Interface descriptor type*/
    USB_INTERFACE_MIDI_INDEX,         /*bInterfaceNumber: Number of Interface*/
    0x00,         /*bAlternateSetting: Alternate setting*/
    0x02,         /*bNumEndpoints*/
    0x01,         /*bInterfaceClass: Audio*/
    0x03,         /*bInterfaceSubClass : MIDI Streaming*/
    0,            /*nInterfaceProtocol*/
    0,            /*iInterface: Index of string descriptor*/
    /**************** Class-specific MS Interface Descriptor ******************/
    /* 27 */
    0x07,         /*bLength: Interface Descriptor size*/
    0x24,         /*bDescriptorType: Class-specific interface descriptor type*/
    0x01,         /*bDescriptorSubType: MS Header*/
    0x00,         /*bcdADC: Revision of class specification*/
    0x01,
    0x41,         /*wTotalLength: Total size of class specific discriptor*/
    0x00,
    /******************* MIDI IN Jack Descriptor (Embedded) *******************/
    /* 34 */
    0x06,         /*bLength: Size of this descriptor*/
    0x24,         /*bDescriptorType: Class-specific interface descriptor type*/
    0x02,         /*bDescriptorSubType: MIDI IN Jack*/
    0x01,         /*bJackType: Embedded*/
    0x01,         /*bJackID: ID of this Jack*/
    0x00,         /*iJack*/
    /******************* MIDI IN Jack Descriptor (External) *******************/
    /* 40 */
    0x06,         /*bLength: Size of this descriptor*/
    0x24,         /*bDescriptorType: Class-specific interface descriptor type*/
    0x02,         /*bDescriptorSubType: MIDI IN Jack*/
    0x02,         /*bJackType: External*/
    0x02,         /*bJackID: ID of this Jack*/
    0x00,         /*iJack*/
    /******************* MIDI OUT Jack Descriptor (Embedded) ******************/
    /* 46 */
    0x09,         /*bLength: Size of this descriptor*/
    0x24,         /*bDescriptorType: Class-specific interface descriptor type*/
    0x03,         /*bDescriptorSubType: MIDI OUT Jack*/
    0x01,         /*bJackType: Embedded*/
    0x03,         /*bJackID: ID of this Jack*/
    0x01,         /*bNrInputPins: Number of Input Pins of this Jack*/
    0x02,         /*BaSourceID: ID of the Entry to which this Pin is connected*/
    0x01,         /*BaSourceID: Output Pin number of the Entry to 
                            which this Input Pin is connected*/
    0x00,         /*iJack*/
    /******************* MIDI OUT Jack Descriptor (External) ******************/
    /* 55 */
    0x09,         /*bLength: Size of this descriptor*/
    0x24,         /*bDescriptorType: Class-specific interface descriptor type*/
    0x03,         /*bDescriptorSubType: MIDI OUT Jack*/
    0x02,         /*bJackType: External*/
    0x04,         /*bJackID: ID of this Jack*/
    0x01,         /*bNrInputPins: Number of Input Pins of this Jack*/
    0x02,         /*BaSourceID: ID of the Entry to which this Pin is connected*/
    0x01,         /*BaSourceID: Output Pin number of the Entry to 
                            which this Input Pin is connected*/
    0x00,         /*iJack*/
    /****************** Standard Bulk OUT Endpoint Descriptor *****************/
    /* 64 */
    0x09,         /*bLength: Size of this descriptor*/
    USB_DESC_TYPE_ENDPOINT, /*bDescriptorType: Endpoint descriptor type*/
    MIDI_EPOUT_ADDR,         /*bEndpointAddress: OUT Endpoint 1*/
    0x02,         /*bmAttributes: Bulk, not shared.*/
    0x40,         /*wMaxPacketSize 64*/
    0x00,
    0x00,         /*bInterval*/
    0x00,         /*bRefresh*/
    0x00,         /*bSynchAddress*/
    /************* Class-specific MS Bulk OUT Endpoint Descriptor *************/
    /* 73 */
    0x05,         /*bLength: Size of this descriptor*/
    0x25,         /*bDescriptorType: Class-specific endpoint descriptor type*/
    0x01,         /*bDescriptorSubType: MS General*/
    0x01,         /*bNumEmbMIDIJack: Number of embedded MIDI IN Jack*/
    0x01,         /*BaAssocJackID: ID of the Embedded MIDI IN Jack*/
    /****************** Standard Bulk IN Endpoint Descriptor *****************/
    /* 78 */
    0x09,         /*bLength: Size of this descriptor*/
    USB_DESC_TYPE_ENDPOINT, /*bDescriptorType: Endpoint descriptor type*/
    MIDI_EPIN_ADDR,         /*bEndpointAddress: IN Endpoint 1*/
    0x02,         /*bmAttributes: Bulk, not shared.*/
    0x40,         /*wMaxPacketSize 64*/
    0x00,
    0x00,         /*bInterval*/
    0x00,         /*bRefresh*/
    0x00,         /*bSynchAddress*/
    /************* Class-specific MS Bulk OUT Endpoint Descriptor *************/
    /* 87 */
    0x05,         /*bLength: Size of this descriptor*/
    0x25,         /*bDescriptorType: Class-specific endpoint descriptor type*/
    0x01,         /*bDescriptorSubType: MS General*/
    0x01,         /*bNumEmbMIDIJack: Number of embedded MIDI OUT Jack*/
    0x03,         /*BaAssocJackID: ID of the Embedded MIDI OUT Jack*/
    /* 92 */ 
#endif
};

/* USB Standard Device Descriptor */
__ALIGN_BEGIN  uint8_t USBD_Composite_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]  __ALIGN_END =
{
  USB_LEN_DEV_QUALIFIER_DESC,
  USB_DESC_TYPE_DEVICE_QUALIFIER,
  0x00,
  0x02,
  0x00,
  0x00,
  0x00,
  0x40,
  0x01,
  0x00,
};

/**
  * @brief  USBD_Composite_Init
  *         Initialize the Composite interface
  * @param  pdev: device instance
  * @param  cfgidx: Configuration index
  * @retval status
  */
static uint8_t  USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
  uint8_t res = 0;

pdev->pUserData =  &USBD_HID_fops_FS;
  res +=  USBD_HID.Init(pdev,cfgidx);
  pHIDData = pdev->pClassData;
    
  pdev->pUserData =  &USBD_MIDI_fops_FS;
  res +=  USBD_MIDI.Init(pdev,cfgidx);
  pMIDIData = pdev->pClassData;

return res;
}

/**
  * @brief  USBD_Composite_DeInit
  *         DeInitilaize  the Composite configuration
  * @param  pdev: device instance
  * @param  cfgidx: configuration index
  * @retval status
  */
static uint8_t  USBD_Composite_DeInit (USBD_HandleTypeDef *pdev,
                              uint8_t cfgidx)
{
    uint8_t res = 0;
    pdev->pUserData = &USBD_HID_fops_FS;
    pdev->pClassData = pHIDData;
    res +=  USBD_HID.DeInit(pdev,cfgidx);

pdev->pUserData = &USBD_MIDI_fops_FS;
    pdev->pClassData = pMIDIData;
    res +=  USBD_MIDI.DeInit(pdev,cfgidx);

return res;
}

/**
* @brief  USBD_Composite_Setup
*         Handle the Composite requests
* @param  pdev: device instance
* @param  req: USB request
* @retval status
*/
static uint8_t  USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
  switch (req->bmRequest & USB_REQ_RECIPIENT_MASK)
  {
   case USB_REQ_RECIPIENT_INTERFACE:
     switch(req->wIndex)
      {
         case USB_INTERFACE_HID_INDEX:
             pdev->pUserData =  &USBD_HID_fops_FS;
             pdev->pClassData = pHIDData;
          return(USBD_HID.Setup(pdev, req));

case USB_INTERFACE_MIDI_INDEX:
             pdev->pUserData =  &USBD_MIDI_fops_FS;
             pdev->pClassData = pMIDIData;
          return(USBD_MIDI.Setup(pdev, req));

default:
            break;
     }
     break;

case USB_REQ_RECIPIENT_ENDPOINT:
     switch(req->wIndex)
     {
        case HID_EPIN_ADDR:
        case HID_EPOUT_ADDR:
        pdev->pClassData = pHIDData;
         pdev->pUserData =  &USBD_HID_fops_FS;
        return(USBD_HID.Setup(pdev, req));

case MIDI_EPIN_ADDR:
        case MIDI_EPOUT_ADDR:
        pdev->pClassData = pMIDIData;
         pdev->pUserData =  &USBD_MIDI_fops_FS;
        return(USBD_MIDI.Setup(pdev, req));

default:
        break;
     }
     break;
  }
  return USBD_OK;
}

/**
  * @brief  USBD_HID_EP0_RxReady
  *         Handles control request data.
  * @param  pdev: device instance
  * @retval status
  */
uint8_t USBD_Composite_EP0_RxReady(USBD_HandleTypeDef *pdev)
{

return USBD_HID.EP0_RxReady(pdev);
}

/**
* @brief  USBD_Composite_DataIn
*         handle data IN Stage
* @param  pdev: device instance
* @param  epnum: endpoint index
* @retval status
*/
uint8_t  USBD_Composite_DataIn(USBD_HandleTypeDef *pdev,
                              uint8_t epnum)
{
  switch(epnum)
  {
    case HID_INDATA_NUM:
    pdev->pUserData =  &USBD_HID_fops_FS;
    pdev->pClassData = pHIDData;
    return(USBD_HID.DataIn(pdev,epnum));

case MIDI_INDATA_NUM:
    pdev->pUserData =  &USBD_MIDI_fops_FS;
    pdev->pClassData = pMIDIData;
    return(USBD_MIDI.DataIn(pdev,epnum));

default:
    break;

}
  return USBD_FAIL;
}

/**
* @brief  USBD_Composite_DataOut
*         handle data OUT Stage
* @param  pdev: device instance
* @param  epnum: endpoint index
* @retval status
*/
uint8_t  USBD_Composite_DataOut(USBD_HandleTypeDef *pdev,
                               uint8_t epnum)
{
  switch(epnum)
  {
    case HID_OUTDATA_NUM:
    pdev->pUserData =  &USBD_HID_fops_FS;
    pdev->pClassData = pHIDData;
    return(USBD_HID.DataOut(pdev,epnum));

case MIDI_OUTDATA_NUM:
    pdev->pUserData =  &USBD_MIDI_fops_FS;
    pdev->pClassData = pMIDIData;
    return(USBD_MIDI.DataOut(pdev,epnum));

default:
    break;
  }
  return USBD_FAIL;
}

/**
* @brief  USBD_Composite_GetHSCfgDesc
*         return configuration descriptor
* @param  length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t  *USBD_Composite_GetFSCfgDesc (uint16_t *length)
{
   *length = sizeof (USBD_Composite_CfgFSDesc);
   return USBD_Composite_CfgFSDesc;
}

/**
* @brief  DeviceQualifierDescriptor
*         return Device Qualifier descriptor
* @param  length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t  *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length)
{
  *length = sizeof (USBD_Composite_DeviceQualifierDesc);
  return USBD_Composite_DeviceQualifierDesc;
}

<<usbd_composite.h>>

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_COMPOSITE_H
#define __USBD_COMPOSITE_H

#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "usbd_hid.h"
#include "usbd_midi.h"
#include "usbd_desc.h"
#include "usbd_ctlreq.h"

#define WBVAL(x) (x & 0xFF),((x >> 8) & 0xFF)
#define DBVAL(x) (x & 0xFF),((x >> 8) & 0xFF),((x >> 16) & 0xFF),((x >> 24) & 0xFF)

#define USBD_COMPOSITE_DESC_SIZE            (41+92)

#define USB_INTERFACE_HID_INDEX               0
#define USB_INTERFACE_MIDI_CONTRL_INDEX       1
#define USB_INTERFACE_MIDI_INDEX            2

#define HID_INDATA_NUM                      (HID_EPIN_ADDR & 0x0F)
#define HID_OUTDATA_NUM                     (HID_EPOUT_ADDR & 0x0F)

#define MIDI_INDATA_NUM                     (MIDI_EPIN_ADDR & 0x0F)
#define MIDI_OUTDATA_NUM                    (MIDI_EPOUT_ADDR & 0x0F)

extern USBD_ClassTypeDef    USBD_COMPOSITE;

#ifdef __cplusplus
}
#endif

#endif

·修改usbd_device.c

void MX_USB_DEVICE_Init(void)

{

USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);

USBD_RegisterClass(&hUsbDeviceFS, &USBD_COMPOSITE);

//        USBD_HID_RegisterInterface(&hUsbDeviceFS, &USBD_HID_fops_FS);

USBD_Start(&hUsbDeviceFS);

}

·修改usbd_config.c

USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)

{

/* Init USB Ip. */

/* Link the driver to the stack. */

hpcd_USB_FS.pData = pdev;

pdev->pData = &hpcd_USB_FS;

hpcd_USB_FS.Instance = USB;

hpcd_USB_FS.Init.dev_endpoints = 8;

hpcd_USB_FS.Init.speed = PCD_SPEED_FULL;

hpcd_USB_FS.Init.ep0_mps = DEP0CTL_MPS_8;

hpcd_USB_FS.Init.low_power_enable = DISABLE;

hpcd_USB_FS.Init.lpm_enable = DISABLE;

hpcd_USB_FS.Init.battery_charging_enable = DISABLE;

if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK)

{

Error_Handler( );

}

HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);

HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);

HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , HID_EPIN_ADDR , PCD_SNG_BUF, 0x98);

HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , HID_EPOUT_ADDR , PCD_SNG_BUF, 0xD8);

HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , MIDI_EPIN_ADDR , PCD_SNG_BUF, 0x118);

HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , MIDI_EPOUT_ADDR , PCD_SNG_BUF, 0x158);

return USBD_OK;

}

·修改usbd_config.h

#define USBD_MAX_NUM_INTERFACES     3

·修改usbd_desc.c

#define USBD_PRODUCT_STRING_FS                             "STM32_HID+MIDI"

·修改main.c文件,

·烧录测试

识别到HID设备和MIDI设备了

MIDI数据收发OK

HID数据收发OK

参考资料:

使用STM32CubeMX编写USB复合设备        https://www.taterli.com/2355/

STM32 USB复合设备编写                   https://www.cnblogs.com/WeyneChen/p/6007049.html

STM32 USB组合设备HID+MIDI相关推荐

  1. STM32配置组合设备(HID+CDC)

    STM32组合设备 STM32配置组合设备(HID+CDC) 1. CDC基础工程,HID基础工程生成 2.USB工程熟悉 2.1 USB初始化 2.2USB中断 2.3 相关结构体 2.3.1 ` ...

  2. STM32CubeMX | 基于STM32使用HAL库实现USB组合设备之多路CDC

    STM32CubeMX | 基于STM32使用HAL库实现USB组合设备之多路CDC 本博客完整代码下载地址:https://download.csdn.net/download/qq15347150 ...

  3. STM32 USB VCOM和HID的区别,配置及Echo功能实现(HAL)

    STM32 USB VCOM和HID的区别,配置及Echo功能实现(HAL ) STM32的USB功能模块可以配置为虚拟串口(VCOM: Visual Port Com)或人机交互设备(HID: Hu ...

  4. USB Compound Device,USB复合设备 ; USB Composite Device,USB组合设备【转】

    本文转载自:https://blog.csdn.net/autumn20080101/article/details/52776863 科普下USB复合设备和USB组合设备的区别. 关键字 Commu ...

  5. USB组合设备——带鼠标功能的键盘

    文章目录 带鼠标功能的键盘 一个接口实现 报告描述符示例 键盘的报告 鼠标的报告 两个接口实现 配置描述符集合结构 配置描述符集合的实现 接口 1 字符串描述符(索引为 4) 接口 2 字符串描述符( ...

  6. linux usb组合设备,USB组合设备(5)

    最近做一个组合设备,说白了就是在一个usb 设备上面,实现2个或者更多功能,但是说实话中文的资料还是比较少,没找到多少比较靠谱的,就去外文网站翻翻了 还是不少的,下面我将自己的理解理清改一下,希望也可 ...

  7. 【STM32学习】 基于STM32 USB存储设备的w25qxx自动判断容量检测

    简介 使用STM32USB功能配置成Mass Storage Class 存储介质使用w25qxx做U盘时,发现一个比较好玩的事情. 当换不同容量的存储介质时需要改下程序,显示不同的大小. 更改usb ...

  8. linux usb组合设备,USB复合设备的实现

    USB复合设备一般用Interface Association Descriptor(IAD)实现,就是在要合并的接口前加上IAD描述符. IAD描述符: typedef struct _USBInt ...

  9. 首创STM32 USB主机驱动4G rndis设备

    1.4G模块使用技术现状与难题 4G模块支持的对外通信接口有串口和USB接口,串口一般使用AT指令的方式,这个在MCU类产品上面使用的很多,USB接口主用于在连接APU应用处理器上面,由LINUX操作 ...

最新文章

  1. VS.net2008正式版发布了
  2. Android Activity的launchMode四种启动模式备忘
  3. Spring Boot-Profile
  4. make的自动变量和预定义变量
  5. 今天来谈谈Python中的各种排序总结,含实现代码
  6. JAVA可阻塞队列-ArrayBlockingQueue
  7. 【基础数论】欧拉函数
  8. 视达配色教程2 好的配色的第一条件是什么
  9. zabbix mysql trapper_分分钟一键部署Zabbix Server
  10. fms +fme 视频直播
  11. 相见恨晚的 18 个 Linux 趣味命令,最后一个千万要尝试~
  12. 2019年广东当代优质民办学校获奖名单公布
  13. 如何关闭计算机自动关机设置方法,Win7电脑怎么取消自动关机?
  14. win7计算机图标缩在,win7桌面图标怎么变小?win7桌面图标变小解决方法
  15. 蜗牛星际改内存_二、FreeNAS篇:使用U盘在蜗牛星际上安装FreeNAS
  16. 第八章 性能优化 之 内存优化(一)
  17. 北斗校时系统(GPS授时设备)几种时间同步方法
  18. C# 矩阵库 功能特别强大!!
  19. Java设计模式之外观模式
  20. 求二叉树的叶子节点数目

热门文章

  1. 转载 总结了一下十几年来的经验教训
  2. Uboot启动logo修改
  3. Python--面向对象进阶
  4. CentOS7下安装jmeter5.3
  5. android 屏蔽实体按键,Android中屏蔽返回键,home键以及其他实体按键
  6. 在线教育投融数据(2015-2020年)
  7. 如何修改C盘下的用户名
  8. unity中脚本之间传递信息的方式
  9. Find-Sec-Bugs 漏洞范例
  10. Bash解析器常用快捷键