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 中的以下數組.git

__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.修改github

#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函數便可。ui

8.接收數據this

接收數據相對發送要複雜一點。HAL庫已經封裝了底層的接收數據處理,因此用戶主要知道:當芯片完成一組數據接收的時候,中斷會調用CUSTOM_HID_OutEvent_FS這樣一個回調函數。那本文就在這個回調函數裏面設置了一個falg。以下:code

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了就表示中斷接收到一組數據,而後咱們就能夠讀數據了。本文讀數據函數以下:htm

/**
  * @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地址ip

-----------------本文做者「智御電子」,期待與電子愛好者交流學習。----------------

相關文章
相關標籤/搜索