首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32 HID键盘

STM32 HID键盘
EN

Stack Overflow用户
提问于 2022-04-12 18:55:14
回答 1查看 468关注 0票数 3

我正在尝试使用和STM32F0-迪斯科作为键盘的Windows PC。我对正在印刷的人物有意见。

下面的代码等待直到按下星上按钮,然后应该打印这三个字符一次。

代码语言:javascript
复制
    /* 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之类的功能。我把键盘描述符放在下面。

代码语言:javascript
复制
    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

有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2022-04-13 08:41:49

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

因此,您需要为每个键发送一个单独的输出报告。在上一次报告之后,您需要发送另一个空的报告(包含所有的0),以指示密钥已经释放(正如您已经在做的那样)。在同一键的两个按键之间也需要这样一个额外的报告。

连续插入键的原因表明没有收到空报告。尽管函数使用术语发送(USBD_HID_SendReport()),但USB协议的工作方式是主机需要获取输入报告。因为它是一个USB中断端点,所以这种情况经常发生。如果还没有收到报告,USBD_HID_SendReport()什么也不做。它甚至不返回错误。

虽然查询轮询间隔(USBD_HID_GetPollingInterval())一开始看起来还可以,但它是在USB端点描述符中声明的轮询间隔。但是,Windows只支持几个间隔值,并舍入到下一个受支持的值。所以你必须增加价值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71847789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档