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

基于STM32CUBE的USB鼠标键盘二合一

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

看来你们对USB兴趣一般,所以这次我把它放在次条。感兴趣的就看一眼,没兴趣的就算了。

前面两篇文章分别说了如何实现基于STM32的USB鼠标基于STM32的USB键盘。这篇文章,我们试着同时在一个USB设备上,实现USB的鼠标与键盘二合一。花一份的钱,实现两样东西,它不香吗?

这里要说一下,实现鼠标键盘二合一的功能,方法有多种,这里只说其中一种。

少废话,开始干!

首先,在5.3.0版本的STM32CubeMX上选择STM32F103C8T6芯片。具体操作和USB鼠标的操作一样,这里就不重复了。

同理,VID和PID要和之前的设备不一样。设置完成以后,直接生成工程。

第二,修改usbd_hid.c中的配置集合(USBD_HID_CfgFSDesc)。如下图所示,框住的地方是个宏定义。配置集合的长度,由之前的34,变为41.

端点个数,由1变成2.

接口协议,由2(鼠标)变成1(键盘)。

有的小伙伴会奇怪,我们不是鼠标键盘二合一吗?怎么还是键盘?

作为一个技术人员,我们要学会透过现象看本质。虽然表明上是鼠标与键盘二合一,但实际上是以键盘功能为主,而鼠标以一个附属功能加入到了键盘里。所以,这里虽然选的是键盘,但最终的效果是键盘鼠标功能都有。

好了,继续!

跟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 */

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

之前这里是鼠标的报告描述符,长度有74.现在变成了117.

为什么是117?

看下文!

第四,修改报告描述符。STM32CubeMX工具自动生成的工程里,报告描述符是鼠标的。现在我们要实现的是键盘与鼠标二合一,要修改的核心位置就是报告描述符这里。

简单来说,就是把前面两个例程中的报告描述符合二为一。一个数组里面,上面放键盘的报告描述符,下面放鼠标的报告描述符。

这样的话,对USB主机(也就是电脑)来说,它收到的数据,有可能是鼠标的数据,也有可能是键盘的数据。那,怎么区分?

方法就是分别在键盘与鼠标的报告描述符中放一个报告ID,键盘的报告ID是1,鼠标的报告ID是2. 两个报告描述符,一个长65,一个长62,加起来117.

向USB主机发送数据的时候,数组的第一个元素是报告ID,后面才是键盘数据或鼠标数据。实现前面两节的例程的时候,USB键盘我们定义了一个8元素的数组,USB鼠标我们定义了一个4元素的数组。现在我们只需要一个数组,它同一时间,只发送一种数据,所以大小为8,然后,还要包含报告ID,所以变成9.

在USB协议中,报告ID默认是数组的第一个元素。明白了这一点,我们可以去修改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[9] = {1,0,0,4,0,0,0,0,0};
uint8_t KeyBoard01[9] = {1,0,0,0,0,0,0,0,0};
uint8_t Mouse[9] = {2,0,0,0,0,0,0,0,0};
extern USBD_HandleTypeDef hUsbDeviceFS;

KeyBoard 数组第一个元素是1,Mouse 数组第一个元素是2,这两个值分别对应键盘和鼠标的报告ID。KeyBoard01这个数组是为了表示键盘没有被按下的状态。

第六,修改主函数。循环输出a到z字母,同时,鼠标左键每隔1秒触发一下。

代码语言:javascript
复制
   /* USER CODE BEGIN 3 */
    if(KeyBoard[3] >= 29)
    {
      KeyBoard[3] = 4;
    }
    else
    {
      KeyBoard[3]++;
    }
    USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&KeyBoard01,sizeof(KeyBoard));
    HAL_Delay(15);
    USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&KeyBoard,sizeof(KeyBoard));
    HAL_Delay(15);
    USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&KeyBoard01,sizeof(KeyBoard));
    HAL_Delay(1000);

    Mouse[1] = 0x01;
    USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&Mouse,sizeof(Mouse));
    HAL_Delay(1000);
    Mouse[1] = 0x00;
    USBD_HID_SendReport(&hUsbDeviceFS,(uint8_t*)&Mouse,sizeof(Mouse));
    HAL_Delay(1000);

最后,保存、编译、下载、上电!新建一个TXT文档,可以看到字母自动输出,同时鼠标左键每隔1秒被触发一下。

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

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

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

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

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

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