STM32H743-ARM例程23-USB_HID

目录

实验平台

硬件:银杏科技GT7000双核心开发板-ARM-STM32H743XIH6,银杏科技iToolXE仿真器

软件:最新版本STM32CubeH7固件库STM32CubeMX v6.10.0,开发板环境MDK v5.35

USB_HID

USB HID是Human Interface Device的缩写,由其名称可以了解HID设备是直接与人交互的设备,例如键盘、鼠标与游戏杆等。不过HID设备并不一定要有人机接口,只要符合HID类别规范的设备都是HID设备。

交换的数据存储在称为报表(report)的结构内,设备的固件必须支持HID报表的格式。主机在控制与中断传输中传送与要求报表,来传送与接收数据。报表的格式非常有弹性,可以处理任何类别的数据。

设备除了HID接口之外,它可能同时还包含有其他的USB接口。例如影像显示设备可能使用HID接口来做亮度,对比,与更新率的软件控制,而使用传统的影 像接口来传送要显示的数据。USB扩音器可以使用实时传输来播放语音,同时使用HID接口来控制音量,震荡,与低音等。HID接口通常比传统的控制接口来得便宜。

Wndows操作系统最先支持的HID设备。在windows98以及后来的版本中内置有HID设备的驱动程序,应用程序可以直接使用这些驱动程序来与设备通信。

在设计一个USB接口的计算机外部设备时,如果HID类型的设备可以满足需要,可以将其设计为HID类型设备,这样可以省去比较复杂的USB驱动程序的编写,直接利用Windows操作系统对标准的HID类型USB设备的支持。

HID设备特点

  1. 交换的数据储存在称为报表(Report)的结构内,设备的固件必须支持HID报表的格式。主机通过控制和中断传输中的传送和请求报表来传送和接收数据。报表的格式非常灵活。
  2. 每一笔事务可以携带小量或中量的数据。低速设备每一笔事务最大是8B,全速设备每一笔事务最大是64B,高速设备每一笔事务最大是1024B。一个报表可以使用多笔事务。
  3. 设备可以在未预期的时间传送信息给主机,例如键盘的按键或是鼠标的移动。所以主机会定时轮询设备,以取得最新的数据。
  4. HID设备的最大传输速度有限制。主机可以保证低速的中断端点每10ms内最多1笔事务,每一秒最多是800B。保证全速端点每lms一笔事务,每一秒最多是64000B。保证高速端点每125us三笔事务,每一秒最多是24.576MB。
  5. HID设备没有保证的传输速率。如果设备是设置在10ms的时距,事务之间的时间可能等于或小于10ms。除非设备是设置在全速时在每个帧传输数据,或是在高速时在每个微帧传输数据。这是最快的轮询速率,所以端点可以保证有正确的带宽可供使用。
    HID设备除了传送数据给主机外,它也会从主机接收数据。只要能够符合HID类别规范的设备都可以是HID设备。
      设备除了HID接口之外,它可能同时还包含有其他的USB接口。例如影像显示设备可能使用HID接口来做亮度、对比度的软件控制,而使用传统的影像接口来传送要显示的数据。USB扩音器可以使用实时传输来播放语音,同时使用HID接口来控制音量、低音等。
      HID类别设备的规范文件主要是以下两份:
        Device Class Definition for Human interface Devices
        HID Usabe Tables
    想了解更多HID知识可以参考连接http://www.usbzh.com/article/detail-76.html

USB_HS原理图

STM32CubeMX生成工程

我们参考前面章节STM32H743-结合CubeMX新建HAL库MDK工程,打开CubeMX软件,重复步骤不再展示,我们来看配置USB部分如下图所示:

实验步骤

  1. 我们打开实验工程文件,修改USB_hid.c文件

找到USB接口描述符这里我们将bInterfaceProtocol的值改为1:(0 --- NONE,1 --- Keyboard(键盘),2 --- Mouse (鼠标),3~255 Reserved)

  1. 修改报告描述符
    下载 HID Descriptor Tool (DT) HID描述符工具:
    官网下载:https://usb.org/sites/default/files/documents/dt2_4.zip
    打开 File->Open...->keybrd.hid

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

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

实验现象

按下按键KEY1后,键盘自动输入"A"。

实验代码

  1. 主函数
cpp 复制代码
extern USBD_HandleTypeDef hUsbDeviceHS;
uint8_t buffer[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
void SystemClock_Config(void);
int main(void)
{

    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USB_DEVICE_Init();
    MX_USART6_UART_Init();

    while (1)
    {
        if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0)
        {  
          buffer[0] = 0x02; //shift
          buffer[2] = 0x04; //a
          USBD_HID_SendReport(&hUsbDeviceHS, buffer, 8); //send
          HAL_Delay(15); //delay
         
          buffer[0] = 0x00;
          buffer[2] = 0x00;
          USBD_HID_SendReport(&hUsbDeviceHS, buffer, 8);
          HAL_Delay(15);
         
          while(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0)
          HAL_Delay(15);
        }

    }

}
  1. usbd_custom_hid_if.c中的报告描述符
cpp 复制代码
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
    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

};
相关推荐
日更嵌入式的打工仔5 小时前
存储同步管理器SyncManager 归纳
笔记·单片机·嵌入式硬件
社会大青年5 小时前
STM32 GPIO-------设置成51单片机模式输出
stm32·嵌入式硬件·51单片机
半夏微凉半夏殇6 小时前
除了arm 还有那些开源的芯片架构
arm开发·架构·开源
麻辣长颈鹿Sir6 小时前
单片机进入 B. 中断无限循环异常解决方法
单片机·嵌入式硬件·b.中断·异常中断处理·程序无限循环异常处理·芯海spi异常中断·芯海芯片
red watchma6 小时前
Xshell->MCU Ymodem协议实现
网络·单片机·嵌入式硬件
XINVRY-FPGA6 小时前
XC7A100T-2FGG484I Xilinx Artix-7 FPGA
arm开发·嵌入式硬件·fpga开发·硬件工程·信息与通信·信号处理·fpga
lingzhilab7 小时前
零知IDE——基于STM32F407VET6和ESP-01的SHT2X温湿度监测与云传输系统
stm32·单片机·嵌入式硬件
国科安芯7 小时前
高辐射环境下AS32S601ZIT2型MCU的抗辐照性能与应用潜力分析
网络·人工智能·单片机·嵌入式硬件·fpga开发
三佛科技-1341638421210 小时前
高速风筒方案开发 高速风筒MCU控制方案设计
单片机·嵌入式硬件·智能家居·pcb工艺