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 双向透传功能并不复杂。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/15895.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高并发架构去重难?架构必备技能 - 布隆过滤器

系列文章目录 当Dubbo遇到高并发&#xff1a;探究流量控制解决方案 主从选举机制&#xff0c;架构高可用性的不二选择 高并发架构去重难&#xff1f;架构必备技能 - 布隆过滤器 系列文章目录前言一、布隆过滤器简介二、特性与应用场景三、参数定制四、java版本的Demo五、总结 …

<findbugs>静态代码分析工具

背景&#xff1a; IDEA安装的findbug插件目前无法和jenkins的扫描结果保持一致&#xff0c;因为&#xff1a;没有对应jenkins上findbug的版本&#xff1b; 原理&#xff1a; 将jenkins服务器上的findbugs插件&#xff0c;拷贝到本地&#xff0c;修改build.xml内容以匹配目录…

Resnet与Pytorch花图像分类

1、介绍 1.1数据集介绍 flower_data├── train│ └── 1-102&#xff08;102个文件夹&#xff09;│ └── XXX.jpg&#xff08;每个文件夹含若干张图像&#xff09;├── valid│ └── 1-102&#xff08;102个文件夹&#xff09;└── ─── └── XXX.jp…

Python读取csv、Excel文件生成图表

简介 本文章介绍了通过读取 csv 或 Excel 文件内容&#xff0c;将其转换为折线图或柱状图的方法&#xff0c;并写入 html 文件中。 目录 1. 读取CSV文件 1.1. 生成折线图 1.1.1. 简单生成图表 1.1.2. 设置折线图格式 1.2. 生成柱状图 1.2.1. 简单生成图表 1.2.2. 设置柱…

关于阿里云OSS服务器绑定域名及Https证书

这是一个没有套路的前端博主&#xff0c;热衷各种前端向的骚操作&#xff0c;经常想到哪就写到哪&#xff0c;如果有感兴趣的技术和前端效果可以留言&#xff5e;博主看到后会去代替大家踩坑的&#xff5e; 主页: oliver尹的主页 格言: 跌倒了爬起来就好&#xff5e; 关于阿里云…

零基础玩转C语言—结构体【初阶】

大家好&#xff0c;我是深鱼~ 目录 【前言】&#xff1a; 一、结构体的声明 1.1结构的基本知识 1.2结构的声明 1.3结构体成员的类型 1.4结构体变量的定义和初始化 二、结构体成员的访问 【前言】&#xff1a;本章来介绍结构体的部分知识&#xff0c;并不会深入讲解&…

NOSQL之Redis配置及优化

目录 一、关系型数据库 二、非关系型数据库 三、关系型数据库和非关系型数据库区别 1、数据存储方式不同 2、扩展方式不同 3、对事务性的支持不同 四、Redis简介 五、Redis优点 &#xff08;1&#xff09;具有极高的数据读写速度 &#xff08;2&#xff09;支持丰富的…

基于解析法和遗传算法相结合的配电网多台分布式电源降损配置(Matlab实现)

目录 1 概述 2 数学模型 2.1 问题表述 2.2 DG的最佳位置和容量&#xff08;解析法&#xff09; 2.3 使用 GA 进行最佳功率因数确定和 DG 分配 3 仿真结果与讨论 3.1 33 节点测试配电系统的仿真 3.2 69 节点测试配电系统仿真 4 结论 1 概述 为了使系统网损达到最低值&a…

C 语言 - 存储类说明符

【预备知识】 1&#xff09;C 语言 - 存储时期 2&#xff09;C 语言 - 链接属性 3&#xff09;C 语言 - 作用域 1. 分类&#xff1a; C 语言为变量提供了 5 中不同的存储模型&#xff08;即存储类&#xff09;。 &#xff08;此外还有基于指针的第 6 种存储模型&#xff0c…

html实现蜂窝菜单

效果图 CSS样式 keyframes _fade-in_mkmxd_1 {0% {filter: blur(20px);opacity: 0}to {filter: none;opacity: 1} } keyframes _drop-in_mkmxd_1 {0% {transform: var(--transform) translateY(-100px) translateZ(400px)}to {transform: var(--transform)} } ._examples_mkmx…

uniapp小程序,根据小程序的环境版本,控制的显页面功能按钮的示隐藏

需求&#xff1a;根据小程序环境控制控制页面某个功能按钮的显示隐藏&#xff1b; 下面是官方文档和功能实现的相关代码&#xff1a; 实现上面需要&#xff0c;用到了uni.getAccountInfoSync()&#xff1a; uni.getAccountInfoSync() 是一个 Uniapp 提供的同步方法&#xff0c…

rsync远程同步

文章目录 一.rsync简介1.一款快速增量备份工具2.rsync应用场景2.1 rsyncinotify的应用场景2.2 rsynccron的应用场景 二.配置rsync备份源&#xff08;同步方式&#xff09;1.rsync同步源2.同步方式3.备份的方式 三.常用rsync命令1.基本格式2.常用选项3.配置源的两种表达 四.配置…

Android 面试题 内存泄露的原因 二

&#x1f525; 什么是内存泄漏 &#x1f525; 在Android开发过程中&#xff0c;当一个对象已经不需要再使用了&#xff0c;本该被回收时&#xff0c;而另个正在使用的对象持有它引用从而导致它不能被回收&#xff0c;这就导致本该被回收的对象不能被回收而停留在堆内存中&#…

SQL-每日一题【626.换座位】

题目 表: Seat 编写SQL查询来交换每两个连续的学生的座位号。如果学生的数量是奇数&#xff0c;则最后一个学生的id不交换。 按 id 升序 返回结果表。 查询结果格式如下所示。 示例 1: 解题思路 前置知识 MySQL 的 MOD() 函数是取模运算的函数&#xff0c;它返回两个数相除…

【自用记录】常见的第三方接口加密签名方式(ASCll码字典序、URL键值对、 SHA-256加密、MD5加密)

案例1: 案例2: 以上第三方接口都用类似的加密签名方式,两者有类似的部分: 方案1的: $kdata = array(parkId=>$parkId,ts => $ts,serviceCode=>getParkingPaymentList,reqId => $reqId,plateNo => $car_code,//车牌 可为空pageIndex => 1,//第几页page…

无涯教程-jQuery - innerHeight( )方法函数

innerHeight()方法获取第一个匹配元素的内部高度(不包括边框&#xff0c;包括填充)。 innerHeight( ) - 语法 selector.innerHeight( ) innerHeight( ) - 示例 以下是一个简单的示例&#xff0c;简单说明了此方法的用法- <html><head><title>The jQuery…

适合做笔记的软件有哪些?8款好用强大的笔记软件推荐!

除了Goodnotes和Notability&#xff0c;你还知道哪些值得推荐的免费笔记软件吗&#xff1f;本文结合自己的使用经验&#xff0c;推荐笔记软件的同时&#xff0c;亦推荐一些不错的绘图软件供大家选择使用。 1.OneNote 基本的笔记功能都有&#xff0c;加粗、倾斜、下划线、突…

TPlink云路由器界面端口映射设置方法?快解析内网穿透能实现吗?

有很多网友在问&#xff1a;TPlink路由器端口映射怎么设置&#xff1f;因为不懂端口映射的原理&#xff0c;所以无从下手&#xff0c;下面小编就给大家分享TPlink云路由器界面端口映射设置方法&#xff0c;帮助大家快速入门TP路由器端口映射设置方法。 1.登录路由器管理界面&a…

高等数学中如何求间断点

高等数学中求间断点是一项重要的技巧&#xff0c;特别适用于分析函数的性质和图像的特征。在本文中&#xff0c;我们将深入探讨如何在给定函数中找到间断点&#xff0c;并解释其数学原理和实际应用。 什么是间断点&#xff1f; 在高等数学中&#xff0c;间断点是指函数在某个点…

【C++从0到王者】第十四站:list基本使用及其介绍

文章目录 一、list基本介绍二、list基本使用1.尾插头插接口使用2.insert接口使用3.查找某个值所在的位置4.erase接口使用以及迭代器失效5.reverse6.sort7.merge8.unique9.remove11.splice 三、list基本使用完整代码 一、list基本介绍 如下所示&#xff0c;是库里面对list的基本…