STM32完成USB_Keyboard的实验总结

本文是STM32完成USB_Keyboard的实验总结。实验使用正点原子战舰开发板与PC通讯,以触摸屏作键盘输入。实验中设备枚举易出问题,成功枚举后可修改程序发送键盘数据。还介绍了枚举过程分析及模拟键盘发送数据的具体实现方法。

STM32完成USB_Keyboard的实验总结

实验平台: 正点原子战舰开发板(STM32F103ZET6) + win7(PC),下位机程序是通过战舰开发板上“实验49触摸USB鼠标”更改.

实验目的: 使用STM32F103自带的USB模块编程实现下位机与PC的USB通讯,使用开发板上自带的触目屏作为键盘输入,在PC的记事本中显示对应按键.

实验心得: 实验中碰到问题最多的地方就是设备的枚举不成功.若设备的枚举成功,后面的处理就会简单很多.通讯成功后就可以使用USBlyzer软件抓取数据包,解析通讯数据.

1. USB_Keyboard的枚举过程

以下代码是使用串口助手获取的数据,记录了USB_Keyboard枚举过程的部分数据,主要是通过Endpoint0的Setup完成枚举,代码中有部分注释,详细的枚举过程请参考USB2.0协议或参考《圈圈教你玩USB》.

 

设备复位
设备复位
SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80    Get_Configuaration
USBbRequest = 0x06         Get_Descriptor
USBwValue = 0x01           Device Descriptor
USBwIndex = 0x00
USBwLength = 0x40          Max Bytes

数据输出 
0x12  0x01  0x00  0x02  0x00  0x00  0x00  0x40  0x83  
0x04  0x10  0x57  0x00  0x02  0x01  0x02  0x03  0x01
const u8 Keyboard_DeviceDescriptor[KEYBOARD_SIZ_DEVICE_DESC] =
  {
    0x12,                       /*bLength */
    USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
    0x00,                       /*bcdUSB */
    0x02,
    0x00,                       /*bDeviceClass*/
    0x00,                       /*bDeviceSubClass*/
    0x00,                       /*bDeviceProtocol*/
    0x40,                       /*bMaxPacketSize40*/
    0x83,                       /*idVendor (0x0483)*/
    0x04,
    0x10,                       /*idProduct = 0x5710*/
    0x57,
    0x00,                       /*bcdDevice rel. 2.00*/
    0x02,
    1,                          /*Index of string descriptor describing
                                                  manufacturer */
    2,                          /*Index of string descriptor describing
                                                 product*/
    3,                          /*Index of string descriptor describing the
                                                 device serial number */
    0x01                        /*bNumConfigurations*/
  }
  ; /* Keyboard_DeviceDescriptor */

设备复位
SetUp阶段......
Host 输入信息
USBbmRequestType = 0x00    Set_Address
USBbRequest = 0x05         
USBwValue = 0x0004         Address = 0x04
USBwIndex = 0x00
USBwLength = 0x00

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80    Get_Configuaration
USBbRequest = 0x06		   Get_Descriptor
USBwValue = 0x01 		   Device Descriptor
USBwIndex = 0x00
USBwLength = 0x12

数据输出 
0x12  0x01  0x00  0x02  0x00  0x00  0x00  0x40  0x83  
0x04  0x10  0x57  0x00  0x02  0x01  0x02  0x03  0x01 


SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80    Get_Configuaration
USBbRequest = 0x06 		   Get_Descriptor
USBwValue = 0x02           Configuaration + Interface + String + Endpoint Descriptor
USBwIndex = 0x00
USBwLength = 0xff

数据输出 
0x09  0x02  0x29  0x00  0x01  0x01  0x00  0xe0  0x32  
0x09  0x04  0x00  0x00  0x02  0x03  0x01  0x01  0x00  
0x09  0x21  0x00  0x01  0x00  0x01  0x22  0x3d  0x00  
0x07  0x05  0x81  0x03  0x08  0x00  0x20  0x07  0x05  
0x01  0x03  0x08  0x00  0x20 
const u8 Keyboard_ConfigDescriptor[KEYBOARD_SIZ_CONFIG_DESC] =
  {
    0x09, /* bLength: Configuation Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    KEYBOARD_SIZ_CONFIG_DESC,
    /* wTotalLength: Bytes returned */
    0x00,
    0x01,         /*bNumInterfaces: 1 interface*/
    0x01,         /*bConfigurationValue: Configuration value*/
    0x00,         /*iConfiguration: Index of string descriptor describing
                                     the configuration*/
    0xE0,         /*bmAttributes: bus powered */
    0x32,                             /*MaxPower 100 mA: this current is used for detecting Vbus*/

    /************** Descriptor of Keyboard Mouse interface ****************/
    /* 09 */
    0x09,         /*bLength: Interface Descriptor size*/
    USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
    0x00,         /*bInterfaceNumber: Number of Interface*/
    0x00,         /*bAlternateSetting: Alternate setting*/
    0x02,         /*bNumEndpoints*/
    0x03,         /*bInterfaceClass: HID*/
    0x01,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
    0x01,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
    0,            /*iInterface: Index of string descriptor*/
    /******************** Descriptor of Keyboard Mouse HID ********************/
    /* 18 */
    0x09,         /*bLength: HID Descriptor size*/
    HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
    0x00,         /*bcdHID: HID Class Spec release number*/
    0x01,
    0x00,         /*bCountryCode: Hardware target country*/
    0x01,         /*bNumDescriptors: Number of HID class descriptors to follow*/
    0x22,         /*bDescriptorType*/
    KEYBOARD_SIZ_REPORT_DESC,/*wItemLength: Total length of Report descriptor*/
    0x00,
    /******************** Descriptor of Keyboard Mouse endpoint ********************/
    /* 27 */
    0x07,          /*bLength: Endpoint Descriptor size*/
    USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/

    0x81,          /*bEndpointAddress: Endpoint Address (IN)*/
    0x03,          /*bmAttributes: Interrupt endpoint*/
    0x08,          /*wMaxPacketSize: 8 Byte max */
    0x00,
    0x20,          /*bInterval: Polling Interval (32 ms)*/
	/******************** Descriptor of Keyboard Mouse endpoint ********************/
    /* 34 */
    0x07,          /*bLength: Endpoint Descriptor size*/
    USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/

    0x01,          /*bEndpointAddress: Endpoint Address (OUT)*/
    0x03,          /*bmAttributes: Interrupt endpoint*/
    0x08,          /*wMaxPacketSize: 8 Byte max */
    0x00,
    0x20,          /*bInterval: Polling Interval (32 ms)*/
    /* 41 */
  };

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x6
USBwValue = 0x0300         03:String_descripotr 00:Index
USBwIndex = 0x00
USBwLength = 0xff

数据输出 
0x04  0x03  0x09  0x04 
const u8 Keyboard_StringLangID[KEYBOARD_SIZ_STRING_LANGID] =
  {
    KEYBOARD_SIZ_STRING_LANGID,
    USB_STRING_DESCRIPTOR_TYPE,
    0x09,
    0x04
  }
  ; /* LangID = 0x0409: U.S. English */

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x0302          03:String_descripotr 02:Index
USBwIndex = 0x0409
USBwLength = 0xff

数据输出 
0x20  0x03  0x48  0x00  0x41  0x00  0x49  0x00  0x59  
0x00  0x41  0x00  0x4e  0x00  0x47  0x00  0x20  0x00  
0xe6  0x89  0xa7  0x63  0x55  0x00  0x53  0x00  0x42  
0x00  0x2e  0x95  0xd8  0x76
//使用UNICODE编码
const u8 Keyboard_StringProduct[KEYBOARD_SIZ_STRING_PRODUCT] =
  {
    KEYBOARD_SIZ_STRING_PRODUCT,          /* bLength */
    USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
    'H', 0, 'A', 0, 'I', 0, 'Y', 0, 'A', 0, 'N', 0, 'G', 0,
    ' ', 0, 
	0XE6,0X89,//触
	0XA7,0X63,//控
	'U', 0,
	'S', 0, 
	'B', 0,
	0X2e,0X95,//键
	0Xd8,0X76,//盘 
  };


SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x0303          03:String_descripotr 03:Index
USBwIndex = 0x0409
USBwLength = 0xff

数据输出 
0x1a  0x03  0x30  0x00  0xff  0x00  0xda  0x00  0x05  
0x00  0x42  0x00  0x47  0x00  0x31  0x00  0x36  0x00  
0x39  0x00  0x65  0x00
u8 Keyboard_StringSerial[KEYBOARD_SIZ_STRING_SERIAL] =
  {
    KEYBOARD_SIZ_STRING_SERIAL,           /* bLength */
    USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
    'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0
  };  0x08  0x00  0x43  0x00  


SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x06            
USBwIndex = 0x00
USBwLength = 0xa

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x01
USBwIndex = 0x00
USBwLength = 0x12

数据输出 
0x12  0x01  0x00  0x02  0x00  0x00  0x00  0x40  0x83  
0x04  0x10  0x57  0x00  0x02  0x01  0x02  0x03  0x01  

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x02
USBwIndex = 0x00
USBwLength = 0x09

数据输出 
0x09  0x02  0x29  0x00  0x01  0x01  0x00  0xe0  0x32  

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x02
USBwIndex = 0x00
USBwLength = 0x29

数据输出 
0x09  0x02  0x29  0x00  0x01  0x01  0x00  0xe0  
0x32  0x09  0x04  0x00  0x00  0x02  0x03  0x01  
0x01  0x00  0x09  0x21  0x00  0x01  0x00  0x01  
0x22  0x3d  0x00  0x07  0x05  0x81  0x03  0x08  
0x00  0x20  0x07  0x05  0x01  0x03  0x08  0x00  
0x20  

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x00
USBbRequest = 0x09            set_configuration
USBwValue = 0x0001            select configuration
USBwIndex = 0x00              set current configuration = 0x01
USBwLength = 0x00

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x21       HID 
USBbRequest = 0x0a            set_idle
USBwValue = 0x00
USBwIndex = 0x00
USBwLength = 0x00

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x06
USBwIndex = 0x00
USBwLength = 0x0a

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x81      Interface_request
USBbRequest = 0x06           
USBwValue = 0x22             Report_descriptor
USBwIndex = 0x00
USBwLength = 0x7d

数据输出 
0x05  0x01  0x09  0x06  0xa1  0x01  0x05  0x07  
0x19  0xe0  0x29  0xe7  0x15  0x00  0x25  0x01  
0x95  0x08  0x75  0x01  0x81  0x02  0x95  0x01  
0x75  0x08  0x81  0x03  0x95  0x06  0x75  0x08  
0x25  0xff  0x19  0x00  0x29  0x65  0x81  0x00  
0x25  0x01  0x95  0x02  0x75  0x01  0x05  0x08  
0x19  0x01  0x29  0x02  0x91  0x02  0x95  0x01  
0x75  0x06  0x91  0x03  0xc0
const u8 Keyboard_ReportDescriptor[KEYBOARD_SIZ_REPORT_DESC] =
  {
	0x05, 0x01, // USAGE_PAGE (Generic Desktop)
	0x09, 0x06, // USAGE (Keyboard)
	0xa1, 0x01, // COLLECTION (Application)
	0x05, 0x07, //     USAGE_PAGE (Keyboard/Keypad)
	0x19, 0xe0, //     USAGE_MINIMUM (Keyboard LeftControl)
	0x29, 0xe7, //     USAGE_MAXIMUM (Keyboard Right GUI)
	0x15, 0x00, //     LOGICAL_MINIMUM (0)
	0x25, 0x01, //     LOGICAL_MAXIMUM (1)
	0x95, 0x08, //     REPORT_COUNT (8)
	0x75, 0x01, //     REPORT_SIZE (1)
	0x81, 0x02, //     INPUT (Data,Var,Abs)
	0x95, 0x01, //     REPORT_COUNT (1)
	0x75, 0x08, //     REPORT_SIZE (8)
	0x81, 0x03, //     INPUT (Cnst,Var,Abs)
	0x95, 0x06, //   REPORT_COUNT (6)
	0x75, 0x08, //   REPORT_SIZE (8)
	0x25, 0xFF, //   LOGICAL_MAXIMUM (255)
	0x19, 0x00, //   USAGE_MINIMUM (Reserved (no event indicated))
	0x29, 0x65, //   USAGE_MAXIMUM (Keyboard Application)
	0x81, 0x00, //     INPUT (Data,Ary,Abs)
	0x25, 0x01, //     LOGICAL_MAXIMUM (1)
	0x95, 0x02, //   REPORT_COUNT (2)
	0x75, 0x01, //   REPORT_SIZE (1)
	0x05, 0x08, //   USAGE_PAGE (LEDs)
	0x19, 0x01, //   USAGE_MINIMUM (Num Lock)
	0x29, 0x02, //   USAGE_MAXIMUM (Caps Lock)
	0x91, 0x02, //   OUTPUT (Data,Var,Abs)
	0x95, 0x01, //   REPORT_COUNT (1)
	0x75, 0x06, //   REPORT_SIZE (6)
	0x91, 0x03, //   OUTPUT (Cnst,Var,Abs)
	0xc0        // END_COLLECTION
  }
  ; /* Keyboard_ReportDescriptor */

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x0301
USBwIndex = 0x0409
USBwLength = 0xff

数据输出 
0x10  0x03  0x77  0x6d  0x0b  0x0d  0x35  0x75  
0x50  0x5b  0xe5  0x5d  0x5c  0x4f  0xa4  0x5b 


SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x0303
USBwIndex = 0x0409
USBwLength = 0xff

数据输出 
0x1a  0x03  0x30  0x00  0xff  0x00  0xda  0x00  
0x05  0x00  0x42  0x00  0x47  0x00  0x31  0x00  
0x36  0x00  0x39  0x00  0x65  0x00  0x08  0x00  
0x43  0x00


SetUp阶段......
Host 输入信息
USBbmRequestType = 0x21
USBbRequest = 0x0a
USBwValue = 0x00
USBwIndex = 0x00
USBwLength = 0x00

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x06
USBwIndex = 0x00
USBwLength = 0x0a

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x21
USBbRequest = 0x0a
USBwValue = 0x00
USBwIndex = 0x00
USBwLength = 0x00

SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x0301
USBwIndex = 0x0409
USBwLength = 0xff

数据输出 
0x10  0x03  0x77  0x6d  0x0b  0x0d  0x35  0x75  
0x50  0x5b  0xe5  0x5d  0x5c  0x4f  0xa4  0x5b


SetUp阶段......
Host 输入信息
USBbmRequestType = 0x80
USBbRequest = 0x06
USBwValue = 0x0303
USBwIndex = 0x0409
USBwLength = 0xff

数据输出 
0x1a  0x03  0x30  0x00  0xff  0x00  0xda  0x00  
0x05  0x00  0x42  0x00  0x47  0x00  0x31  0x00  
0x36  0x00  0x39  0x00  0x65  0x00  0x08  0x00  
0x43  0x00 


SetUp阶段......
Host 输入信息
USBbmRequestType = 0x21
USBbRequest = 0x0a
USBwValue = 0x00
USBwIndex = 0x00
USBwLength = 0x00

在usb_core.c文件中Endpoint0处理函数中增加代码,将USB主机与USB设备通讯的数据都通过串口打印出来,通过打印的数据来分析USB设备的枚举过程对理解程序很有帮助,能够更好的了解设备的枚举过程.建议多看一下usb_core.c文件,里面有详细的处理过程,对以后编写程序有帮助.

 

实验过程中,按照网上查找的资料更改usb_des.c文件中的报告描述符,反复试了几个版本都无法完成设备的枚举,后来在论坛中找到了一份描述符才能够完成设备的枚举,报告描述符在上面的代码中,有需要的请参考.

2. 模拟键盘发送数据

设备成功枚举后,就可以修改程序完成键盘数据的发送了.

本实验因使用2.8‘触摸屏,尺寸较小,因此每次只发送一个按键值,实现简单功能.

首先对Endpoint1进行设置.在usb_proc.c文件的Keyboard_Reset函数中增加Endpoint1接收地址等设置.如下,已标红色.

 


 
  1.  
    void Keyboard_Reset(void)
  2.  
    {
  3.  
    /* Set Keyboard_DEVICE as not configured */
  4.  
    pInformation->Current_Configuration = 0;
  5.  
    pInformation->Current_Interface = 0;/*the default Interface*/
  6.  
     
  7.  
    /* Current Feature initialization */
  8.  
    pInformation->Current_Feature = Keyboard_ConfigDescriptor[7];
  9.  
     
  10.  
    SetBTABLE(BTABLE_ADDRESS);
  11.  
     
  12.  
    /* Initialize Endpoint 0 */
  13.  
    SetEPType(ENDP0, EP_CONTROL);
  14.  
    SetEPTxStatus(ENDP0, EP_TX_STALL);
  15.  
    SetEPRxAddr(ENDP0, ENDP0_RXADDR);
  16.  
    SetEPTxAddr(ENDP0, ENDP0_TXADDR);
  17.  
    Clear_Status_Out(ENDP0);
  18.  
    SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  19.  
    SetEPRxValid(ENDP0);
  20.  
     
  21.  
    /* Initialize Endpoint 1 */
  22.  
    SetEPType(ENDP1, EP_INTERRUPT);
  23.  
    SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  24.  
    SetEPTxCount(ENDP1, 8);
  25.  
    //SetEPRxStatus(ENDP1, EP_RX_DIS);
  26.  
    SetEPTxStatus(ENDP1, EP_TX_NAK);
  27.  
     
  28.  
    SetEPRxAddr(ENDP1, ENDP1_RXADDR);
  29.  
    SetEPRxCount(ENDP1, 1);
  30.  
    SetEPRxStatus(ENDP1, EP_RX_VALID);
  31.  
     
  32.  
    bDeviceState = ATTACHED;
  33.  
     
  34.  
    /* Set this device to response on default address */
  35.  
    SetDeviceAddress(0);
  36.  
    }

编写键盘按键值发送函数.

 

 


 
  1.  
    const u8 Keyboard_Value[] = {0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x04, 0x27,     //1, 2, 3, 4, 5, 6, 7, 8, 9, a, 0,
  2.  
                     0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,      //b, c, d, e, f, g, h, i, j, k, l,
  3.  
                     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,              //m, n, o, p, q, r, s, t
  4.  
                     };
  5.  
    void Keyboard_Send(u8 keys)
  6.  
    {
  7.  
    u8 Keyboard_Buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  8.  
     
  9.  
    u8 i;
  10.  
     
  11.  
    i = 2;
  12.  
    if(keys)
  13.  
    {
  14.  
    Keyboard_Buffer[i] = Keyboard_Value[keys - 1];
  15.  
    i++;
  16.  
    }
  17.  
    if(keys != 0) flag = 1;
  18.  
    else flag = 0;
  19.  
    /*copy mouse position info in ENDP1 Tx Packet Memory Area*/
  20.  
    UserToPMABufferCopy(Keyboard_Buffer, GetEPTxAddr(ENDP1), 8);
  21.  
    /* enable endpoint for transmission */
  22.  
    SetEPTxValid(ENDP1);
  23.  
    }

最初时程序编译下载后,当有键按下时会一直发送同一按键值.上网查找资料后发现在没有接收到新的数据时PC会一直认为接收到上次数据,所以在发送完一个按键后需要发送 一包数据“00“(8个0x00)到PC,这样就不会误操作了.手边正好有一个Dell的USB键盘连接到电脑上使用USBlyzer软件抓取Dell键盘按键数据,当发送完一个按键后后面就给跟着发送一包 "00"(仅测试了单个按键发送的情况),所以在按键发送程序中增加标志位flag,当发送键值不为0时,flag置1,这样可以在发送完按键值后再发送一包数据"00".

 

按键发送处理如下:

 


 
  1.  
    if(key)
  2.  
    {
  3.  
    Keyboard_Send(key);
  4.  
    }
  5.  
    else
  6.  
    {
  7.  
    if(flag_sendok == 1) //判断是否发送完成
  8.  
    {
  9.  
    if(flag == 1) //发送了一包不为0x00的数据
  10.  
    {
  11.  
    Keyboard_Send(0); //不为0x00数据后发送0x00数据
  12.  
    flag = 0; //清除标志位
  13.  
    }
  14.  
    flag_sendok = 0;
  15.  
    }
  16.  
    }

按键值首先会写入USB Endpoint1的发送缓冲区中等待发送,当发送完成后会产生相应中断.如果在发送前缓冲区中的数据改变,则数据会被覆盖,所以必须等待上次数据发送完成后再向缓冲区内写入数据,故程序中使用flag_sendok标志位来标志数据是否发送成功.当发送成功后会在中断函数中置1.


 
  1.  
    if ((wEPVal & EP_CTR_TX) != 0)
  2.  
    {
  3.  
    /* clear int flag */
  4.  
    _ClearEP_CTR_TX(EPindex);
  5.  
     
  6.  
    /* call IN service function */
  7.  
    (*pEpInt_IN[EPindex-1])();
  8.  
    flag_sendok = 1;
  9.  
    } /* if((wEPVal & EP_CTR_TX) != 0) */

以上,便可实现USB_Keyboard简单功能.仅为最近学习USB的一点心得,和大家分享一下.
第一次发博客,而且关于USB的知识水平有限,有不对的地方欢迎大家指正!谢谢!

STM32F103C8 Serial(UART) to USB HID Keyboard Mouse 串口 转 USB键盘鼠标 (1) 使用Composite Device 组合(复合)设备 (1.1) 1个Device -> 1个 Configuation -> 2个Interfance (Keyboard & Mouse) (1.2) Keyboard Interfance -> HID (boot mode) -> 2个Endpoint(IN_0x81 & OUT_0x01) -> KeyboardReportDescriptor(不使用Report ID) (1.3) Mouse Interfance -> HID (boot mode) -> 1个Endpoint(IN_0x82) -> MouseReportDescriptor(不使用Report ID) (1.4) 使用HID boot模式, 不使用Report ID, 以便兼容在 计算器设定BIOS模式 中的操作 (2) 串口接收 命令 (2.1) UART协议: 115200, n, 8, 1 (2.2) 1帧发送字符串格式, 以 '{'开始; '}'结束; ','分隔. 共9个10进制数字 例如: {1,2,3,4,5,6,7,8,9} (2.3) 第9位 区分 Keyboard(64) 或是 Mouse(128) 命令 例如: {0,0,0,0,0,0,0,0,64} --- 发送Keyboard命令 {0,0,0,0,0,0,0,0,128} --- 发送Keyboard命令 (3) 发送Keyboard键盘命令时 : 第1~8位 分别如下 (3.1) 第1位 : Key_Release = 0x00, Left_Control = 0x01, Left_Shift = 0x02, Left_Alt = 0x04, Left_GUI = 0x08, Right_Control = 0x10, Right_Shift = 0x20, Right_Alt = 0x40, Right_GUI = 0x80, 例如: {8,0,0,0,0,0,0,0,64} --- 发送 Win_Key键 {128,0,0,0,0,0,0,0,64} --- 发送 WinApp_Key键 {32,0,0,0,0,0,0,0,64} --- 发送 右Shift键 (3.2) 第2位 : 保留,不使用,一律填0 (3.3) 第3~8位 : 可以同时发送6个Keyboard按键 例如: {0,0,4,5,6,7,8,9,64} --- 发送 'abcdef'键 {2,0,4,5,6,7,8,9,64} --- 按住 左Shift 发送 'abcdef'键 => 'ABCDEF' {0,0,0,5,0,7,0,9,64} --- 发送 'bdf'键 (0表示 无按键) 按键码 可参阅: (HID Usage ID) http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf https://www.hiemalis.org/~keiji/PC/scancode-translate.pdf https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2 http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (4) 发送Mouse鼠标命令时 : 第1~8位 分别如下 (4.1) 第1位 : Button_Release = 0x00, Left_Button = 0x01, Right_Button = 0x02, Mid_Button = 0x04, 例如: {1,0,0,0,0,0,0,0,128} --- 点击 左键 {2,0,0,0,0,0,0,0,128} --- 点击 右键 {4,0,0,0,0,0,0,0,128} --- 点击 中键 (4.2) 第2~4位 : 移动(X,Y), 滚轮(Wheel) X: -127~127:左右移动鼠标 Y: -127~127:上下移动鼠标 Wheel: -127~127:上下转动滚轮 例如: {0,20,-10,0,0,0,0,0,128} --- 鼠标 右移20,上移10 {0,0,0,-30,0,0,0,0,128} --- 滚轮-30 (4.2) 第5~8位 : 保留,不使用,一律填0
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值