STM32 HID键盘

3

我正在尝试将STM32F0-disco用作Windows PC的键盘。 我遇到了正在打印的字符问题。

以下代码将等待板载按钮被按下,然后应该打印三个字符。

    /* USER CODE BEGIN 2 */

USBDelay = USBD_HID_GetPollingInterval(&hUsbDeviceFS);
while (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 0);
if (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 1) {
    HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);


    buff[0] = 0x00;
    buff[2] = 0x04;
    buff[3] = 0x05;
    buff[4] = 0x06;
    USBD_HID_SendReport(&hUsbDeviceFS, buff, 8);
    HAL_Delay(USBDelay);

    buff[0] = 0x00;
    buff[2] = 0x00;
    buff[3] = 0x00;
    buff[4] = 0x00;

    USBD_HID_SendReport(&hUsbDeviceFS, buff, 8);
    HAL_GPIO_TogglePin(LD4_GPIO_Port, LD4_Pin);
    HAL_Delay(1000);
}
while (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 1);

/* USER CODE END 2 */

我遇到的问题是,缓冲区中仅有前两个关键位置的字符(这将是数组中第三和第四个元素,因为第一个元素是修改器,第二个元素是保留字)。此外,字符不断连续打印而不停止。
根据我添加的LED进行测试,我想要打印的字符直到第二个USB_SendReport后才会打印出来,该命令应该发送空白字符以停止打印。
我已经对usbd_hid.c和usbd_hid.h进行了必要的更改,还有时钟配置和启用USB等。下面是我的键盘描述符。
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
0x09, 0x06,                    // USAGE (Keyboard)
0xa1, 0x01,                    // COLLECTION (Application)
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

有什么想法吗?

1个回答

2

USB HID协议的工作方式与您预期的不同。如果输入报告包含多个按下的键,主机(您的Windows PC)会假设它们同时被按下。因此它们可以以任何顺序插入。这也可能是第三个键未被插入的原因。

因此,您需要为每个键发送单独的输出报告。在最后一个报告之后,您需要发送另一个空报告(全部为0),以指示键已被释放(正如您已经在做的那样)。在相同键的两次按下之间还需要这样的附加报告。

连续插入按键的原因表明尚未收到空报告。尽管函数使用了术语sendUSBD_HID_SendReport()),但USB协议的工作方式是主机需要接收输入报告。由于它是USB中断端点,这仅会发生很少的时间。如果尚未接收报告,则USBD_HID_SendReport()不起作用。它甚至不返回错误。

虽然查询轮询间隔(USBD_HID_GetPollingInterval())乍一看不错,但它是在USB端点描述符中声明的轮询间隔。但是,Windows仅支持几个间隔值,并向上取整到下一个支持的值。因此,您必须增加该值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接