<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > STM32 USB-HID通信移植步驟

          STM32 USB-HID通信移植步驟

          作者: 時間:2016-11-17 來源:網(wǎng)絡 收藏
          最近發(fā)現(xiàn)很多人對STM32的USB通信很感興趣。要將USB的通信協(xié)議搞懂確實是一個比較漫長的過程。但是USB的HID通信無論是上位機的設計還是STM32程序的編程都非常的簡單。只是我想很多人都不知道而已。這篇文章的目的是讓大家以最短的時間將USB加到你的設備中。如果想學得更深就靠大家。

          本文引用地址:http://www.ex-cimer.com/article/201611/315429.htm

          HID只是適合低速傳輸,其理論上可以達到64KB/S,但多由于windows系統(tǒng)和硬件的關系一般達不到這個傳輸數(shù)度。但這個速度對于一般系統(tǒng)的控制和數(shù)據(jù)傳輸都已經(jīng)足夠了,而且是免驅,省去了很多麻煩。如果您需要高速傳輸可參考我的另外一篇文章《STM32的USB例程修改步驟》文章在http://blog.csdn.net/cy757/archive/2010/01/01/5117610.aspx

          一、安裝完MDK后請打開C:/Keil/ARM/Examples/ST/STM32F10xUSBLib/Demos路徑,將Custom_HID在同一個目錄下復制一份,如果你要放到其他路徑你需要在MDK Options for target的C/C++中添加USB的頭文件路徑(MDK下的/INC/ST/STM32F10x/USB)。

          二、打開usb_desc.c文件,該文件主要包含的端點描述符、設備描述符、配置描述符和字符描述符等。具體請大家參考其他資料了,這里主要說幾個常用。

          u8 DeviceDescriptor[SIZ_DEVICE_DESC]為USB設備描述符。當中的

          0x83, /*idVendor (0x0483)*/

          0x04,

          0x50, /*idProduct = 0x5750*/

          0x57,

          //idVender字段。廠商ID號,我們這里取0x0483,僅供實驗用。

          //實際產(chǎn)品不能隨便使用廠商ID號,必須跟USB協(xié)會申請廠商ID號。

          //注意小端模式,低字節(jié)在先。

          //idProduct字段。產(chǎn)品ID號,我們這里取0x5750。

          //注意小端模式,低字節(jié)應該在前。

          const u8 ConfigDescriptor[SIZ_CONFIG_DESC]是配置描述符,注意如下

          USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */

          0x81, /* bEndpointAddress: Endpoint Address (IN) */

          0x03, /* bmAttributes: Interrupt endpoint */

          0x02, /* wMaxPacketSize: 2 Bytes max */

          0x00,

          0x20, /* bInterval: Polling Interval (32 ms) */

          /* 34 */

          0x07, /* bLength: Endpoint Descriptor size */

          USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */

          /* Endpoint descriptor type */

          0x01, /* bEndpointAddress: */

          /* Endpoint Address (OUT) */

          0x03, /* bmAttributes: Interrupt endpoint */

          0x02, /* wMaxPacketSize: 2 Bytes max */

          0x00,

          0x20, /* bInterval: Polling Interval (20 ms) */

          上面包含了“輸入端點描述符”和“輸出端點描述符”。

          //wMaxPacketSize字段。該端點的最大包長。

          //bInterval字段。端點查詢的時間,

          為了實現(xiàn)更高速的通信我們修改如下:

          /******************** Descriptor of endpoint ********************/

          /* 27 */

          0x07, /*bLength: Endpoint Descriptor size*/

          USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/

          0x81, /*bEndpointAddress: Endpoint Address (IN)*/

          0x03, /*bmAttributes: Interrupt endpoint*/

          0x40, /*wMaxPacketSize: 64 Byte max */

          0x00,

          0x0A, /*bInterval: Polling Interval (10 ms)*/

          /* 34 */

          /******************** Descriptor of endpoint ********************/

          /* 27 */

          0x07, /*bLength: Endpoint Descriptor size*/

          USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/

          0x01, /*bEndpointAddress: Endpoint Address (OUT)*/

          0x03, /*bmAttributes: Interrupt endpoint*/

          0x40, /*wMaxPacketSize: 64 Byte max */

          0x00,

          0x0A, /*bInterval: Polling Interval (10 ms)*/

          const u8 ReportDescriptor[SIZ_REPORT_DESC]為HID專用的報告描述符,具體的大家就參考資料了,這里可以直接復制了。

          const u8 CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =

          {

          0x05, 0xFF, // USAGE_PAGE(User define)

          0x09, 0xFF, // USAGE(User define)

          0xa1, 0x01, // COLLECTION (Application)

          0x05, 0x01, // USAGE_PAGE(1)

          0x19, 0x00, // USAGE_MINIMUM(0)

          0x29, 0xFF, // USAGE_MAXIMUM(255)

          0x15, 0x00, // LOGICAL_MINIMUM (0)

          0x25, 0xFF, // LOGICAL_MAXIMUM (255)

          0x75, 0x08, // REPORT_SIZE (8)

          0x95, 0x40, // REPORT_COUNT (64)

          0x81, 0x02, // INPUT (Data,Var,Abs)

          0x05, 0x02, // USAGE_PAGE(2)

          0x19, 0x00, // USAGE_MINIMUM (0)

          0x29, 0xFF, // USAGE_MAXIMUM (255)

          0x15, 0x00, // LOGICAL_MINIMUM (0)

          0x25, 0xFF, // LOGICAL_MAXIMUM (255)

          0x95, 0x08, // REPORT_COUNT (8)

          0x75, 0x40, // REPORT_SIZE (64)

          0x91, 0x02, // OUTPUT (Data,Var,Abs)

          0xc0 // END_COLLECTION

          }; /* ReportDescriptor */

          const u8 CustomHID_StringVendor[CUSTOMHID_SIZ_STRING_VENDOR]

          const u8 StringProduct[SIZ_STRING_PRODUCT]

          const u8 StringSerial[SIZ_STRING_SERIAL]

          分別是“廠商字符”、“產(chǎn)品字符”、“產(chǎn)品序列號”,這些將在USB HID設備加載的時候顯示。但是這需要這些字符要求為Unicode編碼,你需要將你要顯示的字符先轉為Unicode編碼。你可以到http://computer00.21ic.org/user1/2198/archives/2007/42769.html轉換。最好大家還要根據(jù)各個數(shù)組的長度修改如下定義。

          #define CUSTOMHID_SIZ_REPORT_DESC 39

          #define CUSTOMHID_SIZ_STRING_VENDOR 64

          #define CUSTOMHID_SIZ_STRING_PRODUCT 28

          #define CUSTOMHID_SIZ_STRING_SERIAL 26

          三、打開hw_config.c文件,將那些沒有的函數(shù)刪除,只保留如下函數(shù)

          a) Set_System(void)

          b) void Set_USBClock(void)

          c) void USB_Interrupts_Config(void)

          d) void USB_Cable_Config (FunctionalState NewState)

          特別要注意最后一個函數(shù),其主要作用是控制USB的上拉電阻,讓電腦檢測USB設備是否連接的。

          四、打開stm32f10x_it.c文件,把EXTI15_10_IRQHandler等中斷內(nèi)的代碼刪除。

          打開usb_prop.c文件,修改如下:

          void CustomHID_Reset(void)

          {

          /* Set Joystick_DEVICE as not configured */

          pInformation->Current_Configuration = 0;

          pInformation->Current_Interface = 0;/*the default Interface*/

          SetBTABLE(BTABLE_ADDRESS);

          /* Initialize Endpoint 0 */

          SetEPType(ENDP0, EP_CONTROL);

          SetEPTxStatus(ENDP0, EP_TX_STALL);

          SetEPRxAddr(ENDP0, ENDP0_RXADDR);

          SetEPTxAddr(ENDP0, ENDP0_TXADDR);

          Clear_Status_Out(ENDP0);

          SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);

          SetEPRxValid(ENDP0);

          /* Initialize Endpoint 1 */

          SetEPType(ENDP1, EP_INTERRUPT);

          SetEPTxAddr(ENDP1, ENDP1_TXADDR);

          SetEPTxCount(ENDP1, 64);

          SetEPRxStatus(ENDP1, EP_RX_DIS);

          SetEPTxStatus(ENDP1, EP_TX_NAK);

          /* Initialize Endpoint 1 */

          // SetEPType(ENDP1, EP_INTERRUPT);

          SetEPRxAddr(ENDP1, ENDP1_RXADDR);

          SetEPRxCount(ENDP1, 64);

          // SetEPTxStatus(ENDP1, EP_TX_DIS);

          SetEPRxStatus(ENDP1, EP_RX_VALID);

          /* Set this device to response on default address */

          SetDeviceAddress(0);

          }

          五、usb_endp.c文件

          void EP1_OUT_Callback(void)

          {

          這些寫接收代碼

          }

          六、數(shù)據(jù)發(fā)送和接收,舉例說明

          1、數(shù)據(jù)接收

          u8 DataLen;

          DataLen = GetEPRxCount(ENDP1);

          PMAToUserBufferCopy(TX1_buffer, ENDP1_RXADDR, DataLen);

          SetEPRxValid(ENDP1);

          USART1_Send(DataLen);

          count_out = 1;

          2、數(shù)據(jù)發(fā)送

          UserToPMABufferCopy(InBuffer, GetEPTxAddr(ENDP1), 64);

          SetEPTxCount(ENDP1, 64);

          SetEPTxValid(ENDP1);

          如果你發(fā)送數(shù)據(jù)較為頻繁,每次發(fā)送前應使用GetEPTxStatus(ENDP1)檢測上次發(fā)送是否完成。如果端點狀態(tài)處于EP_TX_VALID,說明發(fā)送未結束,如果端點狀態(tài)處于EP_TX_NAK,說明發(fā)送結束。



          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();