HID(Human Interface Device)即人机接口设备,是指能够通过USB、PS/2等接口进行传输的输入和输出设备,如键盘、鼠标、游戏手柄、扫描仪等。
一、HID设备通讯协议
HID设备通讯协议有两种,分别是HID Boot Protocol和HID Report Protocol。其中HID Boot Protocol是一种通用协议,可用于交换所有HID设备的数据,但是它不支持多个并发数据输入输出;而HID Report Protocol是一种自定义协议,不同的HID设备可以使用不同格式的报告描述符和报告协议来进行数据传输,并支持多个并发数据输入输出。
HID Boot Protocol的报告描述符如下所示:
// HID Boot Protocol Report Descriptor 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x02, // Usage (Mouse) 0xA1, 0x01, // Collection (Application) 0x09, 0x01, // Usage (Pointer) 0xA1, 0x00, // Collection (Physical) 0x05, 0x09, // Usage Page (Button) 0x19, 0x01, // Usage Minimum (01) 0x29, 0x03, // Usage Maximum (03) 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, 0x01, // Input (Cnst,Ary,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
而HID Report Protocol的报告描述符,则是根据HID设备的具体情况而定,下面以鼠标为例,列出其报告描述符:
// Mouse HID Report Descriptor 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x02, // USAGE (Mouse) 0xA1, 0x01, // COLLECTION (Application) 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, 0x01, // INPUT (Constant) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) 0x09, 0x38, // USAGE (Wheel) 0x15, 0x81, // LOGICAL_MINIMUM (-127) 0x25, 0x7F, // LOGICAL_MAXIMUM (127) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x03, // REPORT_COUNT (3) 0x81, 0x06, // INPUT (Data,Var,Rel) 0xC0, // END_COLLECTION 0xC0 // END_COLLECTION
二、HID设备驱动程序
HID设备需要特定的驱动程序才能被计算机识别和使用。通常情况下,Windows操作系统内置了很多常见的HID设备驱动程序,可直接使用。而对于某些不常见的HID设备,则需要手动安装其对应的驱动程序。
三、HID设备数据传输
HID设备的数据传输主要是通过输入报告和输出报告进行的。
输入报告是指从HID设备向计算机发送数据的报告,一般用于传输HID设备的输入信号,如键盘的按键、鼠标的位置等信息。输出报告则是指从计算机向HID设备发送数据的报告,一般用于传输HID设备的输出信号,如LED灯的亮度和颜色等信息。
下面是一个使用WINAPI函数来进行HID设备输入输出的例子:
// WinHidIO.c - Windows HID I/O test program #include #include #include const UINT32 g_OutReportSize = 16; const UINT32 g_InReportSize = 16; HANDLE g_hDev = NULL; BYTE g_OutBuf[g_OutReportSize]; BYTE g_InBuf[g_InReportSize]; BOOL OpenDevice() { GUID guid; HDEVINFO hdevInfo; SP_DEVICE_INTERFACE_DATA ifaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA detailData; // Get the HID GUID class if (!SetupDiClassGuidsFromName(TEXT("HIDClass"), &guid, 1, NULL)) return FALSE; // Get devices matching HID GUID class hdevInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hdevInfo == INVALID_HANDLE_VALUE) return FALSE; // Enumerate all devices ifaceData.cbSize = sizeof(ifaceData); detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH); detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); for (DWORD i = 0; SetupDiEnumDeviceInterfaces(hdevInfo, NULL, &guid, i, &ifaceData); ++i) { DWORD dwSize = 0; BOOL bRet = SetupDiGetDeviceInterfaceDetail(hdevInfo, &ifaceData, detailData, sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH, &dwSize, NULL); if (bRet) { // Open HID device with read/write access g_hDev = CreateFile(detailData->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (g_hDev != INVALID_HANDLE_VALUE) { // Set feature report HIDD_ATTRIBUTES attr; ATTR_AND_STRING as[] = {{&attr.ProductID, 0, 0}, {&attr.VendorID, 0, 0}}; HidD_GetAttributes(g_hDev, &attr); printf("Found HID device (vid=%04X, pid=%04X)\n", attr.VendorID, attr.ProductID); // Write output report bRet = HidD_SetOutputReport(g_hDev, g_OutBuf, g_OutReportSize); if (bRet) { // Read input report memset(g_InBuf, 0, g_InReportSize); bRet = HidD_GetInputReport(g_hDev, g_InBuf, g_InReportSize); if (bRet) { // Process input report data for (UINT32 j = 0; j < g_InReportSize; ++j) printf("InBuf[%d] = %02X\n", j, g_InBuf[j]); } } CloseHandle(g_hDev); g_hDev = NULL; } } } free(detailData); SetupDiDestroyDeviceInfoList(hdevInfo); return TRUE; } int main() { // Fill output report buffer memset(g_OutBuf, 0, g_OutReportSize); g_OutBuf[0] = 0x01; // Open HID device and perform I/O operations if (OpenDevice()) printf("Test completed successfully\n"); return 0; }
四、HID设备应用场景
HID设备可以广泛应用于各种交互式设备上,如电脑、手机、平板等。下面是一些常见的应用场景:
1.键盘和鼠标
键盘和鼠标是最常见的HID设备之一,可以用于输入文字、控制光标等操作。
2.游戏手柄和方向盘
游戏手柄和方向盘是常见的游戏控制器,可以实现游戏中的各种操作,如移动、跳跃、射击等。
3.触摸屏
触摸屏可以用于移动设备上的交互,如点击、滑动、缩放等操作。
4.扫描仪
扫描仪可以用于将文档或图片数字化,便于存储和传输。
5.电视遥控器
电视遥控器可以通过HID设备来实现对电视的遥控操作,包括调节音量、切换频道等。
五、总结
HID设备是一种重要的人机接口设备,其通讯协议、驱动程序、数据传输等方面都需要进行详细的了解和应用。常见的HID设备包括键盘、鼠标、游戏手柄、触摸屏、扫描仪、电视遥控器等。通过对HID设备的应用,可以实现各种交互性设备操作,方便用户的使用。
原创文章,作者:DPEUM,如若转载,请注明出处:https://www.506064.com/n/332716.html