STM32CubeMX学习笔记(44)——USB接口使用(HID按键)

发布者:BlissfulBliss最新更新时间:2025-02-11 来源: jianshu关键字:STM32CubeMX  USB接口 手机看文章 扫描二维码
随时随地手机看文章

一、USB简介

USB(Universal Serial BUS)通用串行总线,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯。是应用在 PC 领域的接口技术。USB 接口支持设备的即插即用和热插拔功能。USB 是在 1994 年底由英特尔、康柏、IBM、Microsoft 等多家公司联合提出的。

USB 发展到现在已经有 USB1.0/1.1/2.0/3.0 等多个版本。目前用的最多的就是 USB1.1 和 USB2.0,USB3.0 目前已经开始普及。STM32F103 自带的 USB 符合 USB2.0 规范,不过 STM32F103 的 USB 都只能用来做设备,而不能用作主机。

标准 USB 共四根线组成,除 VCC/GND 外,另外为 D+,D-; 这两根数据线采用的是差分电压的方式进行数据传输的。在 USB 主机上,D-和 D+都是接了 15K 的电阻到低的,所以在没有设备接入的时候,D+、D-均是低电平。而在 USB 设备中,如果是高速设备,则会在 D+上接一个 1.5K 的电阻到 VCC,而如果是低速设备,则会在 D-上接一个 1.5K 的电阻到 VCC。这样当设备接入主机的时候,主机就可以判断是否有设备接入,并能判断设备是高速设备还是低速设备。

STM32F103 的 MCU 自带 USB 从控制器,符合 USB 规范的通信连接;PC 主机和微控制器之间的数据传输是通过共享一专用的数据缓冲区来完成的,该数据缓冲区能被 USB 外设直接访问。这块专用数据缓冲区的大小由所使用的端点数目和每个端点最大的数据分组大小所决定,每个端点最大可使用 512 字节缓冲区(专用的 512 字节,和 CAN 共用),最多可用于 16 个单向或 8 个双向端点。USB 模块同 PC 主机通信,根据 USB 规范实现令牌分组的检测,数据发送/接收的处理,和握手分组的处理。整个传输的格式由硬件完成,其中包括 CRC 的生成和校验。

1.1 USB HID简介

USB HID类是USB设备的一个标准设备类,包括的设备非常多。HID类设备定义它属于人机交互操作的设备,用于控制计算机操作的一些方面,如USB鼠标、USB键盘、USB游戏操纵杆等。但HID设备类不一定要有人机接口,只要符合HID类别规范的设备都是HID设备。

USB HID设备的一个好处就是操作系统自带了HID类的驱动程序,而用户无需去开发驱动程序,只要使用API系统调用即可完成通信。

官方资料:http://www.usb.org/developers/hidpage
其中包含最主要的两个说明:

  • 《Device Class Definition for human interface device (HID)》【描述了 HID 的基本组成和格式】

  • 《Universal Serial Bus HID Usage Tables》【对上面文档的补充,将各种不同的 HID 设备的基本组成列举出来】

二、新建工程

1. 打开 STM32CubeMX 软件,点击“新建工程”


2. 选择 MCU 和封装


3. 配置时钟
RCC 设置,选择 HSE(外部高速时钟) 为 Crystal/Ceramic Resonator(晶振/陶瓷谐振器)


选择 Clock Configuration,配置系统时钟 SYSCLK 为 72MHz
修改 HCLK 的值为 72 后,输入回车,软件会自动修改所有配置


4. 配置调试模式
非常重要的一步,否则会造成第一次烧录程序后续无法识别调试器
SYS 设置,选择 Debug 为 Serial Wire


三、USB

3.1 参数配置

在 Connectivity 中选择 USB 设置,并勾选 Device(FS) 激活 USB 设备。


在 Parameter Settings 进行具体参数配置。


  • Speed: Full Speed 12MBit/s(固定为全速)

  • Low Power: 默认 Disabled(在任何不需要使用usb模块的时候,通过写控制寄存器总可以使usb模块置于低功耗模式(low power mode ,suspend模式)。在这种模式下,不产生任何静态电流消耗,同时usb时钟也会减慢或停止。通过对usb线上数据传输的检测,可以在低功耗模式下唤醒usb模块。也可以将一特定的中断输入源直接连接到唤醒引脚上,以使系统能立即恢复正常的时钟系统,并支持直接启动或停止时钟系统。)

3.2 引脚配置

USB 的 DP 引脚必须上拉 1.5K 欧的电阻,电脑才能检测到 USB,否则检测不到。


查看野火指南者开发板原理图可知,需要将 PD6 配置为低电平使能 USB。


在右边图中找到 PD6 引脚,选择 GPIO_Output。


在GPIO output level 中选择 Low 输出低电平。


3.3 配置时钟

选择 Clock Configuration,USB 时钟配置为 48MHz,且来源最好是外部晶振分频得到。


3.4 USB Device

USB有主机(Host)和设备(Device)之分。一般电脑的USB接口为主机接口,而键盘、鼠标、U盘等则为设备。

部分型号的STM32芯片有1~2个USB接口。像STM32F103系列的有一个USB Device接口,STM32F407系列的有2个USB接口,既可以作为HOST,又可以作为Device,还可以作为OTG接口。

在 Middleware 中选择 USB_DEVICE 设置,在 Class For FS IP 设备类别选择 Human Interface Device Class(HID) 人机接口设备。


参数配置保持默认。


  • HID_FS_BINTERVAL(主机读取设备数据时间间隔): 0xA(STM32将数据发送到一个缓存区,而不是直接发送到上位机,而上位机每隔一端时间会来访问缓冲区读取数据。读取时间间隔过快会导致多次数据发送,过慢会导致数据丢失)

  • USBD_MAX_NUM_INTERFACES (Maximum number of supported interfaces)(最大支持HID设备的接口数): 1(应为现在只有键盘,所以1就行,如果是需要同时键盘,鼠标,手柄啥的,根据数量选择即可)

设备描述符保持默认。


四、添加按键

4.1 GPIO配置

在 System Core 中选择 GPIO 设置。


在右边图中找到按键对应引脚,选择 GPIO_Input。


五、生成代码

输入项目名和项目路径


选择应用的 IDE 开发环境 MDK-ARM V5


每个外设生成独立的 ’.c/.h’ 文件
不勾:所有初始化代码都生成在 main.c
勾选:初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。


点击 GENERATE CODE 生成代码


六、修改usbd_hid.c

打开工程文件夹Middlewares/USB_Device_Library下usbd_hid.c文件


6.1 修改接口描述符(可跳过)

HID设备的描述符除了5个USB的标准描述符(设备描述符、配置描述符、接口描述符、端点描述符、字符串描述符)外,还包括三个HID设备类特定的描述符:HID描述符、报告描述符(Report)、实体描述符(Physical)。

他们之间的层次关系如图:


打开usbd_hid.c文件,找到USBD_HID_CfgFSDesc配置全速描述符数组定义处。

  • 配置描述符
    bNumInterfaces表示这个设备有多少个接口。
    MaxPower 100 mA表示这个设备需要从总线上获取100mA电流。

/* USB HID device FS Configuration Descriptor */

__ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ]  __ALIGN_END =

{

  0x09, /* bLength: Configuration Descriptor size */

  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */

  USB_HID_CONFIG_DESC_SIZ,

  /* wTotalLength: Bytes returned */

  0x00,

  0x01,         /*bNumInterfaces: 1 interface*/

  0x01,         /*bConfigurationValue: Configuration value*/

  0x00,         /*iConfiguration: Index of string descriptor describing

  the configuration*/

  0xE0,         /*bmAttributes: bus powered and Support Remote Wake-up */

  0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/


  • 接口描述符
    bInterfaceClass的值必须是 0x03
    bInterfaceSubClass的值为 0 或 1, 为1表示HID设备是一个启动设备(BootDevice, 一般对PC机有意义,意思是BIOS启动时能识别您使用的HID设备,切只有标准鼠标或者键盘才能称为BootDevice),为0表示HID设备是操作系统启动厚才能识别使用的设备。


  /************** Descriptor of Joystick Mouse interface ****************/

  /* 09 */

  0x09,         /*bLength: Interface Descriptor size*/

  USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/

  0x00,         /*bInterfaceNumber: Number of Interface*/

  0x00,         /*bAlternateSetting: Alternate setting*/

  0x01,         /*bNumEndpoints*/

  0x03,         /*bInterfaceClass: HID*/

  0x01,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/

  0x02,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/

  0,            /*iInterface: Index of string descriptor*/


这里我们将bInterfaceProtocol的值改为1:(0 — NONE,1 — Keyboard(键盘),2 — Mouse (鼠标),3~255  Reserved)


  • HID描述符
    HID描述符关联于接口描述符,因而如果一个设备只有一个接口描述符,则无论它有几个端点描述符,HID设备只有一个HID描述符。HID设备描述符主要描述HID规范的版本号, HID通信所使用的额外描述符,报告描述符的长度等。


  /******************** Descriptor of Joystick Mouse HID ********************/

  /* 18 */

  0x09,         /*bLength: HID Descriptor size*/

  HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/

  0x11,         /*bcdHID: HID Class Spec release number*/

  0x01,

  0x00,         /*bCountryCode: Hardware target country*/

  0x01,         /*bNumDescriptors: Number of HID class descriptors to follow*/

  0x22,         /*bDescriptorType*/

  HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/

  0x00,


下表为HID描述符的结构。

偏移量大小(Byte)描述
0bLength1数字此描述符的长度,以字节为单位
1bDescriptorType1常量描述符种类(此处 0x21为HID类)
2bcdHID2数字HID规范版本号(BCD码),采用4个16进制的BCD格式编码
4bCountryCode1数字硬件目的国家的识别码
5bNumDescriptors1数字支持的附属描述符数目
6bDescriptorType1常量0x21-HID描述符,0x22-报告描述符,0x23-实体描述符
7wDescriptorLength2数字报告描述符的总长度
9bDescriptorType1常量用于识别描述符类型的常量,使用有一个以上描述符的设备
10wDescriptorLength2数字描述符总长度,使用在有一个以上描述符的设备
  • 端点描述符
    bEndpointAddress表示端点地址,表示当前这个接口所需要的端点资源,输入(相对于主机而言)端点最高位为1,输出(相对于主机而言)端点最高位为0。HID设备一般都是使用中断端点进行数据传输。
    wMaxPacketSize表示该端点上数据传输的数量。
    bInterval表示主机查询设备数据的时间间隔,如果设置的太长,则键盘输入延迟很高。


 0x05, 0x01, // USAGE_PAGE (Generic Desktop) //63

 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



6.2 修改报告描述符

下载 HID Descriptor Tool (DT) HID描述符工具:
官网下载:https://usb.org/sites/default/files/documents/dt2_4.zip
百度网盘:https://pan.baidu.com/s/1ayjdQtc7e9NWwYJqdp0pXA?pwd=4ghb  提取码:4ghb

打开 File——》Open...——》keybrd.hid


我们可以看到HID键盘的描述符情况:


打开usbd_hid.c文件,找到HID_MOUSE_ReportDesc数组定义处(默认生产HID设备为Mouse,这里数组名不影响,只要里面的描述符是键盘的就行)。

 0x05, 0x01, // USAGE_PAGE (Generic Desktop) //63
 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]
关键字:STM32CubeMX  USB接口 引用地址:STM32CubeMX学习笔记(44)——USB接口使用(HID按键)

上一篇:STM32CubeMX学习笔记(47)——USB接口使用(MSC基于内部Flash模拟U盘)
下一篇:STM32CubeMX学习笔记(43)——USB接口使用(CDC虚拟串口)

推荐阅读最新更新时间:2026-03-25 11:30

STM32CubeMX学习笔记(46)——USB接口使用(HID自定义设备)
一、USB简介 USB(Universal Serial BUS)通用串行总线,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯。是应用在 PC 领域的接口技术。USB 接口支持设备的即插即用和热插拔功能。USB 是在 1994 年底由英特尔、康柏、IBM、Microsoft 等多家公司联合提出的。 USB 发展到现在已经有 USB1.0/1.1/2.0/3.0 等多个版本。目前用的最多的就是 USB1.1 和 USB2.0,USB3.0 目前已经开始普及。STM32F103 自带的 USB 符合 USB2.0 规范,不过 STM32F103 的 USB 都只能用来做设备,而不能用作主机。 标准 USB 共四根线组成,除
[单片机]
配置CLion + STM32CubeMX开发环境
0.前言 由于本人对Keil的编译环境不太满意,故在网上搜寻了各种代替方法,最终选定了CLoin的IDE,它可以支持从STM32CubeMX生成的代码直接编译,节省了大量时间去配置初始化代码,以下只作为本人的一次环境搭建的踩坑记录,希望对正在解决问题的你有所帮助。 本次配置参考了如下几位大佬的说明 配置CLion用于STM32开发【优雅の嵌入式开发】 - 哔哩哔哩 (bilibili.com) 使用Clion优雅开发STM32 _哔哩哔哩_bilibili Clion实现Stm32标准库开发 - 哔哩哔哩 (bilibili.com) 网页链接 1.环境所需配置搭建 首先确保已经安装了stlink的驱动,如使用的是
[单片机]
基于STM32CUBEMX驱动低压步进器电机驱动器STSPIN220(1)----套件概述
套件概述 STM32C011F4Px_STSPIN220 是一款基于 STM32C011F4Px 的低压步进电机驱动套件。其中,STSPIN220 是一款步进电机驱动器,在一个小型 VFQFPN 3 x 3 x 1.0 mm 封装中集成了控制逻辑和低 RDS(开启)功率级。该套件提供一整套保护功能,包括过电流、过热和短路保护,并且可以强制进入零消耗状态,从而显著延长电池寿命。 最近在弄ST的课程,需要样片的可以加qun申请:615061293 。 视频教学 https://www.bilibili.com/video/BV1Ju4y1R7mA/ 19:14 基于STM32CUBEMX驱动低压步进器电机驱动器STSP
[单片机]
STM32CUBEMX生成freeRTOS代码的时候出现警告
概述 最近做新项目使用了FREERTOS.1,执行生成代码时提示: WARNINGS: - When FreeRTOS is used, it is strongly recommanded to use HAL timebase source other than the Systick. HAL函数如果是阻塞型呼叫,內部会用到HAL_Delay(),FreeRTOS应该还是使用SystTick。如果使用的时基操作來源一样,怕有不可预期问题出现,故选择其他定时器。 此时在生成代码报错就会消失。
[单片机]
STM32cubeMX 和 C++ 记要
一、目的 本文是为了记录使用 stm32CubeMX 、arm-none-eabi-gcc 和 vscode 配置 arm 的 C++ 环境。 参考了下面的两篇文章。 在arm-gcc的环境下使用C/C++混合编程开发stm32 - 哔哩哔哩 (bilibili.com) (31条消息) STM32 C++编程系列一:STM32 C++编程介绍c++开发stm32江雨潇潇下的博客-CSDN博客 二、CubeMX 基本配置 有两点记要: SYS 的 Debug 选项 image.png 不然只能下载一次程序。 Toolchain 工具链 image.png 要选择 Makefile 三、VScode 配置
[单片机]
<font color='red'>STM32cubeMX</font> 和 C++ 记要
STM32CubeMX学习笔记(2)——GPIO接口使用
一、新建工程 1. 打开 STM32CubeMX 软件,点击“新建工程” 2. 选择 MCU 和封装 3. 配置时钟 RCC 设置,选择 HSE(外部高速时钟) 为 Crystal/Ceramic Resonator(晶振/陶瓷谐振器) 选择 Clock Configuration,配置系统时钟 SYSCLK 为 72MHz 修改 HCLK 的值为 72 后,输入回车,软件会自动修改所有配置 4. 配置调试模式 非常重要的一步,否则会造成第一次烧录程序后续无法识别调试器 SYS 设置,选择 Debug 为 Serial Wire 二、GPIO输出 2.1 参数配置 在 System Core
[单片机]
STM32CubeMX学习笔记(9)——I2C接口使用(读写EEPROM AT24C02)
一、I2C简介 I2C(Inter-Integrated Circuit ,内部集成电路) 总线是一种由飞利浦 Philip 公司开发的串行总线。是两条串行的总线,它由一根数据线(SDA)和一根 时钟线(SCL)组成。I2C 总线上可以接多个 I2C 设备,每个器件都有一个唯一的地址识别。同一时间只能有一个主设备,其他为从设备。通常 MCU 作为主设备控制,外设作为从设备。 STM32 的 I2C 外设可用作通讯的主机及从机,支持 100Kbit/s 和 400Kbit/s 的速率,支持 7 位、10 位设备地址,支持 DMA 数据传输,并具有数据校验功能。它的 I2C 外设还支持 SMBus2.0 协议,SMBus 协议与 I
[单片机]
STM32CubeMX学习笔记(11)——IWDG独立看门狗使用
一、IWDG简介 看门狗其实就是一个定时器,从功能上说它可以让微控制器在程序发生意外(程序进入死循环或跑飞)的时候,能重新回复到系统刚上电状态,以保障系统出问题的时候可以重启一次。说的复杂一点,看门狗就是能让程序出问题是能重新启动系统。 STM32 有两个看门狗,一个是独立看门狗另外一个是窗口看门狗,独立看门狗号称宠物狗,窗口看门狗号称警犬。独立看门狗用通俗一点的话来解释就是一个 12 位的递减计数器,当计数器的值从某个值一直减到 0 的时候,系统就会产生一个复位信号,即 IWDG_RESET。如果在计数没减到 0 之前,刷新了计数器的值的话,那么就不会产生复位信号,这个动作就是我们经常说的喂狗。看门狗功能由 VDD 电压域供电
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved