USB -- STM32F103复合设备(HID+MassStorage)传输讲解(十)

目录

链接快速定位

前沿  

1 描述符讲解

1.1 设备描述符

1.2 配置描述符

1.3 接口描述符

1.4 功能描述符

1.5 端点描述符

1.6 字符串描述符

1.7 报告描述符

    2 运行演示


链接快速定位

USB -- 初识USB协议(一)

源码下载请参考链接:USB -- STM32-FS-USB-Device驱动代码简述(二)

USB -- STM32F103虚拟串口bulk传输讲解(三)

USB -- STM32F103自定义HID设备及HID上位机中断传输讲解(四)

USB -- STM32F103 U盘(MassStorage)SDIO接口SCSI协议Bulk传输讲解(五)

USB -- STM32F103 USB DFU设备固件升级(IAP)控制传输讲解(六)

USB -- STM32F103 USB AUDIO(音频)Speak同步传输(Out传输)讲解(七)

USB -- STM32F103 USB AUDIO(音频)Microphone同步传输(In传输)讲解(八)

USB -- STM32F103 USB VIDEO(视频)Camera同步传输讲解(九)

前沿  

        前面两节主要是对USB的基本概念做了简单讲解,学习USB的最本质目的还是要回到USB的应用方向,接下来的几章主要讲解USB的各类应用,包括:

  • 虚拟串口(环回测试)-- bulk传输(USB -- STM32F103虚拟串口bulk传输讲解(三))
  • 自定义HID -- 中断传输(USB -- STM32F103自定义HID设备及HID上位机中断传输讲解(四))
  • U盘 -- bulk传输(USB -- STM32F103 U盘(MassStorage)SDIO接口SCSI协议Bulk传输讲解(五))
  • 在线固件升级(DFU)-- 控制传输(USB -- STM32F103 USB DFU设备固件升级(IAP)控制传输讲解(六))
  • 语音录制及播放 -- 同步Out传输(USB -- STM32F103 USB AUDIO(音频)Speak同步传输(Out传输)讲解(七))
  • 语音录制及播放 -- 同步In传输(USB -- STM32F103 USB AUDIO(音频)Microphone同步传输(In传输)讲解(八))
  • 照相机 -- 同步传输(USB -- STM32F103 USB VIDEO(视频)Camera同步传输讲解(九))
  • 复合设备 -- 中断+bulk传输(本章讲解)

        由于前面的章节已经对HID和MassStorage进行了详细的讲解,这里只简单讲解一下描述符,具体的请参见:

  • USB -- STM32F103自定义HID设备及HID上位机中断传输讲解(四)
  • USB -- STM32F103 U盘(MassStorage)SDIO接口SCSI协议Bulk传输讲解(五)

1 描述符讲解

        描述符是USB能够正常通信的前提,没有描述符,USB就不知道当前是什么样的设备,所以描述符在USB整个通信过程中占有十分重要的地位,所以这里重点讲解一下USB的各类描述符。

        ST的例程为我们配置好了应用的描述符,我们不需要关注也能正常运行程序,但是我们这里讲解一下怎么通过查找资料来知道具体描述符的含义。

1.1 设备描述符

        以下是STM32F103系列的符合设备的设备描述符代码(每个字节对应的含义可以在USB -- 初识USB协议(一)中查看):

/* USB Standard Device Descriptor */
const uint8_t Composite_DeviceDescriptor[Composite_SIZ_DEVICE_DESC] ={0x12,                       /*bLength */USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/0x00,                       /*bcdUSB */0x02,0x00,                       /*bDeviceClass*/0x00,                       /*bDeviceSubClass*/0x00,                       /*bDeviceProtocol*/0x40,                       /*bMaxPacketSize40*/0x83,                       /*idVendor (0x0483)*/0x04, 0x50,                       /*idProduct = 0x5750*/0x57,0x00,                       /*bcdDevice rel. 2.00*/0x02,1,                          /*Index of string descriptor describingmanufacturer */2,                          /*Index of string descriptor describingproduct*/3,                          /*Index of string descriptor describing thedevice serial number */0x01                        /*bNumConfigurations*/}; /* Composite_DeviceDescriptor */

        设备描述符顾名思义就是描述USB设备的基本信息,主要包括以下信息:

  • USB版本号
  • USB设备类型
  • USB设备协议
  • 端点0最大传输大小(最大64byte)
  • 厂商向USBIF申请的VID(需付费,由芯片厂商提供)
  • 设备PID(厂商自定义)
  • 制造商的字符串描述符索引(描述生产这个产品的厂商)
  • 产品的字符串描述符索引(描述是什么产品)
  • 设备序号的字符串描述符索引(主要是芯片的UID)
  • 配置的数量(一般为1)

        制造商的字符串描述符索引、产品的字符串描述符索引和设备序号的字符串描述符索引主要是制造商、产品和设备序列号在字符串描述符的索引位置。

        比如这里举个例子,以下三个是字符串描述符,分别是制造商描述符、产品描述符和序列号描述符:

const uint8_t Composite_StringVendor[Composite_SIZ_STRING_VENDOR] ={Composite_SIZ_STRING_VENDOR, /* Size of Vendor string */USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType*//* Manufacturer: "STMicroelectronics" */'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,'c', 0, 's', 0};const uint8_t Composite_StringProduct[Composite_SIZ_STRING_PRODUCT] ={Composite_SIZ_STRING_PRODUCT,          /* bLength */USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'C', 0,'o', 0, 'm', 0, 'p', 0, 'o', 0, 's', 0, 'i', 0, 't', 0,'e', 0,' ',0, 'M', 0, 'S', 0, 'C', 0, '+', 0, 'H', 0, 'I', 0, 'D', 0};
uint8_t Composite_StringSerial[Composite_SIZ_STRING_SERIAL] ={Composite_SIZ_STRING_SERIAL,           /* bLength */USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */'S', 0, 'T', 0, 'M', 0,'3', 0,'2', 0};

    由下面代码可知,他们的位置也是根据索引号排列的,所以主机请求index为1的描述符,那么设备就发送制造商描述符给主机,告诉主机USB的制造商是什么。

ONE_DESCRIPTOR String_Descriptor[4] ={{(uint8_t*)Composite_StringLangID, Composite_SIZ_STRING_LANGID},{(uint8_t*)Composite_StringVendor, Composite_SIZ_STRING_VENDOR},{(uint8_t*)Composite_StringProduct, Composite_SIZ_STRING_PRODUCT},{(uint8_t*)Composite_StringSerial, Composite_SIZ_STRING_SERIAL}};

        如果设备描述符的索引值修改了,那么String_Descriptor数组存放数据的顺序也需要相应的修改。

        VID可以通过USB官网:USB_Members查看,比如这里的是ST的VID,0x0483的10进制是1155,我们在USB官网查看,如下:

1.2 配置描述符

        配置描述符顾名思义就是描述USB设备的配置信息,主要包括以下信息:

  • USB接口的数量(会在接口描述符讲解)
  • USB的配置值(一般为1,根据设备描述符配置数量决定)
  • USB的供电信息
  • USB的最大电流
const uint8_t Composite_ConfigDescriptor[] ={0x09, /* bLength: Configuration Descriptor size */USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */Composite_SIZ_CONFIG_DESC,/* wTotalLength: Bytes returned */0x00,0x02,         /* bNumInterfaces: 2 interfaces */0x01,         /* bConfigurationValue: Configuration value */0x00,         /* iConfiguration: Index of string descriptor describingthe configuration*/0xC0,         /* bmAttributes: Self powered */0x32,         /* MaxPower 100 mA: this current is used for detecting Vbus */}

1.3 接口描述符

        这里的接口描述符有两个,由配置描述符指定个数。一个接口描述HID设备,另一个接口描述MassStorage设备,详细的解释可以参考博主以前的博客。

uint8_t Composite_InterfaceDescriptor[ ] = 
{/************** Descriptor of Custom HID interface ****************//* 09 */0x09,         /* bLength: Interface Descriptor size */USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */0x00,         /* bInterfaceNumber: Number of Interface */0x00,         /* bAlternateSetting: Alternate setting */0x02,         /* bNumEndpoints */0x03,         /* bInterfaceClass: HID */0x00,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */0x00,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */0,            /* iInterface: Index of string descriptor */。。。/******************** Descriptor of Mass Storage interface ********************//* 09 */0x09,   /* bLength: Interface Descriptor size */0x04,   /* bDescriptorType: *//*      Interface descriptor type */0x01,   /* bInterfaceNumber: Number of Interface */0x00,   /* bAlternateSetting: Alternate setting */0x02,   /* bNumEndpoints*/0x08,   /* bInterfaceClass: MASS STORAGE Class */0x06,   /* bInterfaceSubClass : SCSI transparent*/0x50,   /* nInterfaceProtocol */1,          /* iInterface: */}

1.4 功能描述符

        这里只有HID的功能描述符,主要是引出报告描述符。

uint8_t Composite_FunctionalDescriptor[ ] = 
{/******************** Descriptor of Custom HID HID ********************//* 18 */0x09,         /* bLength: HID Descriptor size */HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */0x10,         /* bcdHID: HID Class Spec release number */0x01,0x00,         /* bCountryCode: Hardware target country */0x01,         /* bNumDescriptors: Number of HID class descriptors to follow */0x22,         /* bDescriptorType */CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */0x00,}

1.5 端点描述符

        这里用到4个端点,分别是HID使用两个和MassStorage使用两个,具体的解释可参见USB -- 初识USB协议(一)。

uint8_t Compositet_EndpointDescriptor[ ] = 
{/******************** Descriptor of Custom HID endpoints ******************//* 27 */0x07,          /* bLength: Endpoint Descriptor size */USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */0x81,          /* bEndpointAddress: Endpoint Address (IN) */0x03,          /* bmAttributes: Interrupt endpoint */0x02,          /* wMaxPacketSize: 2 Bytes max */0x00,0x20,          /* bInterval: Polling Interval (32 ms) *//* 34 */0x07,	/* bLength: Endpoint Descriptor size */USB_ENDPOINT_DESCRIPTOR_TYPE,	/* bDescriptorType: *//*	Endpoint descriptor type */0x01,	/* bEndpointAddress: *//*	Endpoint Address (OUT) */0x03,	/* bmAttributes: Interrupt endpoint */0x02,	/* wMaxPacketSize: 2 Bytes max  */0x00,0x20,	/* bInterval: Polling Interval (20 ms) */。。。0x07,   /*Endpoint descriptor length = 7*/0x05,   /*Endpoint descriptor type */0x82,   /*Endpoint address (IN, address 2) */0x02,   /*Bulk endpoint type */0x40,   /*Maximum packet size (64 bytes) */0x00,0x00,   /*Polling interval in milliseconds *//* 25 */0x07,   /*Endpoint descriptor length = 7 */0x05,   /*Endpoint descriptor type */0x02,   /*Endpoint address (OUT, address 2) */0x02,   /*Bulk endpoint type */0x40,   /*Maximum packet size (64 bytes) */0x00,0x00     /*Polling interval in milliseconds*/}

1.6 字符串描述符

        在设备描述符中已经对制造商描述符、产品描述符和设备序号描述符做了说明,这里仅对语言ID描述符做简单说明。

        语言ID描述符相对很简单,就是告诉主机用的哪种语言编码,这里一般选择0x0409,使用美国的编码。一般使用最多的也是美国编码。

/* USB String Descriptors (optional) */
const uint8_t Composite_StringLangID[Composite_SIZ_STRING_LANGID] ={Composite_SIZ_STRING_LANGID,USB_STRING_DESCRIPTOR_TYPE,0x09,0x04}; /* LangID = 0x0409: U.S. English */

1.7 报告描述符

        参见:USB -- STM32F103自定义HID设备及HID上位机中断传输讲解(四)

    2 运行演示

        在运行演示之前,至少需要修改D+的上拉电阻控制pin脚和操作nand flash的函数,具体可以参考(具体的操作演示也需参见下面链接,这里就不多做解释了):

  • USB -- STM32F103自定义HID设备及HID上位机中断传输讲解(四)
  • USB -- STM32F103 U盘(MassStorage)SDIO接口SCSI协议Bulk传输讲解(五)

        下载程序,在设备管理器能够查看到HID设备和大容量设备,证明枚举成功。

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

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

相关文章

java中PhantomReference WeakReference SoftReference垃圾回收触发时机以及使用场景

java 中对象引用一般引用分为四种情况 强引用 即我们平常创建的对象 Object obj new Object() 垃圾回收触发时机 在没设置 jvm 参数 -XX:PretenureSizeThreshold 和 -XX:MaxTenuringThreshold 的情况下 -XX:PretenureSizeThreshold 的值为 0,即未设置大对象直接…

三巨头对决:深入了解pnpm、yarn与npm

欢迎来到我的博客,代码的世界里,每一行都是一个故事 三巨头对决:深入了解pnpm、yarn与npm 前言包管理器简介npm(Node Package Manager):Yarn:pnpm(Performant Npm)&#…

基于Mapify的在线艺术地图设计

地图是传递空间信息的有效载体,更加美观、生动的地图产品也是我们追求目标。 那么,我们如何才能制出如下图所示这样一幅艺术性较高的地图呢?今天我们来一探究竟吧! 按照惯例,现将网址给出: https://www.m…

SpringBoot知识

1、Spring和SpringBoot对比 2、版本调整 (1)先排除是否是JDK与SpringBoot的版本不一致导致的:如JDK1.8和SpringBoot3.1.5冲突; (2)调整编译版本 (3)调整maven的jdk (4&…

Vscode运行调试文件

文章目录 vscode调试运行流程vscode 执行报错settings.json成功截图 vscode调试运行流程 vscode左侧菜单栏点击运行调试icon,点击菜单右侧栏运行和调试按钮,选择node调试器,js文件行数左边点击添加红色断点,运行当前文件 vscode…

【docker实战】01 Linux上docker的安装

Docker CE是免费的Docker产品的新名称,Docker CE包含了完整的Docker平台,非常适合开发人员和运维团队构建容器APP。 Ubuntu 14.04/16.04(使用 apt-get 进行安装) # step 1: 安装必要的一些系统工具 sudo apt-get update sudo ap…

湘潭大学-2023年下学期-c语言-作业0x0a-综合1

A 求最小公倍数 #include<stdio.h>int gcd(int a,int b) {return b>0?gcd(b,a%b):a; }int main() {int a,b;while(~scanf("%d%d",&a,&b)){if(a0&&b0) break;printf("%d\n",a*b/gcd(a,b));}return 0; }记住最大公约数的函数&…

如何编写一个javaAgent jar工具包超详细教程

介绍 Java Agent技术 Java Agent技术是JDK提供的用来编写Java工具的技术&#xff0c;使用这种技术生成一种特殊的jar包&#xff0c;这种jar包可以让Java程序 运行其中的代码。 Java Agent技术的两种模式 Java Agent技术实现了让Java程序执行独立的Java Agent程序中的代码…

【机组期末速成】CPU的结构与功能|CPU结构|指令周期概述|指令流水线|中断系统

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;计算机组成原理&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 前言&#xff1a; 最近在备战期末考试&#xff0c;所以本专栏主要是为了备战期末计算机组成原理这门考试&#xff0c;讲的比较浅显&…

详解Keras3.0 Layer API: Dropout layer

Dropout layer 图1 标准的神经网络 图2 加了Dropout临时删除部分神经元 Dropout层的作用是在神经网络中引入正则化&#xff0c;以防止过拟合。它通过随机丢弃一部分神经元&#xff08;如图2&#xff09;的输出来减少模型对训练数据的依赖性。这样可以提高模型的泛化能力&#x…

C++初阶——基础知识(函数重载与引用)

目录 1.命名冲突 2.命名空间 3.缺省参数 4.函数重载 1.函数重载的特点包括&#xff1a; 2.函数重载的好处包括&#xff1a; 3.引用 引用的特点包括 引用的主要用途包括 引用和指针 引用 指针 类域 命名空间域 局部域 全局域 第一个关键字 命名冲突 同一个项目之间冲…

二分查找--二分查找算法(朴素二分模板)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 本题题目链接https://leetcode.cn/problems/binary-search/description/ 算法原理 二段性&#xff0c;我们发现这个数组可以找到某种规律将其分为两段&#xff0c;不断划分下去&#xff0c;最终可以找到target 图示 我们分…

图灵日记之java奇妙历险记--继承和多态

目录 继承概念继承语法父类成员访问子类中访问父类的成员变量子类中访问父类的成员方法 super关键字子类构造方法super和this初始化protected关键字继承方式final 关键字继承与组合 多态条件向上转型重写动态绑定&&静态绑定多态再理解向下转型多态的优缺点好处缺陷 继承…

Element|InfiniteScroll 无限滚动组件的具体使用方法

目录 InfiniteScroll 无限滚动 基本用法 详细说明 v-infinite-scroll 指令 infinite-scroll-disabled 属性 infinite-scroll-distance 属性 总结 需求背景 &#xff1a; 项目统计管理列表页面&#xff0c;数据量过多时在 IE 浏览器上面会加载异常缓慢&#xff0c;导致刚…

如何通过易舟云财务软件,查看会计账簿的明细账?

如何通过易舟云财务软件&#xff0c;查看会计账簿的明细账&#xff1f; 前言1、会计账簿2、会计明细账 财务软件操作步骤 前言 1、会计账簿 财务软件是一种用于管理和记录企业财务活动的电子工具。会计账簿是财务软件中的一个重要功能&#xff0c;用于记录和管理企业的会计信…

superset利用mysql物化视图解决不同数据授权需要写好几次中文别名的问题

背景 在使用superset时&#xff0c;给不同的人授权不同的数据&#xff0c;需要不同的数据源&#xff0c;可视化字段希望是中文&#xff0c;所以导致不同的人需要都需要去改表的字段&#xff0c;因此引入视图&#xff0c;将视图中字段名称设置为中文 原表数据 select * from …

将按键次数写入AT24C02,再读出并用1602LCD显示

#include<reg51.h> //包含单片机寄存器的头文件 #include<intrins.h> //包含_nop_()函数定义的头文件 sbit RSP2^0; //寄存器选择位&#xff0c;将RS位定义为P2.0引脚 sbit RWP2^1; //读写选择位&#xff0c;将RW位定义为P2.1引脚 s…

【面试】 Maven 的八大核心概念

Maven 的八大核心概念 在这里&#xff0c;举出这个标题&#xff0c;自然大家知道Maven是干啥的&#xff0c;就不过多进行赘述&#xff01;我们主要对于Maven的八大核心概念做一个解释补充&#xff0c;这也是我自己的一个学习历程&#xff0c;我们一起共勉&#xff01; 文章概述…

word中MathType公式编号

直接上效果图&#xff1a; 步骤如下&#xff1a; 安装MathTypeword中安装MathType选项卡。设置MathType选项卡添加分隔符插入公式&#xff0c;自动生成右编码 接下来介绍每一步。 文章目录 1. 安装MathType2. Word中安装MathType选项卡3. 配置MathType选项4. 添加分隔符5. 插…

Java注解以及自定义注解

Java注解以及自定义注解 要深入学习注解&#xff0c;我们就必须能定义自己的注解&#xff0c;并使用注解&#xff0c;在定义自己的注解之前&#xff0c;我们就必须要了解Java为 我们提供的元注解和相关定义注解的语法。 1、注解 1.1 注解的官方定义 注解是一种元数据形式。…