STM32:Custom HID实现USB双向通信

news2024/11/27 2:22:47

本文章主要讲了使用STM32的USB Device,实现控制板和电脑通信功能。从而实现,上位机对控制板进行调试。

USB Device可以有多种类型,实现双向通信的话,推荐使用Custom HID类型。

首先使用STM32CubeMx实现功能引脚配置并且生成对应的工程文件。

 

Middleware设置USB_DEVICE

 

 配置时钟,USB设置为48MHz。

 生成驱动代码和工程:

生成的代码还有点问题,修改对应的CUSTOM_HID_ReportDesc_FS。 

/** Usb HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
    /* USER CODE BEGIN 0 */
    0x06,0xFF,0x00,     // USAGE_PAGE (Vendor Page: 0xFF00) ±íʾһ¸ö±¨ÎıêÇ©Ö®ÀàµÄÓÃ;ÀàÒ³
    0x09,0x01,          // USAGE (Vendor Usage 1) ±íʾһ¸ö±¨¸æID±êÖ¾
    0xA1,0x01,          // COLLECTION (Application) ±íʾӦÓü¯ºÏ£¬ÒªÒÔÏÂÃæ×îºóµÄ0xc0½áÊøËü
    0x15,0x00,          // LOGICAL_MINIMUM (0) ±íʾÿ¸ö´«ÊäÊý¾ÝÏÞ¶¨Îª0
    0x26,0xFF,0x00,     // LOGICAL_MAXIMUM (255) ±íʾÿ¸ö´«ÊäÊý¾ÝµÄ×î´óÖµÏÞ¶¨Îª255
    0x75,0x08,          // REPORT_SIZE (8) ´«Êä×ֶεĿí¶ÈΪ8bit£¬±íʾÿ¸ö´«ÊäµÄÊý¾Ý·¶Î§Îª0~ffff ffff
    0x95,0x40,          // REPORT_COUNT (64)ÿ´Î·¢Ë͵ÄÊý¾Ý³¤¶È£¬ÕâÀïÊÇ64λ
    0x09,0x02,          // USAGE (Vendor Usage 2) ±íʾһ¸ö±¨¸æID±êÖ¾
    0x81,0x02,          // INPUT (Data,Var,Abs) ±íʾUSBÒªÊäÈëÊý¾Ýµ½PCµÄ¹¦ÄÜ
    0x09,0x03,          // USAGE (Vendor Usage 3) ±íʾһ¸ö±¨¸æID±êÖ¾
    0x91,0x02,          // OUTPUT (Data,Var,Abs) ±íʾUSBÉ豸Ҫ½ÓÊÕPCµÄÊý¾ÝµÄ¹¦ÄÜ
    0x0A,0x00,0xFF,     // UsageS(0xFF00)
    0x0B1,0x02,         // feature (data, variable, absolute)
    /* USER CODE END 0 */
    0xC0                  // END_COLLECTION ½áÊø±êÖ¾

};

 配置数据长度:

/*---------- -----------*/
#define USBD_MAX_NUM_INTERFACES     1U
/*---------- -----------*/
#define USBD_MAX_NUM_CONFIGURATION     1U
/*---------- -----------*/
#define USBD_MAX_STR_DESC_SIZ     512U
/*---------- -----------*/
#define USBD_DEBUG_LEVEL     0U
/*---------- -----------*/
#define USBD_LPM_ENABLED     1U
/*---------- -----------*/
#define USBD_SELF_POWERED     1U
/*---------- -----------*/
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE     64U
/*---------- -----------*/
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE     30U
/*---------- -----------*/
#define CUSTOM_HID_FS_BINTERVAL     0x1U

 usbd_customhid.c

#define CUSTOM_HID_EPIN_ADDR                         0x81U
#define CUSTOM_HID_EPIN_SIZE                         0x40U

#define CUSTOM_HID_EPOUT_ADDR                        0x02U
#define CUSTOM_HID_EPOUT_SIZE                        0x40U

#define USB_CUSTOM_HID_CONFIG_DESC_SIZ               41U
#define USB_CUSTOM_HID_DESC_SIZ                      9U

#ifndef CUSTOM_HID_HS_BINTERVAL
#define CUSTOM_HID_HS_BINTERVAL                      0x05U
#endif /* CUSTOM_HID_HS_BINTERVAL */

#ifndef CUSTOM_HID_FS_BINTERVAL
#define CUSTOM_HID_FS_BINTERVAL                      0x05U
#endif /* CUSTOM_HID_FS_BINTERVAL */

#ifndef USBD_CUSTOMHID_OUTREPORT_BUF_SIZE
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE            0x64U
#endif /* USBD_CUSTOMHID_OUTREPORT_BUF_SIZE */

#ifndef USBD_CUSTOM_HID_REPORT_DESC_SIZE
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE             30U
#endif /* USBD_CUSTOM_HID_REPORT_DESC_SIZE */

#define CUSTOM_HID_DESCRIPTOR_TYPE                   0x21U
#define CUSTOM_HID_REPORT_DESC                       0x22U

#define CUSTOM_HID_REQ_SET_PROTOCOL                  0x0BU
#define CUSTOM_HID_REQ_GET_PROTOCOL                  0x03U

#define CUSTOM_HID_REQ_SET_IDLE                      0x0AU
#define CUSTOM_HID_REQ_GET_IDLE                      0x02U

#define CUSTOM_HID_REQ_SET_REPORT                    0x09U
#define CUSTOM_HID_REQ_GET_REPORT                    0x01U

 

 

#include "usb_device.h"
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_customhid.h"
#include "usbd_custom_hid_if.h"
#include "usart.h"

/* USER CODE BEGIN Includes */

unsigned char USB_Send_Buffer[64] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
unsigned char USB_Recive_Buffer[64] = {1,2,3,4,5,6,7,8,9,}; //USB½ÓÊÕ»º´æ
unsigned char USB_Received_Count = 0;//USB½ÓÊÕÊý¾Ý¼ÆÊý

/* USER CODE END Includes */

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USB Device Core handle declaration. */
USBD_HandleTypeDef hUsbDeviceFS;

/*
 * -- Insert your variables declaration here --
 */
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/*
 * -- Insert your external function declaration here --
 */
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/**
  * Init USB device Library, add supported class and start the library
  * @retval None
  */
void MX_USB_DEVICE_Init(void)
{
  /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
  /* USER CODE END USB_DEVICE_Init_PreTreatment */

  /* Init Device Library, add supported class and start the library. */
  if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
  {
    Error_Handler();
  }
  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CUSTOM_HID) != USBD_OK)
  {
    Error_Handler();
  }
  if (USBD_CUSTOM_HID_RegisterInterface(&hUsbDeviceFS, &USBD_CustomHID_fops_FS) != USBD_OK)
  {
    Error_Handler();
  }
  if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */

  /* USER CODE END USB_DEVICE_Init_PostTreatment */
}

void Usbd_Send_Test(void)
{

    Usart_Printf("USBD_CUSTOM_HID_SendReport!\r\n");
    USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, USB_Send_Buffer, 64);
}

void Usbd_Receive_Test(void)
{
    Usart_Printf("\r\nUsbd_Receive_Test:\r\n");
    for(int i = 0; i < 64; i++)
    {
        Usart_Printf("%02x", USB_Recive_Buffer[i]);
    }
}

 发送测试:

 

 接收测试:

 

 

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

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

相关文章

Win11的两个实用技巧系列之关闭输入法悬浮窗方法、记住窗口位置禁用或启用的方法

Win11输入法悬浮窗怎么去掉? win11关闭输入法悬浮窗方法 Win11输入法悬浮窗怎么去掉&#xff1f;win11安装的输入法有悬浮窗&#xff0c;想要去掉悬浮窗&#xff0c;该怎么操作呢&#xff1f;下面我们就来看看win11关闭输入法悬浮窗方法 很多用户将自己win11更新到了最新版本…

面试题 16.02. 单词频率

设计一个方法&#xff0c;找出任意指定单词在一本书中的出现频率。 你的实现应该支持如下操作&#xff1a; WordsFrequency(book)构造函数&#xff0c;参数为字符串数组构成的一本书get(word)查询指定单词在书中出现的频率 示例&#xff1a; WordsFrequency wordsFrequency …

git cherry-pick 用法

1. 切换到目标分支 说明&#xff1a;本人基于 master 新建分支 master-fxd&#xff0c;那么目标分支为 master-fxd git checkout <target-branch>2. 从其他分支选择并应用单个提交 说明&#xff0c;其他分支例如 dev 提交的代码&#xff0c;使用 jihulab.com 比较 master…

针对WordPress程序无法升级最新版本的问题分析

WordPress程序是当前使用率最高的CMS系统之一&#xff0c;因开发功能完善&#xff0c;WordPress模板和插件众多而著称&#xff0c;茹莱神兽做三个网站&#xff0c;其中有两个网站使用的是WordPress程序搭建&#xff0c;可见它的受欢迎程度。 而WordPress程序本身也相当给力&a…

刷简单的题也很吃力怎么办?(经验分享)

目录 一、前言 1.刷简单的题也很吃力怎么办&#xff1f; 2.不重视这种问题会怎么样&#xff1f; 二、找到属于自己的解决方案 三、根据问题进行分解或建立思维导图​​​​​​​ 四、分享刷题网站 一、前言 1.刷简单的题也很吃力怎么办&#xff1f; 有的时候在当时学完…

ZMQ在windows下配合VS2017使用(c++)

ZMQ专题学习之四&#xff1a;libzmq的发布及订阅方式_jyl_sh的博客-CSDN博客 一、背景介绍 高速并发消息通信框架——ZeroMQ详解&#xff08;一&#xff09; - 知乎 (zhihu.com) zmq将socket进行了封装&#xff0c;可以快速在两个进程间进行通信 二、编译libzip https:/…

超详细Redis入门教程——Redis缓存

前言 本文小新为大家带来 Redis缓存 相关知识&#xff0c;具体内容包括Jedis客户端&#xff08;包括&#xff1a;Jedis简介&#xff0c;创建工程&#xff0c;使用 Jedis 实例&#xff0c;使用 JedisPool&#xff0c;使用 JedisPooled&#xff0c;连接 Sentinel 高可用集群&…

锂电池组冷却模型

文章最下方的长方形小方框内有博主的QQ名片获取本文同款程序 硕博期间所有的程序代码&#xff0c;一共2个多g&#xff0c;可以给你指导&#xff0c;赠送半个小时的语音电话答疑。电池数据辨识程序各种卡尔曼滤波算法都在里面了&#xff0c;后续还会有新模型的更新。快速入门BM…

初识栈溢出 pwn02

题目给了一个链接和端口 pwn.challenge.ctf.show 28183&#xff0c;可以nc看一下 题目给的链接和端口的其实是用来放进我们编写的exp脚本的 还给了一个附件 stack 下载好后拖进kali使用file和checksec命令检查一下 发现是一个32位的程序 No canary found 表示没有金丝雀保…

Stable Diffusion 多角度人设立绘快速生成多种方法

对于插画师构建人物立绘图设计一套多方位的人设可能要很久&#xff0c;但是使用SD进行操作的话就非常简单了&#xff0c;这个利用ControlNet骨骼图进行配置操作。 供一些样图参考&#xff0c;也可以使用ADetailer进行人物相关部位的修复。 文章目录 准备工作关键词绘制使用骨骼…

深入理解ASEMI整流桥KBP210特性及其应用

编辑-Z 在电子工程领域&#xff0c;整流器是一种重要的元件&#xff0c;它能将交流电&#xff08;AC&#xff09;转换为直流电&#xff08;DC&#xff09;。其中&#xff0c;整流桥KBP210是一种常见的整流器&#xff0c;因其优秀的性能和广泛的应用&#xff0c;受到了工程师们…

【专题速递】大模型、带宽优化、智能外呼和AIGC的数据实践

// ChatGPT的爆发为音视频带来了怎样的革新&#xff1f;AIGC又将如何辅助音视频技术为用户带来更好的体验&#xff1f;7月29日LiveVideoStackCon上海站AI与多媒体专场&#xff0c;为您解答。 AI与多媒体 随着生活方式及习惯的变化&#xff0c;人们对于媒体内容与体验有着更高…

8、离线数仓同步数据

1、 用户行为数据同步 1.1、 数据通道 用户行为数据由Flume从Kafka直接同步到HDFS&#xff0c;由于离线数仓采用Hive的分区表按天统计&#xff0c;所以目标路径要包含一层日期。具体数据流向如下图所示。 1.2、 日志消费Flume配置概述 按照规划&#xff0c;该Flume需将Kafka…

案例挑战——事务传播行为

事务的传播行为 一、背景介绍二、 什么是事物的传播行为常见的事物传播行为mandatorysupportsrequiredrequired_newnestednot supportnever 三、为什么要有事务的传播行为&#xff0c;它是为了解决什么问题&#xff1f;四、如何使用事务的传播行为外围方法没有事务&#xff0c;…

audio标签如何去掉controls属性上的下载和倍速

<audioref"audioPlayer":src"data.url"controlstimeupdate"updateProgress" ></audio> controlslist 属性将帮助浏览器选择在媒体元素上显示的控件。 <audioref"audioPlayer":src"data.url"controlscontrol…

【Hello mysql】 数据库表操作

Mysql专栏&#xff1a;Mysql 本篇博客简介&#xff1a;介绍数据库的表操作 数据库表操作 创建表查看表结构修改表添加列修改列删除列修改表名修改列名 删除表总结 创建表 语法 CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set…

Facebook 商务管理:成为 Facebook 业务经理大师的关键

Facebook 商务管理&#xff1a;成为 Facebook 业务经理大师的关键 尽管社交媒体行业有许多冉冉升起的新星&#xff0c;但Facebook仍然是不败的冠军。Facebook每月活跃用户超过2.85亿&#xff0c;在受欢迎程度方面遥遥领先于同行&#xff0c;它无疑是您业务的绝佳免费营销工具。…

一亿港元的“入场费”?香港合规门槛太高,加密从业者仍选择观望!

6月1日&#xff0c;备受瞩目的香港加密新规正式生效&#xff0c;但靴子落地&#xff0c;市场预期却不及以往&#xff0c;想象中人声鼎沸的讨论并未出现。尽管蔓延的熊市仍负主要责任&#xff0c;但仍有很多因素使从业者观望态度。 合规门槛太高&#xff1f; 纵观圈内&#xff0…

Python编程实现针对回撤的交易策略

在金融交易市场上&#xff0c;回撤是一个常见的现象。因此&#xff0c;对于投资者来说&#xff0c;研究和设计针对回撤的交易策略是非常必要的。本文将介绍如何使用Python编程实现针对回撤的交易策略&#xff0c;以帮助投资者更好地进行交易。 一、回撤分析 在设计针对回撤的…

智能导航:独家互联网网站推荐指南

在数字化时代&#xff0c;人们对于影视娱乐的需求日益增长。而随着高速互联网的普及和技术的进步&#xff0c;极速冲浪成为了探索各种精彩影视作品的主流方式。众多影视网站应运而生&#xff0c;为我们提供了丰富多样的内容&#xff0c;并以便捷的方式满足我们对于电影、剧集和…