一、背景
項目用到單片機采集模擬量數據,原先使用USB轉串口,速度嫌慢,還要轉串口芯片,電腦還要安裝驅動,現更改為采用USB的HID類來傳輸。
二、單片機選型
STM32F103的USB接口簡單易用,且有STM32CubeMx代碼生成器,非常方便,可惜芯片越來越貴。本次轉用國產替代品沁恆CH32F103C8T6,價格比51還便宜,這家做USB多年,值得嘗試。
三、開發過程
(一)閱讀相關資料:
1. 關於CH32F103與STM32F103在USB接口上的差異與使用
https://blog.csdn.net/CAImoontion/article/details/112565011
2.USB HID報告描述符教程
https://zhuanlan.zhihu.com/p/27568561
(二)硬件准備
沁恆原廠開發板。USB接口方面有USBHD和USBD兩種,均是從芯片引腳直接引出到TYPE-C的USB座,沒有任何上拉、下拉電阻。
(三)編程
1. 學習沁恆官方開發包自帶的USB例程。里面沒有HID相關示例。將自帶的一個示例下載到板子后,電腦並沒有識別出硬件,看了一下代碼說明,可能需要安裝相關驅動,並使用特定上位機程序才可以通信。放棄此示例。
2. 參看《關於CH32F103與STM32F103在USB接口上的差異與使用》一文,此芯片的USBD與STM32的USBD寄存器等完全兼容,於是想到,用STM32的現有成熟代碼編好程序,再移植過來。
(1)使用STM32CubeMx,設置時鍾樹,確保USB時鍾為48M,選擇usb中間庫,配置相關參數,生成代碼。
(2)安裝官方提供的器件描述文件,打開上一步驟生成的KEIL工程,在配置中更改芯片型號,添加flash算法文件,更改調試為DAP方式。
(3)設置官方DAP調試下載器。將TX和RX引腳短路,插入USB接口,藍燈常亮,表示進入ARM模式。
(4)下載程序成功。但沒有成功,電腦沒有反應,未檢測到USB設備。
(5)反復排查,閱讀官方快速應用手冊,得知:雖然此芯片內置上下拉電阻,但是上電默認是沒打開的,估計這是為了徹底兼容STM32。按手冊上的說法,要設置新增的寄存器。經查詢,參考官方其它例程,在main函數前方代碼中加入:
typedef struct { __IO uint32_t EXTEN_CTR; } EXTEN_TypeDef; #define EXTEN_BASE ((uint32_t)0x40023800) #define EXTEN ((EXTEN_TypeDef *) EXTEN_BASE) #define EXTEN_USBD_PU_EN ((uint32_t)0x00000002)
在main函數中初始化USB設備后,加入
(EXTEN->EXTEN_CTR) |= EXTEN_USBD_PU_EN;
這樣就使能了內部電阻。
(6)下載程序,電腦可以發現設備,但認為是鼠標。正常,因為CUBEMx里面配置的是鼠標,需要改各種描述符。
(7)利用HID描述符生成軟件DT.exe,生成joystick類型的報告描述符,僅保留油門,刪除里面不需要的usage_page,只保留1個就行。
USAGE_PAGE (Generic Desktop) 05 01 LOGICAL_MINIMUM (0) 15 00 USAGE (Joystick) 09 04 COLLECTION (Application) A1 01 USAGE_PAGE (Simulation Controls) 05 02 USAGE (Throttle) 09 BB LOGICAL_MINIMUM (0) 15 00 LOGICAL_MAXIMUM (255) 26 FF 00 REPORT_SIZE (8) 75 08 REPORT_COUNT (8) 95 08 INPUT (Data,Var,Abs) 81 02 END_COLLECTION C0
(8)將上述數據填入HID_MOUSE_ReportDesc,刪掉原來的數據,得到
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { 0x05, 0x01, 0x15, 0x00, 0x09, 0x04, 0xA1, 0x01, 0x05, 0x02, 0x09, 0xBB, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x08, 0x81, 0x02, 0xC0 };
編譯下載,電腦可以識別,但是屬性框里顯示“報告描述符中找到未知項目”,說明報告描述符有問題。但仔細觀察第(7)步數據,沒發現問題。
聯系代碼上下文,發現上述數組中 HID_MOUSE_REPORT_DESC_SIZE 應該修改,否則還是之前自動生成前的數組大小,找到后修改為當前數組大小,編譯下載,電腦識別成功,在【控制面板】>【設備和打印機】中找到設備,右鍵菜單中點擊游戲控制器設置,點擊屬性,可以看到測試頁,有油門的數據條。
(9)在單片機中繼續編程,輸出數據。在上位機中利用前面獲取羅技方向盤的代碼模塊,獲取應用數據。
四、后記
整個過程耗時一天,應該說還是挺順利的。不過本次USBHD的功能沒有得到測試,這個就不能通過STM32CUBEMx的方式來編程了,只能使用官方提供的函數庫,這個要留待后面測試。