前面幾節我們使用Cubemx生成了usb的兩個使用例子(虛擬串口、HID鼠標),本節我們進一步學習,如何用生成自定義的HID設備。本節的例子在開發板上運行以后,可以通過usb HID接口實現和計算機更為自由的通信。
本節的例子使用的開發環境是cubemx 6.1.0,pack版本是1.8.0。
1)生成USB HID工程
仍然使用串口工程,如下圖添加USB的配置:
可以看到,勾選usb device的功能后,右側的芯片引腳已經設置好了,DP和DM兩根線就是usb通信的差分線。
再配置USB的軟件中間件,選擇usb device,Custom Interface Device Class,這個選項生成的就是自定義的HID設備。
然后需要修改三個參數:
CUSTOM_HID_FS_BINTERVAL,這個設置的是HID設備的通信時間間隔,單位為ms,最快可以為1ms間隔;
USBD_CUSTOM_HID_REPORT_DESC_SIZE,設置的是報告描述符的長度,設為34(后面會提到為什么是這個值);
USBD_CUSTOMHID_OUTREPORT_BUF_SIZE,比較好理解,設置的是發送緩沖區的大小,HID一次最多可以發送64個字節,我們設置為最大值。
在另一個選項卡中,我們可以看到下面幾個參數:VID、PID,以及設備標識,這里我們都不修改。
修改時鍾設置,把usb時鍾設置為48M:
其他的配置都不用改,就可以生成工程代碼了。
2)代碼編寫
打開生成的keil工程,可以看到已經生成了usb相關的源文件。
我們一步步添加需要的代碼。
首先添加報告描述符,如下圖,在usbd_custom_hid_if.c文件中,CUSTOM_HID_ReportDesc_FS定義數組內部添加:
描述符定義了usb傳輸數據的格式。
這里的數組長度USBD_CUSTOM_HID_REPORT_DESC_SIZE就是在cubemx中定義的34,與描述符數組的長度必須一樣。
然后,在usbd_customhid.c文件中,找到USBD_CUSTOM_HID_CfgHSDesc數組,修改里面的參數:
標記的四個參數,分別是:接收的長度、延時,發送的長度、延時;這里我們可以跳轉到它們的宏定義處修改;長度都修改為0x40;延時可以默認,也可以修改到1,也就是1ms周期,可以加快通信的最快速率。
接着,修改接收函數,如下圖,在usbd_custom_hid_if.c文件中,添加語句如下:
這個函數在usb接收到數據時會自動調用,這里我們在函數中,把接收到的數據用strncpy這個函數拷貝到usb_rx_data數組中,然后設置usb_rx_flag標志位。
到主函數中循環查詢標志位,查詢到則可以處理usb_rx_data中接收到的數據。
需要發送數據時,直接調用HAL庫生成的發送函數即可,函數原型如下:
到這里,最主要的就添加完了,可以到主函數中編寫測試代碼:
主函數中主要添加的是:初始時將USB端口復位,以及主循環中的接收和發送數據。
USB_IO_rest();這個函數主要是用在初始時把usb接口引腳拉低一下,讓計算機知道有新設備插入(以前的文章講過,也可以參考源代碼,很容易理解);
主循環中檢測接收標志位,如果收到數據,則把數據更新到usb_tx_data中,每隔1s檢測一下;每隔1s把usb_tx_data中的數據發送出去。
3)代碼測試
將上述keil工程編譯、下載、運行,開發板的usb口連接到計算機,可以看到計算機中識別出了一個HID設備,VID和PID與我們設置的一致:
我們使用Bus bond這個軟件,來實現usb接口和開發板通信。
打開Bus bond,在Devices頁面找到我們的hid設備,注意VID和PID與我們設置的一致:
選中該設備,然后切換到capture頁面,點擊run,檢測收發數據,可以看到開發板每1s向計算機發送一包數據,長度為64字節:
說明發送功能給是正常的。
接着,我們測試接收功能,在Devices頁面,選中我們自定義的HID設備后,點擊右下方的Send Commands,打開發送窗口,如下設置:
選中usb選項卡,然后選中interrupt Out,在data length處填入64,即需要發送64個字節;修改下方的數據為想要發送的數據,這里為便於觀察,設置成全0x11;然后點擊發送。
觀察captrue窗口,可以看到,監測到接收和發送的數據,其中out為計算機發送,in為計算機接收:
可以看到,發送去的數據,處理之后正確返回了,說明HID雙向通信成功了。
4)注意事項
a) 使用HID方式通信,最大的方便之處是不用安裝驅動程序,HID設備本質是和鼠標鍵盤一類的設備,無論windows、linux、或是andriod,都能識別;
b) USB的HID通信最快速率是64Btye/1ms,也就是最快64KB每秒,如果需要使用更快的速率通信,得使用USB的其他模式。
c) 本節的例子使用的開發環境是cubemx 6.1.0,pack版本是1.8.0,換成這個版本主要是因為在這個例子的調試過程中,老版本的環境(cubemx 5.1.0,pack1.7.0)生成的代碼里有bug,不太便於學習。
比如,生成的代碼在編譯時會報錯,原因是usbd_conf.c文件中,分頻內存的函數內部的mem沒有定義,在文件開頭添加如下代碼可以解決:
(這里在更老的版本和新版本的庫中都有定義,中間版本的卻沒有,ST公司的操作真是迷惑)。
另外,老版本的環境生成的代碼,在發送數據時,會莫名其妙把發送的數據長度填充到要發送的數據中,找了好久無法解決的一個bug。
好了,本節usb自定義HID通信的方法,就講到這里了。
歡迎關注我的公眾號,可留言“資料”獲取相關資料和軟件: