STM32 USB使用记录:HID类设备(后篇)
文章目录
- 目的
- 基础说明
- 项目构建与代码调整
- 接收发送代码与测试
- 示例链接
- 报告描述符
- 总结
目的
接上篇: 《STM32 USB使用记录:HID类设备(前篇)》
USB HID 类的设备有个比较大的好处是大部分时候接入主机中都是可以免驱使用的。这篇文章将介绍下 STM32 中实现 USB HID 双向透传功能,结合免驱的特点,这在实际工作中是比较常用的。
基础说明
在上一篇文章中简单了解接触了下HID设备,了解了USB设备的各种描述符概念。在这篇文章追中我们要制作一个自定义的HID设备,实现双向透传功能,主要就是要调整配置描述符、端口、报告描述符等内容。
项目构建与代码调整
首先使用Cube工具来生成基础的项目,其它内容和上一篇文章一样,唯一不同的是 USB_DEVICE 这里选用 Custom Human Interface Device Class(HID) :

生成的项目和上篇文章中差不多:

因为是自定义的HID设备,所以报告描述符需要自己准备,这里修改 usbd_custom_hid_if.c 中的报告描述符实现双向透传功能:
/** Usb HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x00, // Usage (0x00)
0xA1, 0x01, // Collection (Application)
0x09, 0x01, // Usage (0x01)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x40, // Report Count (64)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x02, // Usage (0x02)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x40, // Report Count (64)
0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
// 34 bytes
};
然后需要修改 usbd_conf.h 中一些定义值:
/*---------- 接收缓冲区大小 -----------*/
/*---------- 对于全速设备收和发一个包最大都为64字节 -----------*/
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 64U
/*---------- 报告描述符长度 -----------*/
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 34U
/*---------- 端电查询时间间隔 -----------*/
/*---------- 对于全速设备该值为1表示最快可以每1ms通讯一次 -----------*/
#define CUSTOM_HID_FS_BINTERVAL 0x5U
/*---------- -----------*/
还需要修改 usbd_customhid.h 中的定义值:
// 接收一个包最大为64字节
#define CUSTOM_HID_EPIN_SIZE 0x40U
// 发送一个包最大为64字节
#define CUSTOM_HID_EPOUT_SIZE 0x40U
上面的定义值的调整也可以在Cube工具中直接进行配置。
接收发送代码与测试
在 usbd_custom_hid_if.c 文件中修改接收事件( OutEvent )部分代码:
uint32_t size = 0;
uint8_t buff[64];// 收到来自主机的数据时会触发该事件
static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
{UNUSED(event_idx);UNUSED(state);size = USBD_LL_GetRxDataSize(&hUsbDeviceFS, CUSTOM_HID_EPOUT_ADDR); // 获取收到的数据长度USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)(hUsbDeviceFS.pClassData);for(int i=0; i<size; i++){buff[i]=hhid->Report_buf[i]; // 读取接收到的数据}USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, buff, size);// 开启下一次接收if (USBD_CUSTOM_HID_ReceivePacket(&hUsbDeviceFS) != (uint8_t)USBD_OK){return -1;}return (USBD_OK);
}
至此就可以进行测试了,这里用的工具下载地址如下:
https://pan.baidu.com/s/1i5QVmrN

测试时依据设备的VID和PID来分辨设备,这两个值定义在 usbd_desc.c 文件中(注意十进制和十六进制的差别):
#define USBD_VID 1155
#define USBD_PID_FS 22352

上面演示中接收部分代码有拷贝动作,这在高性能需求下其实是不太合适的,可以使用下面方式来处理:
uint32_t size = 0;
uint8_t buff[64]; // 接收缓冲区
static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
{size = USBD_LL_GetRxDataSize(&hUsbDeviceFS, CUSTOM_HID_EPOUT_ADDR); // 获取收到的数据长度USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, buff, size); // 发送数据// 开启下一次接收,设置接收缓冲区(默认的USBD_CUSTOM_HID_ReceivePacket方法中调用的其实也是这个)USBD_LL_PrepareReceive(&hUsbDeviceFS, CUSTOM_HID_EPOUT_ADDR, buff, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);return (USBD_OK);
}
需要注意的是上面方式第一次接到数据是用的还是默认设置的缓冲区。
示例链接
仓库地址: https://github.com/NaisuXu/STM32_MCU_Examples
本示例为仓库中 USBD_HID_FS_H750 。
报告描述符
上面演示中用的是 USB FS ,该规范下HID一包数据最大为64Bytes,如果使用 USB HS ,那么每包最大为1024Bytes,报告描述符可以使用下这个(未测试):
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x00, // Usage (0x00)
0xA1, 0x01, // Collection (Application)
0x09, 0x01, // Usage (0x01)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x96, 0x00, 0x04, // Report Count (1024)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x02, // Usage (0x02)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x96, 0x00, 0x04, // Report Count (1024)
0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
// 36 bytes
HID设备的报告描述符可以使用 HID Descriptor Tool 工具配置生成:
https://www.usb.org/document-library/hid-descriptor-tool

总结
总体来说 STM32 中实现 USB HID 双向透传功能并不复杂。
相关文章:
STM32 USB使用记录:HID类设备(后篇)
文章目录 目的基础说明项目构建与代码调整接收发送代码与测试示例链接报告描述符总结 目的 接上篇: 《STM32 USB使用记录:HID类设备(前篇)》 USB HID 类的设备有个比较大的好处是大部分时候接入主机中都是可以免驱使用的。这篇文…...
C# 快速写入日志 不卡线程 生产者 消费者模式
有这样一种场景需求,就是某个方法,对耗时要求很高,但是又要记录日志到数据库便于分析,由于访问数据库基本都要几十毫秒,可在方法里写入BlockingCollection,由另外的线程写入数据库。 可以看到,在…...
Pandas将对角线元素设为1
Pandas将对角线元素设为1 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 入门之pandas的使用 提示:np.fill_diagonal(df.values, 1)的用法 Pandas将对角线元素设为1 Pandas将对角线元素设为…...
WPF实战学习笔记28-登录界面
添加登录界面UI 添加文件loginview.xaml。注意本界面使用的是md内的图标。没有登录界面的图片 <UserControlx:Class"Mytodo.Views.LoginView"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsof…...
01背包
动态规划解题步骤: 动态规划问题,一般从三个步骤进行考虑。 步骤一:集合及集合的状态。 所谓的集合,就是一些方案的集合。 用 g[i][j] 表示从前 i 种物品中进行选择,且总体积不大于 j 的各个选法获得的价值的集合。注意&#…...
064、故障处理之OMM_TiDB
oom 内存溢出,内存泄漏,相当于TiDB不能用了 TiDB Server OOM对业务的影响 TiDB Server上的业务SQL会失败业务响应时间升高前端体验变差 诊断方法 客户端应用 ERROR 2013(HY000): Lost connection to MySQL Server during query日志 dmesg -T | gr…...
网络设备中的配置文件管理
建立强大网络的第一步是为灾难和网络中断做好准备,许多企业在中断期间遭受损失,因为他们缺乏备份计划并且配置管理不达标,使用配置文件管理工具进行适当的配置文件管理不仅有助于处理网络中断,还有助于优化网络性能。 使用配置文…...
HCIP BGP综合实验
题目 1、AS1存在两个环回,一个地址为192.168.1.0/24该地址不能在任何协议中宣告; 2、AS3中存在两个环回,一个地址为192.168.2.0/24该地址不能在任何协议中宣告,最终要求这两个环回可以互相通讯; 3、AS间的骨干链路I…...
【mysql学习篇】Order by与Group by优化以及排序算法详解
一、Order by与Group by优化 Case1: 分析: 利用最左前缀法则:中间字段不能断,因此查询用到了name索引,从key_len74也能看出,age索引列用在排序过程中,因为Extra字段里没有using filesort 注意…...
【业务功能篇60】Springboot + Spring Security 权限管理 【终篇】
4.4.7 权限校验扩展 4.4.7.1 PreAuthorize注解中的其他方法 hasAuthority:检查调用者是否具有指定的权限; RequestMapping("/hello")PreAuthorize("hasAuthority(system:user:list)")public String hello(){return "hello Sp…...
文章详情页 - 评论功能的实现
目录 1. 准备工作 1.1 创建评论表 1.2 创建评论实体类 1.3 创建 mapper 层评论接口和对应的 xml 实现 1.4 准备评论的 service 层 1.5 准备评论的 controller 层 2. 总的初始化详情页 2.1 加载评论列表 2.1.1 实现前端代码 2.1.2 实现后端代码 2.2 查询当前登录用户的…...
使用贝叶斯滤波器通过运动模型和嘈杂的墙壁传感器定位机器人研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Day 69-70:矩阵分解
代码: package dl;import java.io.*; import java.util.Random;/** Matrix factorization for recommender systems.*/public class MatrixFactorization {/*** Used to generate random numbers.*/Random rand new Random();/*** Number of users.*/int numUsers…...
数据结构:树的存储结构
学习树之前,我们已经了解了二叉树的顺序存储和链式存储,哪么我们如何来存储普通型的树结构的数据?如下图1: 如图1所示,这是一颗普通的树,我们要如何来存储呢?通常,存储这种树结构的数…...
Vue前端渲染blob二进制对象图片的方法
近期做开发,联调接口。接口返回的是一张图片,是对二进制图片处理并渲染,特此记录一下。 本文章是转载文章,原文章:Vue前端处理blob二进制对象图片的方法 接口response是下图 显然,获取到的是一堆乱码&…...
Java的标记接口(Marker Interface)
Java中的标记接口(Marker Interface)是一个空接口,接口内什么也没有定义。它标识了一种能力,标识继承自该接口的接口、实现了此接口的类具有某种能力。 例如,jdk的com.sun.org.apache.xalan.internal.xsltc.trax.Temp…...
Kafka基础架构与核心概念
Kafka简介 Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。架构特点是分区、多副本、多生产者、多订阅者,性能特点主要是…...
观察者模式与观察者模式实例EventBus
什么是观察者模式 顾名思义,观察者模式就是在多个对象之间,定义一个一对多的依赖,当一个对象状态改变时,所有依赖这个对象的对象都会自动收到通知。 观察者模式也称为发布订阅模式(Publish-Subscribe Design Pattern)࿰…...
科普 | OSI模型
本文简要地介绍 OSI 模型 1’ 2’ 3。 更新:2023 / 7 / 23 科普 | OSI模型 术语节点链路协议网络拓扑 概念作用结构应用层表示层会话层传输层网络层数据链路层物理层 数据如何流动OSI 和TCP/IP 的对应关系和协议参考链接 术语 节点 节点( Node &#…...
redis相关异常之RedisConnectionExceptionRedisCommandTimeoutException
本文只是分析Letture类型的Redis 池化连接出现的连接超时异常、读超时异常问题。 1.RedisConnectionException 默认是10秒。 通过如下可以配置: public class MyLettuceClientConfigurationBuilderCustomizer implements LettuceClientConfigurationBuilderCusto…...
Calibre-Web豆瓣API插件终极指南:5分钟恢复智能元数据获取
Calibre-Web豆瓣API插件终极指南:5分钟恢复智能元数据获取 【免费下载链接】calibre-web-douban-api 新版calibre-web已经移除douban-api了,添加一个豆瓣api实现 项目地址: https://gitcode.com/gh_mirrors/ca/calibre-web-douban-api 还在为Cali…...
Gemini SQL查询生成落地手册(企业级生产环境已验证)
更多请点击: https://kaifayun.com 第一章:Gemini SQL查询生成落地手册(企业级生产环境已验证) 在大型金融与电商客户的真实生产环境中,Gemini 模型已被成功集成至自助分析平台,日均稳定生成超 12,000 条符…...
人机协同决策:AI如何通过认知冲突提升专家判断力
1. 人机协同决策的认知悖论:当“不如你”的AI成为你的最佳搭档在医疗诊断室里,一位经验丰富的放射科医生正在审阅一张肺部CT影像。他的初步判断是良性结节,但屏幕角落弹出的AI辅助诊断系统却给出了“疑似恶性”的提示,置信度显示为…...
LangGraph 与 Streamlit 集成:实时展示多智能体执行状态
1. 标题选项 核心关键词:LangGraph、Streamlit、多智能体、实时可观测性、执行状态可视化 《从0到1:LangGraph + Streamlit 打造可观测的多智能体实时运行面板》 《多智能体开发不再黑盒!手把手教你用Streamlit可视化LangGraph执行全流程》 《LangGraph实战:集成Streamlit实…...
低查重AI写教材秘诀大揭秘!高效工具助你快速生成专业教材
一、AI教材写作的现状与需求 在编写教材之前,选择合适的工具常常让人感到无比纠结!如果用普通的办公软件,功能显得太过于简单,想要搭建框架或者规范格式,都只能依靠手工操作;而如果选择了专业的教材编写工…...
B站CC字幕下载与转换工具:技术实现与实用指南
B站CC字幕下载与转换工具:技术实现与实用指南 【免费下载链接】BiliBiliCCSubtitle 一个用于下载B站(哔哩哔哩)CC字幕及转换的工具; 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBiliCCSubtitle 在当今数字化学习时代,视频内容已成为获取知…...
DS4Windows:让PS4手柄在Windows电脑上焕发新生!5个超实用功能解锁游戏新境界
DS4Windows:让PS4手柄在Windows电脑上焕发新生!5个超实用功能解锁游戏新境界 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows 还在为PC游戏不支持PS4手柄而烦恼吗&a…...
3分钟搞定学期教材:中小学智慧教育平台电子课本下载全攻略 [特殊字符]
3分钟搞定学期教材:中小学智慧教育平台电子课本下载全攻略 📚 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具,帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载,让您更方便地获取课本…...
机器学习势函数结合自由能微扰:高效预测高熵合金熔点的混合计算框架
1. 项目概述:当机器学习遇上第一性原理,如何为高熵合金“量体温”?在材料设计的战场上,熔化温度是一个决定性的“硬指标”。对于像高熵合金这类由多种元素等比例或近等比例混合而成的新型材料,其卓越的高温强度、耐腐蚀…...
稳定的工作_or_冒险的挖洞副业?成年人的选择,从来不是非黑即白
01 — 导语 在互联网时代,“搞副业”成了年轻人对抗焦虑的标配。有人下班跑滴滴,有人周末做博主,而有一群技术极客则选择了一条更硬核的赛道——漏洞挖掘(俗称“挖洞”)。一边是朝九晚五的稳定工作,五险…...
