STM32 HAL庫學習(六)USB識別成Custom HID通信

一、STM32F070 USB基礎知識瞭解:

STM32F070 USB採用USB 2.0規範,時鐘頻率爲48MHZ,有一個專用的USB數據存儲區,大小爲1024字節;支持16個單向傳輸端點、8個雙向傳輸端點

USB外設模塊構成圖:

USB物理接口模塊:

USB_DM、USB_DP —— 數據正、負信號

Analog Transceiver —— 模擬收發器

Embedded pull-up resister —— 可控嵌入負載電阻

Battery Charging Detection(BCD) —— 電池充電檢測

USB_NOE —— 允許輸出信號,可用於驅動LED或提供通信信息

Serial Interface Engine(SIE)串行接口引擎:

這個模塊主要用於同步模式識別、CRC/PID的生成和檢驗、SOF/reset信號的生成、產生中斷信號等

Timer定時器模塊:

生成起始幀的鎖定時鐘脈衝以及檢測阻塞

USB連接到到APB總線的APB接口模塊構成有:Packet Memory、Arbiter(仲裁器,解決衝突訪問APB的問題)、Register Mapper(寄存器映射器)、APB封裝器(將USB外設映射到APB的地址空間)、中斷映射

 

二、STM32Cube USB中間件文件瞭解:

在STM32CubeMX中選擇USB中間件,點擊生成代碼就會自動加載USB的庫文件,查看STM32_USB_Device_Library文件夾可見,USB庫文件分爲兩類:一類是Class即設備類文件;一類是Core即內核文件。內核文件和設備類文件分別如下兩圖所示:

usbd_core.c /h —— 處理USB通信和狀態機的函數

usbd_ctlreq.c/h —— 處理USB事務結果

usbd_conf_template.c/h —— 底層接口文件的模板文件,用戶對其進行修改包含在應用文件中

usbd_ioreq.c/h —— 包含了USB規範列出的請求實現

 

三、使用STM32Cube MX配置USB

配置RCC時鐘,激活HSE時鐘源,作爲USB時鐘的輸入,選擇USB類爲HID設備類

 

Configuration頁面進行USB的相關設置、描述符設置,這裏配置USB爲用戶自定義的HID設備,生成的MDK代碼文件如下所示,建議先用工具生成報告描述符再根據它的長度進行配置

 

 

 

 分析描述符

首先是USB設備標準描述符,Cube MX 已經根據配置自動生成了

__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
  0x12,                       /*bLength */
  USB_DESC_TYPE_DEVICE,       /*bDescriptorType*/
  0x00,                       /*bcdUSB */
  0x02,
  0x00,                       /*bDeviceClass*/
  0x00,                       /*bDeviceSubClass*/
  0x00,                       /*bDeviceProtocol*/
  USB_MAX_EP0_SIZE,           /*bMaxPacketSize*/
  LOBYTE(USBD_VID),           /*idVendor*/
  HIBYTE(USBD_VID),           /*idVendor*/
  LOBYTE(USBD_PID_FS),        /*idProduct*/
  HIBYTE(USBD_PID_FS),        /*idProduct*/
  0x00,                       /*bcdDevice rel. 2.00*/
  0x02,
  USBD_IDX_MFC_STR,           /*Index of manufacturer  string*/
  USBD_IDX_PRODUCT_STR,       /*Index of product string*/
  USBD_IDX_SERIAL_STR,        /*Index of serial number string*/
  USBD_MAX_NUM_CONFIGURATION  /*bNumConfigurations*/
};

接下來是修改HID報告描述符,STM32HAL爲用戶提供了一個USB設備HID接口類的文件,即usbd_custom_hid_if.c/h,以便用戶自行配置HID報告描述符,要修改的數組是CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE],建議使用 HID descriptor tool工具生成報告符。這裏要注意的是報告描述符大小USBD_CUSTOM_HID_REPORT_DESC_SIZE,一定要與實際生成的報告描述符大小(使用HID descriptor tool可查看)相對應,否則會導致HID設備配置失敗。

HID_Usage()等數值我在usbd_custom_hid_if.h中有定義

__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
  /* USER CODE BEGIN 0 */
  HID_UsagePageVendor(0xa0),   
	HID_Usage(0xa5),
	HID_Collection(0x01),
	HID_Usage(0xa6),
/* input  */
	HID_Usage(0xa7),
	HID_LogicalMin(0x00),
	HID_LogicalMax(0xFF),
	HID_ReportSize(8),
	HID_ReportCount(64),
	HID_Input(HID_Data | HID_Variable | HID_Absolute),



/*  output  */
	HID_Usage(0xa9),
	HID_LogicalMin(0x00),
	HID_LogicalMax(0xff),
	HID_ReportSize(8),
	HID_ReportCount(64),
	HID_Output(HID_Data | HID_Variable | HID_Absolute),
  /* USER CODE END 0 */
  0xC0    /*     END_COLLECTION	             */
};

到這裏爲止,下載程序後PC機就可以識別出HID設備了

發送數據:

使用USBD_CUSTOM_HID_SendReport,這個函數在usbd_customhid.c中定義,在while循環中調用這個函數

uint8_t USBD_CUSTOM_HID_SendReport     (USBD_HandleTypeDef  *pdev, 
                                 uint8_t *report,
                                 uint16_t len)
{
  USBD_CUSTOM_HID_HandleTypeDef     *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData;
  
  if (pdev->dev_state == USBD_STATE_CONFIGURED )
  {
    if(hhid->state == CUSTOM_HID_IDLE)
    {
      hhid->state = CUSTOM_HID_BUSY;
      USBD_LL_Transmit (pdev, 
                        CUSTOM_HID_EPIN_ADDR,                                      
                        report,
                        len);
    }
  }
  return USBD_OK;
}
 /* USER CODE BEGIN WHILE */
  while (1)
  {
    USB_Status = USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS,InReport,64);
		HAL_Delay(100);
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER C

關於端點最大傳輸包大小和HID報告描述符中的ReportCount,在usbd_customhid.c中有如下定義

#define CUSTOM_HID_EPIN_ADDR                 0x81
#define CUSTOM_HID_EPIN_SIZE                 0x02

#define CUSTOM_HID_EPOUT_ADDR                0x01
#define CUSTOM_HID_EPOUT_SIZE                0x02

這裏定義中斷傳輸端點的最大傳輸包大小爲2,但其實實際傳輸時仍然可以傳輸64個數據,原因是在HID報告描述符中有對Input和Output的傳輸數據包大小做定義,實際傳輸大小應該以這個爲標準,即每次傳輸最大數據量爲64個數據,每個數據8位。不過建議將CUSTOM_HID_EPIN_SIZE/CUSTOM_HID_EPOUT_SIZE修改成和報告符中定義的大小一致。

HID_ReportSize(8),
HID_ReportCount(64),

接收數據:

接收數據則對CUSTOM_HID_OutEvent_FS函數進行修改,以便處理接收到的數據(未完)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章