前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于STM32CUBE的USB键盘例程.docx

基于STM32CUBE的USB键盘例程.docx

作者头像
MCU起航
发布2020-06-29 15:33:30
6500
发布2020-06-29 15:33:30
举报
文章被收录于专栏:单片机爱好者单片机爱好者

前面说了USB鼠标,这次趁热打铁,说一下USB键盘。依然只说如何修改,不说背后的原理。原因你懂的,涉及的知识点太多了。

会不会写成USB三部曲? 不知道

猜猜我下一步再写个啥?

1

生成工程

首先,STM32CubeMX的配置部分不说了,和USB鼠标部分的一样。唯一需要注意的一点是,VID和PID这两个值要改一下,否则主机(也就是电脑)会以为你还是鼠标。

2

修改usbd_hid.c文件

其次,生成工程后打开,修改usbd_hid.c文件。配置集合(USBD_HID_CfgFSDesc)要做一些改动,首先是长度:

这是个宏定义,之前是34,现在变成41.

然后是端点数,之前是1,现在改成2.

接着是接口协议,之前是2(鼠标),现在改成1(键盘)。

再接着是报告描述符长度:

之前是:HID_MOUSE_REPORT_DESC_SIZE,长度是74,现在改成:

HID_KEYBOARD_REPORT_DESC_SIZE,长度63.

还有就是端点每次发送的数据包长度:

之前是4,不够用了,现在改成16.

最后配置集合中增加一部分端点描述符,因为USB键盘对主机来说,不光有输入,还有输出。所以,增加的这部分端点描述符,用来描述输出。

代码语言:javascript
复制
/******************** Descriptor of Mouse Output endpoint ********************/
  0x07,          /*bLength: Endpoint Descriptor size*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
  0x01,
  0x03,          /*bmAttributes: Interrupt endpoint*/
  0x10,
  0x00,
  HID_FS_BINTERVAL,          /*bInterval: Polling Interval */

3

修改HID描述符

修改HID描述符中的报告描述符长度:

上面提到了,之前是鼠标描述符,长度74,现在改成键盘描述符,长度63.

4

生成键盘的报告描述符

把USB鼠标的报告描述符删掉,换成USB键盘的报告描述符。

不会写USB键盘的报告描述符怎么办?

USB官方提供了一个USB报告描述符自动配置的工具,打开!里面有各种例程,我们直接复制一个USB键盘的报告描述符即可。

生成.h文件如下:

代码语言:javascript
复制
__ALIGN_BEGIN static uint8_t HID_KEYBOARD_ReportDesc[HID_KEYBOARD_REPORT_DESC_SIZE]  __ALIGN_END =
{
    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
};

5

修改函数USBD_HID_Setup

第五,函数USBD_HID_Setup中,需要修改一部分代码:

获取报告描述符的部分,之前这里是鼠标的报告描述符信息,现在换成了键盘的。

6

修改main.c文件

main.c文件中,添加头文件,并定义相关的数组:

代码语言:javascript
复制
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usbd_hid.h"
/* USER CODE END Includes */


/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint8_t KeyBoard[8] = {0,0,4,0,0,0,0,0};
uint8_t KeyBoard01[8] = {0,0,0,0,0,0,0,0};
extern USBD_HandleTypeDef hUsbDeviceFS;

7

修改主函数

第七,主函数中循环发送英文字母A~Z。

代码语言:javascript
复制
 while (1)
  {
    /* USER CODE END WHILE */


    /* USER CODE BEGIN 3 */
    if(KeyBoard[2] >= 29)
    {
      KeyBoard[2] = 4;
    }
    else
    {
      KeyBoard[2]++;
    }
    USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&KeyBoard01,sizeof(KeyBoard));
    HAL_Delay(15);
    USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&KeyBoard,sizeof(KeyBoard01));
    HAL_Delay(15);
    USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&KeyBoard01,sizeof(KeyBoard));
    HAL_Delay(1000);
  }

为什么4~29对应英文字母A~Z?

USB官网的文件hut1_12v2中,对键盘的每个按键对应的值,都有一个详细的定义,看第53页,我这里截一部分图:

最后,保存、编译、下载、上电!新建一个TXT文档,看键盘自动输出字母,爽不爽?

完整的工程源码,我上传到了网盘,公众号后台回复关键词:USB键盘,即可获得下载链接。

有想做游戏辅助的童鞋,可以研究下~~~

打完收工!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 单片机爱好者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档