《極海芯得》系列內(nèi)容為用戶使用極海系列產(chǎn)品的經(jīng)驗總結(jié),均轉(zhuǎn)載自21ic論壇極海半導(dǎo)體專區(qū),全文未作任何修改,未經(jīng)原文作者授權(quán)禁止轉(zhuǎn)載。
最近需要使用到 APM32F427 枚舉成Custom HID設(shè)備進(jìn)行用戶自定義通信,但是官方的例程只有提供的HID枚舉為鼠標(biāo)或者鍵盤類型的設(shè)備。這里記錄一下,怎么使用Geehy官方的USB中間件,實現(xiàn)自定義的USB HID設(shè)備進(jìn)行用戶通信。
1. USB HID設(shè)備簡介
USB HID類是USB設(shè)備的一個標(biāo)準(zhǔn)設(shè)備類,它屬于人機交互操作的設(shè)備,用于控制計算機操作的一些方面,如USB鼠標(biāo)、USB鍵盤、USB游戲操縱桿等。但HID設(shè)備類不一定要有人機接口,只要符合HID類別規(guī)范的設(shè)備都是HID設(shè)備。
USB HID設(shè)備的一個好處就是操作系統(tǒng)自帶了HID類的驅(qū)動程序,而用戶無需去開發(fā)驅(qū)動程序,只要使用API系統(tǒng)調(diào)用即可完成通信。所以經(jīng)常會把MCU的USB外設(shè)枚舉為自定義的HID設(shè)備類,用于和電腦的上位機進(jìn)行通信。
關(guān)于USB HID設(shè)備,這里只是簡單介紹下,大家可以查閱網(wǎng)上的資料,或者從下面的USB官網(wǎng)進(jìn)行學(xué)習(xí)。
USB HID設(shè)備類官網(wǎng)介紹:https://www.usb.org/hid
2. 基于官網(wǎng)的USB中間件如何實現(xiàn)Custom HID設(shè)備
2.1 準(zhǔn)備工作
官方 F427 芯片的SDK已經(jīng)提供了很多的USB例程,我們基于官方的USB例程修改即可。
1、下載官網(wǎng)APM32F427 SDK:https://www.geehy.com/product/fifth/APM32F427_425_423#design
2、我們要實現(xiàn)自定義的USB HID設(shè)備,與之最接近的就是427 SDK中提供的OTGD_Custom_HID_Keyboard例程。我們復(fù)制一份該例程,基于該例程修改為USB Custom HID設(shè)備例程。

2.2 修改USB HID報告描述符
報告描述符就是描述報告(HID接口上傳輸事務(wù)中的數(shù)據(jù))的一組數(shù)據(jù)結(jié)構(gòu)。
USB的報告描述符組成,都有其特定的組成格式。關(guān)于USB HID的報告描述符的組成和格式,可參考官方文檔《Device Class Definition for human interface device (HID)》。這里不多介紹報告描述符了,直接介紹如何修改代碼即可。
把usbd_custom_hid_if.c文件定義的報告描述符數(shù)組:

把該文件定義的報告描述符直接修改為如下代碼:
/**
* @brief CUSTOM HID report descriptor
*/
uint8_t USBD_CUSTOM_HIDReportDesc[USBD_CUSTOM_HID_REPORT_DESC_SIZE] =
{
/* USER CODE BEGIN 0 */
0x06, 0xFF, 0x00, /* USAGE_PAGE (Vendor Page: 0xFF00) */
0x09, 0x01, /* USAGE (Demo Kit) */
0xa1, 0x01, /* COLLECTION (Application) */
// 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)
// 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)
/* USER CODE END 0 */
0xC0 /* END_COLLECTION */
};
該描述符主要是定義了輸入輸出Input、Ouput兩個報告。其中,Input用于MCU上傳數(shù)據(jù),Output下傳數(shù)據(jù)。所有報告大小定義為64byte,也就是說每次最大上下傳數(shù)據(jù)量也就為64byte。
另外數(shù)組USBD_CUSTOM_HID_REPORT_DESC_SIZE這個宏定義需要修改為我們定義的報告描述符的大小,也就是34。在對應(yīng)的頭文件修改如下:

2.3 修改接收回調(diào)函數(shù)
usbd_custom_hid_if.c文件實現(xiàn)了一個接收處理函數(shù),當(dāng)USB檢測到有數(shù)據(jù)接收時,會調(diào)用該函數(shù)進(jìn)行接收數(shù)據(jù)處理。
我們需要修改該函數(shù),當(dāng)有數(shù)據(jù)接收時,使得 USB_Received_Flag 變量置1,用于上層數(shù)據(jù)處理函數(shù)的處理。修改的代碼如下:
uint8_t USB_Received_Flag = 0;
/*!
* @brief USB device CUSTOM HID interface receive handler
*
* @param buffer: Command data buffer
*
* @param length: Command data length
*
* @retval USB device operation status
*/
USBD_STA_T USBD_FS_CUSTOM_HID_ItfReceive(uint8_t *buffer, uint8_t *length)
{
USBD_STA_T usbStatus = USBD_OK;
UNUSED(length);
USB_Received_Flag = 1; // 檢測到有數(shù)據(jù)接收,標(biāo)志位置1
USBD_CUSTOM_HID_RxPacket(&gUsbDeviceFS);
return usbStatus;
}
2.4 實現(xiàn)應(yīng)用層用戶代碼的收發(fā)函數(shù)
1、實現(xiàn)USB Custom HID設(shè)備接收函數(shù)
我們實現(xiàn)一個USB HID的數(shù)據(jù)接收函數(shù),當(dāng)檢測到 USB_Received_Flag 標(biāo)志位置1之后,就可以調(diào)用該函數(shù)進(jìn)行數(shù)據(jù)接收。
uint32_t USB_GetData(uint8_t *data, uint32_t dataNum)
{
USBD_CUSTOM_HID_INFO_T* usbDevHID = (USBD_CUSTOM_HID_INFO_T*)gUsbDeviceFS.devClass[gUsbDeviceFS.classID]->classData;
if (usbDevHID == NULL)
{
return 0;
}
if (dataNum > usbDevHID->reportSize)
{
dataNum = usbDevHID->reportSize;
}
for (uint32_t i = 0; i < dataNum; i++)
{
*data++ = usbDevHID->report[i];
}
return dataNum;
}
接收到的數(shù)據(jù)會存放在USB的gUsbDeviceFS 全局變量中,該全局變量包含了USB的所有信息。
2、實現(xiàn)USB Custom HID設(shè)備發(fā)送函數(shù)
USB HID設(shè)備發(fā)送數(shù)據(jù),我們只需要調(diào)用F427 SDK提供的USBD_CUSTOM_HID_TxReport函數(shù)發(fā)送數(shù)據(jù)即可。我們對該函數(shù)封裝一層用于用戶調(diào)用。
uint32_t USB_SendData(uint8_t *data, uint32_t dataNum)
{
// USBD_CUSTOM_HID_IN_EP_SIZE 64
if (USBD_OK != USBD_CUSTOM_HID_TxReport(&gUsbDeviceFS, data, 64))
{
return 0;
}
return dataNum;
}
2.5 實現(xiàn)主函數(shù)與PC進(jìn)行讀寫通信
前面已經(jīng)實現(xiàn)的用戶應(yīng)用層USB Custom HID設(shè)備的收發(fā)函數(shù),我們可以在主函數(shù)調(diào)用USB HID收發(fā)函數(shù)進(jìn)行讀寫通信。測試是否確實和PC端上位機實現(xiàn)了數(shù)據(jù)的收發(fā)。
主函數(shù)代碼實現(xiàn)如下:
int main(void)
{
uint8_t report[64] = {0};
DAL_DeviceConfig();
/* Infinite loop */
while (1)
{
// USB_Received_Flag 變量置1,說明有USB數(shù)據(jù)接收到。下面對接收的數(shù)據(jù)進(jìn)行處理
if (USB_Received_Flag == 1)
{
USB_Received_Flag = 0;
USB_GetData(report, 64); // 獲取USB接收到的數(shù)據(jù)
// 打印測試
// for (uint32_t i = 0; i < 64; i++)
// printf("%02X ", report[i]);
USB_SendData(report, 64); // 把接收到的數(shù)據(jù)原封不懂的發(fā)送回給上位機
}
}
}
該主函數(shù)就是實現(xiàn)了簡單的USB HID數(shù)據(jù)的收發(fā),把PC端下發(fā)給F427的USB數(shù)據(jù),然后再返回給PC端上位機。
3. USB Custom HID設(shè)備通信的測試驗證
3.1 在電腦的設(shè)備管理器查看
在第二節(jié)修改完代碼之后,編譯下載到APM32F427芯片,運行起來后,我們可以在windows系統(tǒng)的設(shè)備管理器的人體學(xué)輸入設(shè)備,查看到我們自己實現(xiàn)的USB Custom HID的。如下:

又或者通過控制面板的設(shè)備和打印機的選項,可以查看到我們實現(xiàn)的USB HID設(shè)備,如下:

可以看到我們實現(xiàn)的APM32 Custom HID設(shè)備,說明修改的代碼已經(jīng)正常運行。
3.2 通過PC端上位機工具進(jìn)行數(shù)據(jù)收發(fā)測試
我們需要使用USB HID的調(diào)試工具,進(jìn)行數(shù)據(jù)收發(fā)測試。關(guān)于這樣的上位機工具,網(wǎng)上有很多的。我這里使用的是PortHelper工具。這個工具大家可以網(wǎng)上搜一下下載。
或者下載我分享的下面這個百度網(wǎng)盤鏈接下載:
鏈接:https://pan.baidu.com/s/1qkZCs-dG__czkDrAvN7z-w?pwd=q6er提取碼:q6er
1、打開PortHelper 上位機,然后選擇USB調(diào)試,然后找到 APM32 Custom HID 設(shè)備,然后打開USB。

2、PortHelper 測試與APM32F427進(jìn)行USB數(shù)據(jù)收發(fā)
打開USB之后,然后我們勾選hex發(fā)送,hex顯示。然后點擊發(fā)送即可,如下圖:

然后可以PC端上位機發(fā)送的數(shù)據(jù)給APM32F427,芯片原樣返回數(shù)據(jù)給該上位機。
到這里就實現(xiàn)的我們自定義的USB Custom HID設(shè)備,該設(shè)備主要是接收PC端上位機發(fā)送過來的數(shù)據(jù),然后APM32F427接收進(jìn)行處理。在實際項目我是需要基于這個通信進(jìn)行更復(fù)雜的項目開發(fā)。
注:文章作者在原帖中提供了代碼文件,有需要請至原文21ic論壇
原文地址:https://bbs.21ic.com/icview-3501049-1-1.html?_dsign=8cbdef4d
-
usb
+關(guān)注
關(guān)注
60文章
8456瀏覽量
285261 -
驅(qū)動程序
+關(guān)注
關(guān)注
19文章
872瀏覽量
50609 -
HID
+關(guān)注
關(guān)注
2文章
140瀏覽量
48977
原文標(biāo)題:極海芯得 EP.76 | APM32F427基于官方USB中間件如何實現(xiàn)自定義USB HID設(shè)備與PC進(jìn)行通信
文章出處:【微信號:geehysemi,微信公眾號:Geehy極海半導(dǎo)體】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
極海APM32F427移植CherryUSB實現(xiàn)自定義USB HID設(shè)備
STM32 自定義HID USB設(shè)備的實現(xiàn)
STM32F107做USB host識別自定義HID設(shè)備有了解的嗎
采用HID協(xié)議實現(xiàn)工控自定義鍵盤接口設(shè)計
標(biāo)準(zhǔn)hid設(shè)備pc上驅(qū)動不用自己開發(fā),自定義的hid設(shè)備windows系統(tǒng)的驅(qū)動用自己開發(fā)嗎
USB自定義設(shè)備類的實現(xiàn)
如何利用CubeMX開發(fā)USB自定義HID設(shè)備實現(xiàn)USB人機接口通訊?
求助,能否為USB自定義設(shè)備提供PC端驅(qū)動程序?
國民技術(shù)MCU應(yīng)用筆記連載(4)——N32G45x系列USB自定義HID設(shè)備的實現(xiàn)
各位大佬,CH573F能模擬自定義HID設(shè)備嗎,就是免驅(qū)的HID自定義設(shè)備
基于自定義幀的PC與EEPROM串行通信設(shè)計
萬利EK-STM32板實現(xiàn)的自定義USB HID設(shè)備
基于HAL庫的USB自定義HID設(shè)備實現(xiàn)
【技術(shù)專欄】泰凌微電子USB HID 用戶自定義設(shè)備應(yīng)用及調(diào)試
極海APM32F427系列MCU榮獲IEC 60730/60335功能安全認(rèn)證
極海APM32F427如何實現(xiàn)自定義USB HID設(shè)備與PC進(jìn)行通信
評論