spring boot 网站开发/网站空间费用一年多少

spring boot 网站开发,网站空间费用一年多少,wordpress微商城模板下载,网站模板免费下载网站简介 USB CDC(communication device class)类是usb2.0标准下的一个子类,定义了通信相关设备的抽象集合。usb2.0标准下定义了很多子类,有音频类,CDC类,HID类,打印,大容量存储类&…

简介

USB CDC(communication device class)类是usb2.0标准下的一个子类,定义了通信相关设备的抽象集合。usb2.0标准下定义了很多子类,有音频类,CDC类,HID类,打印,大容量存储类,HUB和智能卡等等。

在这里插入图片描述

CDC类下根据应用场合,又分为多个子类,官方文档主要讲的是PSTN。PSTN(Public Switched Telephone Network)是一个与电信相关的子类,这里只是将其当作一个普通的通信设备使用,并没有使用它的一些电话特性。

使用USB中的CDC类来虚拟串口 Virtual COM Port (VCP)进行通讯是一种非常好用的方式,一方面对于上位机来说显示出来的就是一个串口,所有操作都还是对串口的操作;另一方面实际数据传输是基于USB的,数据传输速度得到大大提升。并且STM32 CDC VCP对于win10和较新版本的Linux来说是免驱的。

示例

使用STM32CubeIDE生成代码。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

将代码编译烧录后,我们可以看到多了一个串口设备。

在这里插入图片描述

其他说明

从USB版本来说目前STM32系列MCU可以认为都是USB2.0的。从硬件接口功能上来说STM32系列MCU的USB分为 USB_FS 、 USB_OTG_FS 、 USB_OTG_HS 三种。其中的FS指的是全速(Full Speed),HS指的是高速(High Speed)。OTG指的是既可以作为Device(从设备)使用,也可以作为Host(主机)使用。

Full Speed 理论上速度为12Mbit/s,High Speed 理论上速度为480Mbit/s ,当然这都是理论速度,实际上通讯速度还依赖于所用通讯方式和设备性能。

对于STM32系列MCU而言,USB FS的使用只要使用 DM / D- 和 DP / D+ 这两个引脚就行了,最多也就加上ID、SOF、VBUS这三个引脚。而使用USB HS大多数还需要外接PHY芯片(比如USB3300),这样使用的引脚就多了,至少也要用到12个引脚。STM32系列MCU中目前只有STM32F723内置USB HS PHY功能,不需要外接PHY芯片。

我们在上面的示例中,是外接了PHY芯片的,所以选择配置的时候是用的USB_HS。

用户代码分析

上述配置生成的代码中,对于用户来说USB使用相关的代码都在 USB_DEVICE > App 中,这其中最重要的就是 usbd_cdc_if.c 文件,大多数时候我们只要改写这个文件就可以实现相关需求了,该文件主要结构与说明如下:

#include "usbd_cdc_if.h"// 数据收发缓存,这部分也可以完全由用户自行定义
uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; // 接收缓存
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; // 发送缓存extern USBD_HandleTypeDef hUsbDeviceFS;// 初始化USB_CDC
static int8_t CDC_Init_FS(void)
{USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0); // 设置发送缓存USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS); // 设置接收缓存
}// 反初始化USB_CDC
static int8_t CDC_DeInit_FS(void){}// 来自主机的请求处理
// cmd: 命令代码
// pbuf & length: 请求数据指针与长度
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)
{switch(cmd){/***********************************************************************************************//* Line Coding Structure                                                                       *//*---------------------------------------------------------------------------------------------*//* Offset | Field       | Size | Description                                                   *//* 0      | dwDTERate   |   4  | Data terminal rate, in bits per second                        *//* 4      | bCharFormat |   1  | Stop bits: 0 - 1 Stop bit; 1 - 1.5 Stop bits; 2 - 2 Stop bits *//* 5      | bParityType |   1  | Parity: 0 - None; 1 - Odd; 2 - Even; 3 - Mark; 4 - Space      *//* 6      | bDataBits   |   1  | Data bits (5, 6, 7, 8 or 16).                                 *//***********************************************************************************************/case CDC_SET_LINE_CODING: break; // 主机设置串口参数}
}// 接收回调函数
// Buf & Len: 当前收到这一包数据指针与长度
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); // 重新设置接收缓存// 注意默认情况下上面一行代码相当于 USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);USBD_CDC_ReceivePacket(&hUsbDeviceFS); // 重新启动数据接收
}// 数据发送函数
// Buf & Len: 要发送的数据指针与长度
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;if (hcdc->TxState != 0){return USBD_BUSY; // 如果当前USB繁忙则返回USBD_BUSY}USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len); // 设置要发送的数据result = USBD_CDC_TransmitPacket(&hUsbDeviceFS); // 发送数据
}// 发送完成回调函数
// Buf & Len: 所送的数据指针与长度
static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum){}

上面代码中最常处理的只有下面四个函数:
CDC_Control_FS() 来自主机请求的回调函数
CDC_Receive_FS() 接收数据回调函数;
CDC_Transmit_FS() 用来发送数据;
CDC_TransmitCplt_FS() 发送完成回调函数;

发送

uint8_t  CDC_Transmit_FS ( uint8_t* Buf,  uint16_t Len );
static int8_t CDC_TransmitCplt_HS(uint8_t *Buf, uint32_t *Len, uint8_t epnum)

我们需要发送数据的时候,需要调用CDC_Transmit_FS函数,该函数的Len参数好像并不会限制在2048。然后我们在发生完成函数中修改如下:

static int8_t CDC_TransmitCplt_HS(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
{uint8_t result = USBD_OK;/* USER CODE BEGIN 14 */printf("CDC_TransmitCplt_HS Len=%d\r\n", *Len);UNUSED(Buf);UNUSED(Len);UNUSED(epnum);/* USER CODE END 14 */return result;
}

在这里插入图片描述

我们可以看到,当一次性发送的数据包大于512的时候,发送函数内部会自动分包,直至发完,就会调用CDC_TransmitCplt_HS函数。接收端好像也会自动组包然后一次性收完?

还有一点需要注意,在发送函数内部,有一个设备状态判断,这意味着如果当前正在发送一包数据,然后你又调用该函数发送一包数据,是会发送失败的。可以理解为发送函数它是一个异步函数,数据真正发完的时候会调用CDC_TransmitCplt_HS函数。所以,我们在发送下一包数据的时候,需要确保上一包数据已经发送完成了,一般可以使用一个信号量进行阻塞之类的。

关于发送函数的总结:

  • 发送函数的数据长度可以大于一包USB数据的长度,函数内部会自动分包。
  • 发送函数是一个异步函数,调用CDC_TransmitCplt_HS函数的时候,数据才真正发完。

接收

当USB CDC接收到来自USB主机的数据时,触发中断进入中断函数,继而自动调用接收回调函数:

int8_t  CDC_Receive_FS (uint8_t* Buf, uint32_t *Len);  
  • uint8_t* Buf: 指向接收缓冲区的指针,即数据缓存的地址。
  • uint16_t* Len: 当前数据包的字节数。

我们将代码改为如下

static int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len)
{/* USER CODE BEGIN 11 */printf("CDC_Receive_HS Len=%d\r\n",*Len);USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &Buf[0]);USBD_CDC_ReceivePacket(&hUsbDeviceHS);return (USBD_OK);/* USER CODE END 11 */
}

然后使用串口助手往底板发送数据的结果如下:

在这里插入图片描述

可以看到,我们串口一次性发送了6868个字节的数据,在底板是分多次接收的。这是为什么呢?这是因为我们在配置USB CDC的时候,USB协议已经规定了一个USB包的数据最大就是512字节,这并不意味着超过512字节的数据帧就不能够发送给单片机,从上例就可以看出,USB协议会自动分包,然后单片机会有多次接收,只是一次接收不能接收所有完整的数据帧。所以,如果有大于512的数据帧时,我们可以在接收端手动组包,将多次接收的一个数据包组成完成的数据帧。组包的机制可以是定义帧头帧尾或者定义包序号,这里就不展开了。

还有一点示例可能看不出来,就是接收函数其实就是一个中断服务函数。所以,我们在该函数中的处理时间应该尽可能的短,因为在接收函数中进行耗时操作时,可能正好有一包数据需要接收,这时可能就会漏收。一般建议在该函数中接收数据时,将数据转存到其他的队列或者缓存空间。

关于接收函数的总结:

  • 如果上位机一次发送的数据帧大于USB最大包长度,那么在接收端需要注意组包。
  • 在接收函数中尽量不要进行耗时的操作,如需处理数据可以先转存到其他地方。

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

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

相关文章

如何修改Windows系统Ollama模型存储位置

默认情况下,Ollama 模型会存储在 C 盘用户目录下的 .ollama/models 文件夹中,这会占用大量 C 盘空间,增加C盘“爆红”的几率。所以,我们就需要修改Ollama的模型存储位置 Ollama提供了一个环境变量参数可以修改Ollama的默认存在位…

Codes 开源免费研发项目管理平台 2025年第一个大版本3.0.0 版本发布及创新的轻IPD实现

Codes 简介 Codes 是国内首款重新定义 SaaS 模式的开源项目管理平台,支持云端认证、本地部署、全部功能开放,并且对 30 人以下团队免费。它通过创新的方式简化研发协同工作,使敏捷开发更易于实施。并提供低成本的敏捷开发解决方案&#xff0…

uniapp 网络请求封装(uni.request 与 uView-Plus)

一、背景 在开发项目中,需要经常与后端服务器进行交互;为了提高开发效率和代码维护性,以及降低重复性代码,便对网络请求进行封装统一管理。 二、创建环境文件 2.1、根目录新建utils文件夹,utils文件夹内新建env.js文…

ESP32-S3 实战指南:BOOT-KEY 按键驱动开发全解析

一、基础知识 本篇我们使用 BOOT 按键来学习一下 GPIO 功能,首先补充一下相关术语介绍。 1、GPIO(General Purpose Input/Output) GPIO 是微控制器上的通用引脚,既可以作为输入(读取外部信号)&#xff0…

初学者如何设置以及使用富文本编辑器[eclipse版]

手把手教你设置富文本编辑器 参考来源:UEditor Docs 初学者按我的步骤来就可以啦 一、设置ueditor编辑器 1.提取文件[文章最底部有链接提取方式] 2.解压文件并放到自己项目中,在WebContent目录下: 3. 修改jar包位置路径 到--> 注意&a…

25轻化工程研究生复试面试问题汇总 轻化工程专业知识问题很全! 轻化工程复试全流程攻略 轻化工程考研复试真题汇总

轻化工程复试心里没谱?学姐带你玩转面试准备! 是不是总觉得老师会问些刁钻问题?别焦虑!其实轻化工程复试套路就那些,看完这篇攻略直接掌握复试通关密码!文中有重点面试题可直接背~ 目录 一、这些行为赶紧避…

企业数据集成:实现高效调拨出库自动化

调拨出库对接调出单-v:旺店通企业奇门数据集成到用友BIP 在企业信息化管理中,数据的高效流转和准确对接是实现业务流程自动化的关键。本文将分享一个实际案例,展示如何通过轻易云数据集成平台,将旺店通企业奇门的数据无缝集成到用…

如何调整CAN位宽容忍度?

CAN位宽容忍度是指在控制器局域网络(CAN, Controller Area Network)中允许时钟同步的误差范围。这是CAN网络正常通信时的关键因素之一,因为CAN协议依赖位同步来确保多个节点在总线上正确解码数据。CAN位宽容忍度确保节点之间由于时钟偏差或抖…

Django-Vue 学习-VUE

主组件中有多个Vue组件 是指在Vue.js框架中,主组件是一个父组件,它包含了多个子组件(Vue组件)。这种组件嵌套的方式可以用于构建复杂的前端应用程序,通过拆分功能和视图,使代码更加模块化、可复用和易于维…

MySql数据库运维学习笔记

数据库运维常识 DQL、DML、DCL 和 DDL 是 SQL(结构化查询语言)中的四个重要类别,它们分别用于不同类型的数据库操作,下面为你简单明了地解释这四类语句: 1. DQL(数据查询语言,Data Query Langu…

如何为自己的 PDF 文件添加密码?在线加密 PDF 文件其实更简单

随着信息泄露和数据安全问题的日益突出,保护敏感信息变得尤为重要。加密 PDF 文件是一种有效的手段,可以确保只有授权用户才能访问或修改文档内容。本文将详细介绍如何使用 CleverPDF 在线工具为你的 PDF 文件添加密码保护,确保其安全性。 为…

UEFI Spec 学习笔记---9 - Protocols — EFI Loaded Image

本节定义EFI_LOADED_IMAGE_PROTOCOL和 EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL。这些协议分别描述了已加载到内存中的映像,并指定了PE/COFF映像通过EFI引导服务LoadImage()加载 时使用的设备路径。这些描述包括 load image 的源、映像在内存中的当前位置、为image分…

pycharm中配置PyQt6详细教程

PyQt6 是 Qt 框架的 Python 绑定库,基于 Qt 6 开发,专为创建跨平台图形用户界面(GUI)应用程序设计。 本章教程,主要记录在pycharm中配置使用PyQt6的流程。 一、安装基础环境 在此之前,你需要提前安装好Python解释器,推荐使用anaconda创建虚拟环境。 conda create -n pyt…

Java+SpringBoot+Vue+数据可视化的综合健身管理平台(程序+论文+讲解+安装+调试+售后)

感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,我会一一回复,希望帮助更多的人。 系统介绍 在当今社会,随着人们生活水平的不断提高和健康意识的日益增强,健…

【从0做项目】Java音缘心动(2)———登录、统一返回设计

阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 一:登录模块设计 1:实体类 2:登录的请求和响应设计 二&#xff…

【Linux网络】认识协议(TCP/UDP)、Mac/IP地址和端口号、网络字节序、socket套接字

⭐️个人主页:小羊 ⭐️所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 1、初识协议2、UDP、TCP3、Mac、IP地址4、端口号5、网络字节序6、socket 1、初识协议 协议就是一种约定。如何让不同厂商生产的计…

【个人开源】——从零开始在高通手机上部署sd(二)

代码:https://github.com/chenjun2hao/qualcomm.ai 推理耗时统计 单位/ms 硬件qnncpu_clipqnncpu_unetqnncpu_vaehtp_cliphtp_unethtp_vae骁龙8 gen124716.994133440.39723.215411.097696.327 1. 下载依赖 下载opencv_x64.tar,提取码: rrbp下载opencv_aarch64.t…

从混沌到有序:一个数据血缘分析的进化故事

从混沌到有序:一个数据血缘分析的进化故事 从混沌到有序的数据治理之路数据血缘的建设方法和实践路径数据血缘的实践场景和未来趋势。 数据就像流淌在企业血管中的血液,它的每一次流动、每一次转化都留下独特的印记。 作为数据工程师,我曾困惑…

图表控件Aspose.Diagram入门教程:使用 Python 将 VSDX 转换为 PDF

将VSDX转换为PDF可让用户轻松共享图表。PDF 文件保留原始文档的布局和设计。它们广泛用于演示文稿、报告和文档。在这篇博文中,我们将探讨如何在 Python 中将 VSDX 转换为 PDF。 本文涵盖以下主题: Python VSDX 到 PDF 转换器库使用 Python 将 VSDX 转…

【测试】⽤例篇

本节重点⽬标 测试⽤例的概念 设计测试⽤例的万能思路 设计测试⽤例的⽅法 基于需求的设计⽅法 具体的设计⽅法 等价类 边界值 判定表法 正交法 场景法 错误猜测法 1. 测试⽤例 1.1 概念 什么是测试⽤例? 测试⽤例(Test Case)是为…