基于STM32CUBE的USB键盘例程.docx

嵌入式ARM 2020-05-04 00:00

前面说了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键盘对主机来说,不光有输入,还有输出。所以,增加的这部分端点描述符,用来描述输出。

/******************** 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文件如下:

__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文件中,添加头文件,并定义相关的数组:

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

 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文档,看键盘自动输出字母,爽不爽?


8


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


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

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

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

端点个数,由1变成2.

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

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

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

好了,继续!

跟USB键盘的部分一样,配置集合最下面,增加一个输出端点的描述符:

/******************** 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文件了。


第五,添加头文件,并定义相关的数组。


/* 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秒触发一下。

 /* 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秒被触发一下。


本文授权转载自公众号“单片机爱好者”,作者MCU启航

嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-12 10:13 40浏览
  • 天问Block和Mixly是两个不同的编程工具,分别在单片机开发和教育编程领域有各自的应用。以下是对它们的详细比较: 基本定义 天问Block:天问Block是一个基于区块链技术的数字身份验证和数据交换平台。它的目标是为用户提供一个安全、去中心化、可信任的数字身份验证和数据交换解决方案。 Mixly:Mixly是一款由北京师范大学教育学部创客教育实验室开发的图形化编程软件,旨在为初学者提供一个易于学习和使用的Arduino编程环境。 主要功能 天问Block:支持STC全系列8位单片机,32位
    丙丁先生 2024-12-11 13:15 63浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-11 17:58 86浏览
  • 全球智能电视时代来临这年头若是消费者想随意地从各个通路中选购电视时,不难发现目前市场上的产品都已是具有智能联网功能的智能电视了,可以宣告智能电视的普及时代已到临!Google从2021年开始大力推广Google TV(即原Android TV的升级版),其他各大品牌商也都跟进推出搭载Google TV操作系统的机种,除了Google TV外,LG、Samsung、Panasonic等大厂牌也开发出自家的智能电视平台,可以看出各家业者都一致地看好这块大饼。智能电视的Wi-Fi连线怎么消失了?智能电
    百佳泰测试实验室 2024-12-12 17:33 53浏览
  • 近日,搭载紫光展锐W517芯片平台的INMO GO2由影目科技正式推出。作为全球首款专为商务场景设计的智能翻译眼镜,INMO GO2 以“快、准、稳”三大核心优势,突破传统翻译产品局限,为全球商务人士带来高效、自然、稳定的跨语言交流体验。 INMO GO2内置的W517芯片,是紫光展锐4G旗舰级智能穿戴平台,采用四核处理器,具有高性能、低功耗的优势,内置超微高集成技术,采用先进工艺,计算能力相比同档位竞品提升4倍,强大的性能提供更加多样化的应用场景。【视频见P盘链接】 依托“
    紫光展锐 2024-12-11 11:50 72浏览
  • 首先在gitee上打个广告:ad5d2f3b647444a88b6f7f9555fd681f.mp4 · 丙丁先生/香河英茂工作室中国 - Gitee.com丙丁先生 (mr-bingding) - Gitee.com2024年对我来说是充满挑战和机遇的一年。在这一年里,我不仅进行了多个开发板的测评,还尝试了多种不同的项目和技术。今天,我想分享一下这一年的故事,希望能给大家带来一些启发和乐趣。 年初的时候,我开始对各种开发板进行测评。从STM32WBA55CG到瑞萨、平头哥和平海的开发板,我都
    丙丁先生 2024-12-11 20:14 73浏览
  • 一、SAE J1939协议概述SAE J1939协议是由美国汽车工程师协会(SAE,Society of Automotive Engineers)定义的一种用于重型车辆和工业设备中的通信协议,主要应用于车辆和设备之间的实时数据交换。J1939基于CAN(Controller Area Network)总线技术,使用29bit的扩展标识符和扩展数据帧,CAN通信速率为250Kbps,用于车载电子控制单元(ECU)之间的通信和控制。小北同学在之前也对J1939协议做过扫盲科普【科普系列】SAE J
    北汇信息 2024-12-11 15:45 112浏览
  • 本文介绍瑞芯微RK3588主板/开发板Android12系统下,APK签名文件生成方法。触觉智能EVB3588开发板演示,搭载了瑞芯微RK3588芯片,该开发板是核心板加底板设计,音视频接口、通信接口等各类接口一应俱全,可帮助企业提高产品开发效率,缩短上市时间,降低成本和设计风险。工具准备下载Keytool-ImportKeyPair工具在源码:build/target/product/security/系统初始签名文件目录中,将以下三个文件拷贝出来:platform.pem;platform.
    Industio_触觉智能 2024-12-12 10:27 62浏览
  • 应用环境与极具挑战性的测试需求在服务器制造领域里,系统整合测试(System Integration Test;SIT)是确保产品质量和性能的关键步骤。随着服务器系统的复杂性不断提升,包括:多种硬件组件、操作系统、虚拟化平台以及各种应用程序和服务的整合,服务器制造商面临着更有挑战性的测试需求。这些挑战主要体现在以下五个方面:1. 硬件和软件的高度整合:现代服务器通常包括多个处理器、内存模块、储存设备和网络接口。这些硬件组件必须与操作系统及应用软件无缝整合。SIT测试可以帮助制造商确保这些不同组件
    百佳泰测试实验室 2024-12-12 17:45 53浏览
  • 时源芯微——RE超标整机定位与解决详细流程一、 初步测量与问题确认使用专业的电磁辐射测量设备,对整机的辐射发射进行精确测量。确认是否存在RE超标问题,并记录超标频段和幅度。二、电缆检查与处理若存在信号电缆:步骤一:拔掉所有信号电缆,仅保留电源线,再次测量整机的辐射发射。若测量合格:判定问题出在信号电缆上,可能是电缆的共模电流导致。逐一连接信号电缆,每次连接后测量,定位具体哪根电缆或接口导致超标。对问题电缆进行处理,如加共模扼流圈、滤波器,或优化电缆布局和屏蔽。重新连接所有电缆,再次测量
    时源芯微 2024-12-11 17:11 109浏览
  • RK3506 是瑞芯微推出的MPU产品,芯片制程为22nm,定位于轻量级、低成本解决方案。该MPU具有低功耗、外设接口丰富、实时性高的特点,适合用多种工商业场景。本文将基于RK3506的设计特点,为大家分析其应用场景。RK3506核心板主要分为三个型号,各型号间的区别如下图:​图 1  RK3506核心板处理器型号场景1:显示HMIRK3506核心板显示接口支持RGB、MIPI、QSPI输出,且支持2D图形加速,轻松运行QT、LVGL等GUI,最快3S内开
    万象奥科 2024-12-11 15:42 88浏览
  • 铁氧体芯片是一种基于铁氧体磁性材料制成的芯片,在通信、传感器、储能等领域有着广泛的应用。铁氧体磁性材料能够通过外加磁场调控其导电性质和反射性质,因此在信号处理和传感器技术方面有着独特的优势。以下是对半导体划片机在铁氧体划切领域应用的详细阐述: 一、半导体划片机的工作原理与特点半导体划片机是一种使用刀片或通过激光等方式高精度切割被加工物的装置,是半导体后道封测中晶圆切割和WLP切割环节的关键设备。它结合了水气电、空气静压高速主轴、精密机械传动、传感器及自动化控制等先进技术,具有高精度、高
    博捷芯划片机 2024-12-12 09:16 85浏览
  • 在智能化技术快速发展当下,图像数据的采集与处理逐渐成为自动驾驶、工业等领域的一项关键技术。高质量的图像数据采集与算法集成测试都是确保系统性能和可靠性的关键。随着技术的不断进步,对于图像数据的采集、处理和分析的需求日益增长,这不仅要求我们拥有高性能的相机硬件,还要求我们能够高效地集成和测试各种算法。我们探索了一种多源相机数据采集与算法集成测试方案,能够满足不同应用场景下对图像采集和算法测试的多样化需求,确保数据的准确性和算法的有效性。一、相机组成相机一般由镜头(Lens),图像传感器(Image
    康谋 2024-12-12 09:45 75浏览
  • 全球知名半导体制造商ROHM Co., Ltd.(以下简称“罗姆”)宣布与Taiwan Semiconductor Manufacturing Company Limited(以下简称“台积公司”)就车载氮化镓功率器件的开发和量产事宜建立战略合作伙伴关系。通过该合作关系,双方将致力于将罗姆的氮化镓器件开发技术与台积公司业界先进的GaN-on-Silicon工艺技术优势结合起来,满足市场对高耐压和高频特性优异的功率元器件日益增长的需求。氮化镓功率器件目前主要被用于AC适配器和服务器电源等消费电子和
    电子资讯报 2024-12-10 17:09 99浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦