王曉東
(唐山學院 計算機科學與技術(shù)系,河北 唐山 063000)
USB總線協(xié)議是由Intel,Compaq,Microsoft等七家公司共同制定的串行接口標準[1],協(xié)議內(nèi)部包含完善的主從機通訊機制,支持從高速視頻傳輸?shù)降退俨樵儌鬏敹喾N通訊模式,傳輸速率高,從USB1.1協(xié)議發(fā)展到USB3.0協(xié)議,速度已達到5.0 Gbps,而且支持設(shè)備的帶電熱插拔,因此支持USB總線協(xié)議的設(shè)備使用起來十分方便,被廣泛應(yīng)用在通用計算機和邊緣計算領(lǐng)域。如文獻[2]作者使用Windows的DDK開發(fā)工具,基于USB總線的HID人機接口協(xié)議,開發(fā)了一種USB接口自動測試設(shè)備。但對于工業(yè)系統(tǒng)開發(fā)者和廠商來說,USB驅(qū)動程序開發(fā)過程十分復雜,在Windows環(huán)境下需要使用WDK或者DDK開發(fā)工具,并且隨著操作系統(tǒng)的升級,開發(fā)工具和驅(qū)動程序也需要隨之升級,另外,商業(yè)開發(fā)USB設(shè)備驅(qū)動還需要繳納認證費用,增加經(jīng)濟負擔。因此大多數(shù)的工業(yè)控制器仍然使用串口或者USB轉(zhuǎn)串口的方式通訊,正常速度為幾十kbps到幾百kbps,效率較低。計算機的USB接口HID(Human Interface Device)類協(xié)議[3]負責人機接口設(shè)備如鼠標、鍵盤和游戲桿等和計算機交互操作。USB HID接口權(quán)限自由度高,特別是鼠標類設(shè)備具有操作系統(tǒng)最高權(quán)限,其每個操作信號、每組數(shù)據(jù)都可以在用戶許可的情況下發(fā)出或者接收,應(yīng)用開發(fā)用戶可以調(diào)用HID接口的API函數(shù)支持人機接口類別的設(shè)備。
STM32系列硬件是專為要求高性能、低成本、低功耗的嵌入式應(yīng)用設(shè)計的ARM Cortex內(nèi)核處理器,其內(nèi)部自帶flash和RAM,接口資源豐富,并自帶USB物理收發(fā)器,因此使用單芯片即可構(gòu)建完整的智能物聯(lián)網(wǎng)儀器儀表的核心模塊[4-5]。STM32處理器性價比很高,適合于工業(yè)和民用測控領(lǐng)域使用,文獻[6]即使用STM32搭建低成本的測量裝置,實現(xiàn)了高精度的電量測量。STM32處理器的通訊功能強大,在STM32處理器內(nèi)部集成了USB收發(fā)器,支持USB HID通訊協(xié)議,使用USB HID接口每次最多可發(fā)送1 024個字節(jié),對于USB2.0硬件,最大速度可以達到24.576 MB/s,足以滿足中等性能工業(yè)控制器的需求。有學者使用USB HID技術(shù)開發(fā)了專用的鼠標[7]、鍵盤[8]和手勢輸入設(shè)備[9],但是由于沒有主機數(shù)據(jù)輸出,僅有單向數(shù)據(jù)輸入功能,不能用于控制器。
本設(shè)計基于STM32構(gòu)建了一個使用USB HID協(xié)議的多功能控制器,數(shù)據(jù)傳輸工作采用中斷傳輸方式,主機和控制器(從機)之間建立相互獨立的寫入和讀出管道,上位機控制軟件直接調(diào)用HID接口的API函數(shù)實現(xiàn)對下位機硬件的讀寫控制。
基于STM32的USB HID接口控制器的硬件系統(tǒng)結(jié)構(gòu)如圖1所示??刂破鬟x擇STM32F103作為系統(tǒng)主處理器,其工作頻率為72 MHz,采用ARM CortexM3內(nèi)核,功耗約為0.1 W,其內(nèi)部集成了兩個AD采樣器,可以直接接收0~3 V的模擬輸入電壓,支持USB全速設(shè)備。主處理器通過定時器中斷輸出3.3 V的PWM信號,PWM信號經(jīng)過光電隔離后輸出給控制驅(qū)動電路。本設(shè)計使用LED驅(qū)動電路進行驗證,由于驅(qū)動電路工作在高電壓、大電流狀態(tài)下,因此PWM信號必須隔離輸出。在控制器系統(tǒng)集成多路光電隔離的GPIO信號,用于外部開關(guān)控制,系統(tǒng)中MAX3232作為UART串口驅(qū)動,用于調(diào)試接口和功能擴展。
圖1 USB HID接口控制器的硬件系統(tǒng)結(jié)構(gòu)圖
控制器USB HID接口部分的實際電路圖如圖2所示。STM32F103的PA11和PA12分別連接USB總線的DM和DP端,在DP端上拉1.5 kΩ電阻用于全速設(shè)備檢測熱插拔事件,如果DP端直接上拉到3.3 V電壓,因從機的上電延遲,會導致枚舉失敗,因此USB總線的上拉電阻接到STM32F103處理器的IO端口PB10,當控制器啟動,在固件main函數(shù)中將PB10拉高,從而等待USB插入事件,開始進行枚舉。
圖2 USB HID接口電路圖
參考USB HID協(xié)議,USB HID接口控制器和主機之間需建立兩種傳輸管道:控制傳輸管道和中斷傳輸管道??刂苽鬏敼艿烙糜谠O(shè)備枚舉,從設(shè)備上傳設(shè)備描述符、配置描述符以及HID描述符等信息,下發(fā)Get請求和Set請求,在設(shè)備資源方面占用默認的端點0。因為本控制器屬于自定義的HID設(shè)備,首先需要重新定義HID報表描述符,在報表描述中增加和修改數(shù)據(jù)輸入和輸出報告,修改通訊數(shù)據(jù)包的字長、字數(shù)目、傳輸方向、最大值和最小值。HID報表描述符完成后,在HID描述符填充HID報表描述符信息(長度、類別)??刂破魇褂弥袛鄠鬏斶M行實際的負載數(shù)據(jù)傳輸,其內(nèi)部分配兩個中斷類型的端點,分別用于數(shù)據(jù)接收和發(fā)送。
控制器USB HID接口主從機枚舉工作和交互過程如圖3所示。主機檢測到從機接入后,開始標準設(shè)備枚舉過程,包括請求和接收設(shè)備描述符、設(shè)置從機地址、請求和接收配置描述符三個步驟。通過標準設(shè)備枚舉過程,主機獲得控制器的設(shè)備描述符、配置描述符、接口描述符和端點描述符。標準設(shè)備枚舉之后,進行HID類設(shè)備枚舉,主機向從機發(fā)送Get HID類描述符請求,然后收到HID類描述符和報表描述符。在控制器全部枚舉后,系統(tǒng)進入正常的工作狀態(tài),在Windows環(huán)境下主機通過調(diào)用ReadFile和WriteFile實現(xiàn)和從機之間收發(fā)數(shù)據(jù)。在Linux環(huán)境下可以調(diào)用libusb庫實現(xiàn)USB HID通訊。HID設(shè)備定義了6個HID類請求,在STM32固件程序的Setup階段中斷函數(shù)中響應(yīng)這些請求命令,根據(jù)HID請求發(fā)送相應(yīng)的HID類描述符。
圖3 控制器USB HID接口主從機枚舉工作和交互過程
對于自定義的USB總線HID設(shè)備,必須重新構(gòu)建Report報表描述符[3]。圖4是控制器HID協(xié)議報表描述符的基本結(jié)構(gòu),包括輸入報告和輸出報告,有效數(shù)據(jù)報文包含8個字單元,每個字單元由8個二進制位(1個字節(jié))組成。報表描述符定義好后在HID設(shè)備的接口描述符和端點描述符進行傳輸方式定義,接口描述符的bNumEndpoints,bInterfaceClass和bInterfaceProtocol字段分別定義控制器端點數(shù)目、HID設(shè)備類別以及HID交互協(xié)議。
圖4 控制器USB HID接口協(xié)議報表描述符的基本結(jié)構(gòu)
控制器STM32硬件的固件程序使用三個數(shù)據(jù)結(jié)構(gòu)處理USB通訊事務(wù),分別是:①DEVICE_INFO,保存USB請求命令和通訊狀態(tài)信息;②DEVICE_PROP,USB通訊過程的回調(diào)函數(shù),包括控制傳輸Setup階段處理,Stage IN和OUT事務(wù)處理,獲得設(shè)備、配置和字符描述符處理;③USER_STANDARD_REQUESTS,一組標準請求回調(diào)函數(shù)指針,用于定制上位機的標準請求,可編寫相應(yīng)的函數(shù)實例化這些指針,也可以設(shè)置成NOP_Process系統(tǒng)函數(shù)。本控制器系統(tǒng)函數(shù)均設(shè)置成NOP_Process??刂破鞴碳绦蚴褂肧TM32開發(fā)庫定義以上三個數(shù)據(jù)結(jié)構(gòu)的實例化對象指針變量pInformation,pProperty,pUser_Standard_Requests處理USB通訊。在STM32的USB總線的中斷處理USB_LP_CAN1_RX0_IRQHandler中調(diào)用CTR_LP中斷服務(wù)函數(shù),中斷服務(wù)函數(shù)內(nèi)部這三個指針指向結(jié)構(gòu)體對象完成控制傳輸過程。
多功能控制器固件主控程序流程如圖5所示??刂破鞣謩e使用中斷模式的端點1(管道EP1)、端點2接收和發(fā)送數(shù)據(jù)。在端點1的中斷服務(wù)中如果接收到一串長度和格式符合要求的數(shù)據(jù),即作為一條控制消息,將其放入一個消息隊列。在主程序中使用一個while循環(huán)任務(wù)作為后臺主線程程序,主線程程序首先檢測消息隊列是否為空,如果不為空,則從隊列中讀取一條控制消息,對控制消息進行CRC校驗,如果CRC校驗成功,則將控制消息里命令參數(shù)賦值給控制寄存器,然后在后續(xù)的過程中根據(jù)控制寄存器的值運行PWM控制程序、AD采樣程序、GPIO讀寫程序等子模塊。
圖5 多功能控制器固件主控程序流程圖
針對本USB HID接口多功能控制器,上位機軟件使用API函數(shù)實現(xiàn)USB HID功能,在Windows環(huán)境下可以調(diào)用hid.lib,hidclass.lib,hidparse.lib和setupapi.lib四個接口庫完成,而在Linux環(huán)境下可使用libusb調(diào)用libusb-1.0.so.0.1.0庫完成。限于篇幅,以下介紹Windows環(huán)境下上位機實現(xiàn)USB HID功能編程的方法。
在Windows環(huán)境下編程時程序中需要hidsdi.h和setupapi.h兩個頭文件。調(diào)用這兩個頭文件必須按照C語言的調(diào)用規(guī)則。Windows環(huán)境下上位機對USB HID接口控制器讀寫流程如圖6所示。首先找到HID設(shè)備的GUID,調(diào)用后獲得HID設(shè)備的指針,然后找到單個HID設(shè)備的信息,調(diào)用后使用CreaeFile函數(shù)按照設(shè)備路徑打開,設(shè)備打開后讀出設(shè)備屬性,然后根據(jù)設(shè)備屬性找到設(shè)備屬性中符合控制器ID(VID和PID)的設(shè)備,針對滿足條件的設(shè)備重新使用CreateFile函數(shù)調(diào)用兩次,建立讀寫句柄hReader和hWriter。以上過程是通過調(diào)用hidsdi.h和setupapi.h頭文件里面的HidD_GetHidGuid,SetupDiGetClassDevs,SetupDiEnumDeviceInterfaces,SetupDiEnumDeviceInterfaceDetail等一系列API函數(shù)實現(xiàn)的。設(shè)備檢測過程中,因為USB從機設(shè)備最多有127個,因此設(shè)備遍歷檢測計數(shù)設(shè)置為127,即可保證全部HID設(shè)備屬性被檢測到。在主機的讀寫進程中直接調(diào)用ReadFile和WriteFile函數(shù)實現(xiàn)對控制器的讀寫,hReader和hWriter句柄是關(guān)鍵參數(shù)。
圖6 上位機對USB HID接口控制器讀寫流程圖
在驗證實驗中,USB HID接口控制器和主機之間的數(shù)據(jù)流管道配置如圖7所示。主機通過EP0端點的控制傳輸方式對控制器進行枚舉和初始化;設(shè)備的端點1(管道EP1)用于接收主機實際控制信息,端點2(管道EP2)用于設(shè)備數(shù)據(jù)讀出,EP1,EP2工作采用中斷傳輸方式??刂破鲾?shù)據(jù)包的大小采用8個字節(jié),控制器和主機之間采用短數(shù)據(jù)包的形式保證控制器響應(yīng)的敏捷性,每個控制輸出事務(wù)和狀態(tài)讀取的輸入事務(wù)均包含8個字節(jié)的有效數(shù)據(jù)。
圖7 控制器和主機之間數(shù)據(jù)流管道配置
實驗驗證用的處理器型號是STM32F103C8T6。圖8是USB HID接口控制器實際硬件電路和系統(tǒng)測試實驗圖。外部測試硬件使用一個LED光源,通過PWM接口控制LED恒流源驅(qū)動器輸出。
(a)實際硬件電路
圖9是示波器顯示的USB HID接口控制器PWM信號輸出的實際波形,其中(a)為50%占空比,(b)為80%占空比,硬件根據(jù)控制要求改變PWM信號的占空比。圖10是控制器通過PWM信號控制LED光源獲得的實驗數(shù)據(jù),橫坐標為PWM信號的占空比(ratio),其范圍從0.05到1.0(較小數(shù)據(jù)沒有顯示),縱坐標為LED工作電流值。LED的驅(qū)動電路使用LM3409恒流源驅(qū)動芯片,在實驗過程中上位機向控制器下發(fā)占空比(ratio)和頻率參數(shù),然后控制器根據(jù)這兩個參數(shù)生成PWM信號,PWM信號控制LED光源驅(qū)動芯片輸出的開關(guān),從而調(diào)節(jié)LED光源的亮度。選擇2 kHz和8 kHz的PWM信號頻率進行測試,由圖10可知,當選擇較高頻率(8 kHz)PWM信號時,LED調(diào)節(jié)的范圍較大,較小的占空比也有電流輸出,LED電流輸出最小值可以小于1 mA,可見控制器可以很方便地實現(xiàn)一個寬范圍的控制過程??刂破饔布骄ぷ麟娏鳛?35 mA,功耗低、性能穩(wěn)定,數(shù)據(jù)測試過程中上位機輸出100%成功。系統(tǒng)經(jīng)過24 h長時間測試,能夠穩(wěn)定運行。
(a)通道1(50%的占空比)
圖10 控制器通過PWM信號控制LED光源圖示(改變占空比獲得電流輸出)
本文提出了一種基于STM32硬件的USB HID接口多功能控制器設(shè)計方案,主機和USB設(shè)備之間采用控制管道、讀管道和寫管道等相互獨立的多個傳輸管道實現(xiàn)控制數(shù)據(jù)的讀寫。通過重新定義USB HID報表描述符和設(shè)備與主機之間的雙向通訊控制流程,實現(xiàn)了可編程變頻PWM信號控制、GPIO讀入和輸出、模擬量AD采集多種功能。實驗驗證的結(jié)果表明,系統(tǒng)使用靈活,反應(yīng)快速,可以穩(wěn)定運行。
此控制器可以在跨平臺操作系統(tǒng)的主機下使用,安裝和部署方便,且免驅(qū)安裝,可用于機器視覺系統(tǒng)、生產(chǎn)測試、工業(yè)測控自動化、儀器儀表、邊緣計算、可穿戴設(shè)備等領(lǐng)域,具備運算處理能力強、功耗小、使用和維護成本低等優(yōu)點,而且為應(yīng)對智能傳感器大數(shù)據(jù)控制的需求,此控制器可以通過增加USB接口設(shè)置、修改包長、升級USB協(xié)議版本來滿足數(shù)據(jù)流傳輸?shù)囊?,因此具有良好的?yīng)用價值。