- uint8_t USBD_HIDReportDesc[USBD_HID_MOUSE_REPORT_DESC_SIZE] =
- {
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x06, // USAGE (Keyboard)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x85, 0x01, // REPORT_ID (1)
- 0x05, 0x07, // USAGE_PAGE (Keyboard)
- 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
- 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x01, // LOGICAL_MAXIMUM (1)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x95, 0x08, // REPORT_COUNT (8)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x81, 0x03, // INPUT (Cnst,Var,Abs)
- 0x95, 0x05, // REPORT_COUNT (5)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x05, 0x08, // USAGE_PAGE (LEDs)
- 0x19, 0x01, // USAGE_MINIMUM (Num Lock)
- 0x29, 0x05, // USAGE_MAXIMUM (Kana)
- 0x91, 0x02, // OUTPUT (Data,Var,Abs)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x75, 0x03, // REPORT_SIZE (3)
- 0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
- 0x95, 0x06, // REPORT_COUNT (6)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x65, // LOGICAL_MAXIMUM (101)
- 0x05, 0x07, // USAGE_PAGE (Keyboard)
- 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
- 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
- 0x81, 0x00, // INPUT (Data,Ary,Abs)
- 0xc0, // END_COLLECTION
-
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x02, // USAGE (Mouse)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x85, 0x02, // REPORT_ID (2)
- 0x09, 0x01, // USAGE (Pointer)
- 0xa1, 0x00, // COLLECTION (Physical)
- 0x05, 0x09, // USAGE_PAGE (Button)
- 0x19, 0x01, // USAGE_MINIMUM (Button 1)
- 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x01, // LOGICAL_MAXIMUM (1)
- 0x95, 0x03, // REPORT_COUNT (3)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x81, 0x02, // INPUT (Data,Var,Abs)
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x75, 0x05, // REPORT_SIZE (5)
- 0x81, 0x03, // INPUT (Cnst,Var,Abs)
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x30, // USAGE (X)
- 0x09, 0x31, // USAGE (Y)
- 0x15, 0x81, // LOGICAL_MINIMUM (-127)
- 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x95, 0x02, // REPORT_COUNT (2)
- 0x81, 0x06, // INPUT (Data,Var,Rel)
- 0xc0, // END_COLLECTION
- 0xc0 // END_COLLECTION
- };
这样,我们USB键盘+鼠标二合一就改好了, 那么需要怎么使用呢?
第三、鼠标和键盘的使用属性简单介绍:
1、Mouse 鼠标:
我们用的鼠标主要就四个属性:键位(左键、右键、中键),左右移动、上下移动、滑轮
第 1 个字节(buff[0]):按钮状态 0x01左键 0x02右键 0x04中键(滚轮按钮)
第 2 个字节(buff[1]):X 轴移动量
第 3 个字节(buff[2]):Y 轴移动量
第 4 个字节(buff[3]):滚轮移动量 0x01表示滚轮向前滚动一格;0xFF表示滚轮向后滚动一格;0x80是个中间值,不滚动。
以下是一个简单的鼠标使用发送函数示例:
- void HidMouse_Write(uint8_t key)
- {
- int8_t x = 0;
- int8_t y = 0;
-
- int8_t Button = 0;
- int8_t Wheel = 0;
-
- uint8_t buffer[4] = {0, 0, 0, 0};
- switch (key)
- {
- case HID_MOUSE_KEY_LEFT:
- x -= 10;
- break;
- case HID_MOUSE_KEY_RIGHT:
- x += 10;
- break;
- case HID_MOUSE_KEY_UP:
- y -= 10;
- break;
- case HID_MOUSE_KEY_DOWN:
- y += 10;
- break;
- case HID_MOUSE_BUTTON:
- Button = 0x01; //0x01左键 0x02右键 0x04中键(滚轮按钮)
- break;
-
- case HID_MOUSE_WHEEL:
- Wheel = 0xff; //0x01表示滚轮向前滚动一格;0xFF表示滚轮向后滚动一格;0x80是个中间值,不滚动。
- break;
- default:
- return;
- }
- buffer[0] = Button;
- buffer[1] = x;
- buffer[2] = y;
- buffer[3] = Wheel;
-
- s_statusEP = 0;
- USBD_TxData(USBD_EP_1, buffer, sizeof(buffer));
- }
2、Keyboard 键盘:
在键盘 HID 报告格式中,每个字节代表不同的含义:
第 1 个字节(buff[0]) 修饰键的状态(如 Ctrl、Alt、Shift 等)。
0x01 表示左 Ctrl 按下。
0x02 表示左 Shift 按下。
0x04 表示左 Alt 按下。
依此类推。
第 2 个字节(buff[1]):保留字节,通常为 0,不使用。
第 3 到第 8 个字节(buff[2] - buff[7]):按键代码,最多可以同时报告 6 个按键。
例如:
0x04 表示字母 'A' 键。
0x05 表示字母 'B' 键。
依此类推。
以下是一个简单的键盘使用发送函数示例:A-Z
- void USB_DevUserApplication(void)
- {
- static uint8_t userAppState = USER_APP_INIT;
- static uint8_t interval = 0;
- static uint8_t report[8] = { 0 };
- static uint8_t i = 4;
- switch (userAppState)
- {
- case USER_APP_INIT:
- interval = USBD_CUSTOM_HID_ReadInterval(&gUsbDeviceFS);
- report[0] = 0;
- report[1] = 0;
- report[2] = 0;
- report[3] = 0;
- userAppState = USER_APP_RUN;
- break;
- case USER_APP_RUN:
- if (!APM_MINI_PBGetState(BUTTON_KEY1))
- {
- APM_DelayMs(10);
- if (!APM_MINI_PBGetState(BUTTON_KEY1))
- {
- if(i > 29)
- {
- i = 4;
- report[2] = KEYBOARD_ENTER;
- USBD_CUSTOM_HID_TxReport(&gUsbDeviceFS, (uint8_t*)report, 8);
- APM_DelayMs(20);
- report[2] = 0;
- USBD_CUSTOM_HID_TxReport(&gUsbDeviceFS, (uint8_t*)report, 8);
- APM_DelayMs(20);
- }
-
- report[2] = i;
- USBD_CUSTOM_HID_TxReport(&gUsbDeviceFS, (uint8_t*)report, 8);
-
- APM_DelayMs(20);
-
- report[2] = 0;
- USBD_CUSTOM_HID_TxReport(&gUsbDeviceFS, (uint8_t*)report, 8);
-
- i++;
-
- while(!APM_MINI_PBGetState(BUTTON_KEY1));
- }
- }
- APM_DelayMs(interval);
- break;
- }
- }
现在我们将它结合起来向USB主机发送数据的时候就需要做出改变了,现在的数组的第一个元素是报告ID,后面才是键盘数据或鼠标数据。
在上面的两个示例中,USB键盘我们定义了一个8元素的数组,USB鼠标我们定义了一个4元素的数组。
现在我们需要一个数组,在同一时间的时候只发送一种数据,再加上报告ID,所以变成9个.
以下是一个简单的键+鼠标使用发送函数示例
- void USB_DevUserApplication(void)
- {
- static uint8_t userAppState = USER_APP_INIT;
- static uint8_t interval = 0;
- uint8_t KeyBoard[9] = {1,0,0,0,0,0,0,0,0};
- uint8_t Mouse[9] = {2,0,0,0,0,0,0,0,0};
- static uint8_t i = 4;
- switch (userAppState)
- {
- case USER_APP_INIT:
- interval = USBD_HID_ReadInterval(&gUsbDeviceFS);
- KeyBoard[0] = 0;
- KeyBoard[1] = 0;
- KeyBoard[2] = 0;
- KeyBoard[3] = 0;
- userAppState = USER_APP_RUN;
- break;
- case USER_APP_RUN:
- if (!APM_MINI_PBGetState(BUTTON_KEY1))
- {
- APM_DelayMs(10);
- if (!APM_MINI_PBGetState(BUTTON_KEY1))
- {
- if(i > 29)
- {
- i = 4;
- KeyBoard[3] = KEYBOARD_ENTER;
- USBD_HID_TxReport(&gUsbDeviceFS, (uint8_t*)KeyBoard, sizeof(KeyBoard));
- APM_DelayMs(20);
- KeyBoard[3] = 0;
- USBD_HID_TxReport(&gUsbDeviceFS, (uint8_t*)KeyBoard, sizeof(KeyBoard));
- APM_DelayMs(20);
- }
- KeyBoard[3] = i;
- USBD_HID_TxReport(&gUsbDeviceFS, (uint8_t*)KeyBoard, sizeof(KeyBoard));
-
- APM_DelayMs(20);
-
- KeyBoard[3] = 0;
- USBD_HID_TxReport(&gUsbDeviceFS, (uint8_t*)KeyBoard, sizeof(KeyBoard));
-
- i++;
-
- while(!APM_MINI_PBGetState(BUTTON_KEY1));
- }
- }
- if (!APM_MINI_PBGetState(BUTTON_KEY2))
- {
- APM_DelayMs(10);
- if (!APM_MINI_PBGetState(BUTTON_KEY2))
- {
- Mouse[3] -= 10;
- USBD_HID_TxReport(&gUsbDeviceFS, (uint8_t*)Mouse, sizeof(Mouse));
- }
- }
- APM_DelayMs(interval);
- break;
- }
- }