STM32 HAL库实现USB虚拟串口
1. 引言
在嵌入式系统开发中,USB 虚拟串口是一种非常实用的功能。它允许 STM32 微控制器通过 USB 接口与计算机进行通信,就像使用传统的串口一样。这种方式不仅简化了硬件设计,还提高了通信的灵活性和稳定性。STM32F407 系列微控制器具有强大的处理能力和丰富的外设资源,配合 HAL 库可以方便地实现 USB 虚拟串口功能。
2. 开发环境搭建
2.1 硬件准备
- STM32F407 开发板:选择一款基于 STM32F407 的开发板,如正点原子的探索者 STM32F407 开发板。
- USB 数据线:用于连接开发板和计算机。
2.2 软件准备
- Keil MDK:一款专业的 ARM 微控制器开发工具,用于编写、编译和调试代码。
- STM32CubeMX:ST 官方提供的图形化配置工具,可用于快速生成 STM32 项目的初始化代码。
点击生成代码;
注意几处需要修改的地方:
3. USB 虚拟串口原理
3.1 USB 协议基础
USB(Universal Serial Bus)是一种通用的串行总线标准,具有高速、可靠、易用等特点。USB 协议定义了设备与主机之间的通信方式,包括设备枚举、数据传输等过程。
3.2 CDC 类协议
CDC(Communication Device Class)是 USB 协议中的一种设备类,专门用于实现虚拟串口通信。CDC 类协议定义了两个接口:通信接口(Communication Interface)和数据接口(Data Interface)。通信接口用于发送和接收控制命令,数据接口用于传输实际的数据。
3.3 数据传输过程
4.2 数据接收处理
在usbd_cdc_if.c
文件中,有一个CDC_Receive_FS
回调函数,用于处理接收到的数据。以下是该函数的示例代码:
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{/* USER CODE BEGIN 6 */USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);USBD_CDC_ReceivePacket(&hUsbDeviceFS);// 处理接收到的数据for (uint32_t i = 0; i < *Len; i++){// 这里可以添加具体的数据处理逻辑// 例如将接收到的数据原样发送回去CDC_Transmit_FS(&Buf[i], 1);}return (USBD_OK);/* USER CODE END 6 */
}
4.3 数据发送处理
在usbd_cdc_if.c
文件中,有一个CDC_Transmit_FS
函数,用于发送数据。以下是该函数的示例代码:
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{uint8_t result = USBD_OK;/* USER CODE BEGIN 7 */USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;if (hcdc->TxState != 0){return USBD_BUSY;}USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);/* USER CODE END 7 */return result;
}
4.4 主函数代码
在main.c
文件中,需要对 USB 设备进行初始化,并启动数据接收。以下是主函数的示例代码:
5. 代码编译与下载
5.1 代码编译
打开 Keil MDK,导入 STM32CubeMX 生成的项目代码。在 Keil MDK 中进行编译,确保代码没有错误和警告。
5.2 代码下载
将开发板通过 USB 数据线连接到计算机,使用 ST-Link 或 J-Link 等调试器将编译好的代码下载到开发板中。
6. 测试与验证
6.1 计算机端软件准备
在计算机上安装串口调试助手,如串口调试精灵、SSCOM 等。
6.2 设备识别
将开发板通过 USB 数据线连接到计算机,计算机应该能够识别出一个新的串口设备。
6.3 数据收发测试
打开串口调试助手,选择识别到的串口,设置波特率为 115200(USB 虚拟串口的波特率不影响实际通信速度)。在串口调试助手中发送数据,开发板应该能够接收到数据并将其原样发送回去。
7. 常见问题及解决方法
7.1 设备无法识别
7.2 数据收发异常
8. 扩展功能
8.1 数据解析与处理
在CDC_Receive_FS
函数中添加更复杂的数据解析逻辑,例如解析特定的命令格式,实现不同的功能。
8.2 多线程处理
使用 STM32 的 RTOS(实时操作系统),如 FreeRTOS,将数据接收和处理任务分配到不同的线程中,提高系统的实时性和稳定性。
9. 总结
通过以上步骤,你可以基于 STM32F407 HAL 库实现 USB 虚拟串口功能。USB 虚拟串口为 STM32 开发板与计算机之间的通信提供了一种方便、高效的方式,在实际应用中具有广泛的用途。
- 设备枚举:当 STM32 开发板通过 USB 连接到计算机时,计算机会对设备进行枚举,获取设备的描述符信息,确定设备的类型和功能。
- 建立通信:枚举完成后,计算机和 STM32 开发板之间建立起 USB 通信连接。
- 数据传输:通过 CDC 类协议,计算机可以向 STM32 开发板发送数据,也可以接收 STM32 开发板发送的数据。
4. 代码实现
4.1 生成的代码结构
使用 STM32CubeMX 生成的代码包含了 USB 虚拟串口的基本框架,主要文件有:
- usbd_cdc_if.c:实现了 CDC 类接口的回调函数,负责处理数据的发送和接收。
- usbd_cdc.c:实现了 CDC 类的核心功能,包括设备枚举、控制命令处理等。
- usbd_core.c:实现了 USB 设备的核心功能,包括设备初始化、数据传输等。
- 检查硬件连接:确保 USB 数据线连接正常,开发板的电源正常。
- 检查 USB 驱动:在设备管理器中查看是否有未识别的设备,尝试更新 USB 驱动。
- 检查代码逻辑:确保
CDC_Receive_FS
和CDC_Transmit_FS
函数的实现正确。 - 检查缓冲区大小:确保数据缓冲区足够大,避免数据溢出。
相关文章:
STM32 HAL库实现USB虚拟串口
1. 引言 在嵌入式系统开发中,USB 虚拟串口是一种非常实用的功能。它允许 STM32 微控制器通过 USB 接口与计算机进行通信,就像使用传统的串口一样。这种方式不仅简化了硬件设计,还提高了通信的灵活性和稳定性。STM32F407 系列微控制器具有强大…...
第二阶段:基础加强阶段总体介绍
Java语法的学习笔记 下面放复习的文档链接,如果有需要可以前往下载获取,这个仓库还有关于mysql、hadoop、python等的复习部分,并且每个文档有着对应的代码部分。文章作为复习使用,更多代码内容见链接如下: https://gitee.com/zha…...
Callable Future 实现多线程按照顺序上传文件
/** * 异步上传 BiopsyFlow 中的所有视频和音频文件到暂存服务器 */ private List<String> uploadBiopsyFlowFiles(BiopsyFlow biopsyFlow, SyncFile SyncFile) { List<String> fileBase64List syncFile.getFileBase64List(); if (CollectionUtils.is…...
leetcode283-移动零
leetcode 283 思路 本题是通过把数组中所有不为0的数字前置,实现把所有的0后置的效果 双指针法 slow 充当指针,记录当前零应该被移到的位置。而 i 用来遍历整个数组,检查每个元素。如果当前元素不为零,就将其与 slow 位置上的…...
【dify+docker安装教程】
目录 一、dify安装包下载 二、运行环境配置 1、下载docker 2、安装 2.1 新建文件夹 2.2 安装 2.3 命令安装 3.下载完成后需要重启电脑,注意保存文档!!注意保存!!注意!!(血的教…...
GPU虚拟化实现(五)
GPU虚拟化实现(五) 章节回顾初步介绍详细介绍核心数据结构核心功能和运作机制初始化显存分配显存释放显存溢出检查显存类型检查查看分配信息代码执行流程假设例子总结章节回顾 在上一章,简单介绍了项目拦截cuda函数的流程,其本质上与拦截nvml函数的流程是一致的,都是首先…...
C++——入门基础
文章目录 一、前言二、C的发展历史2.1 C的诞生2.2 C的重要性 三、C的应用3.1第一个C程序3.2 C版3.2 C版3.3 C版与C版的区分 3.2 namespace关键字3.2.1 namespace的意义3.2.2C中域的分类3.2.3 namespace的定义3.2.4 namespace的实质3.2.5 namespace的嵌套 3.3 作用域运算符 &…...
AT2401C与RFX2401C问题处理资料
1、AT2401C 可以 PIN 对 PIN 替代 RFX2401C 吗? 答:AT2401C 可以 PIN 对 PIN 替换 RFX2401C;同时 CB2401 也可以 PIN 对 PIN 替换 RFX2401C;我们主要推 AT2401C 这款芯片,如果客户产 品需要过认证或者应用于音频产品建…...
微信小程序连续多个特殊字符自动换行解决方法
效果图 .wxml <view class"container"><text>没转换{{text}}</text><view style"height: 60rpx;" /><text>转换后{{convert}}</text> </view>.js Page({data: {text:!!!&am…...
【Linux实践系列】:进程间通信:万字详解命名管道实现通信
🔥 本文专栏:Linux Linux实践项目 🌸作者主页:努力努力再努力wz 💪 今日博客励志语录: 与其等待完美的风,不如学会在逆风中调整帆的角度——所有伟大航程都始于此刻出发的勇气 ★★★ 本文前置知…...
【TS入门笔记4---装饰器】
TS入门笔记4 TypeScript---装饰器一、装饰器基础1. 定义与作用:装饰器是一种特殊类型的声明,它可以被附加到类声明、方法、访问符、属性或参数上,用来修改类的行为。在 TypeScript 里,装饰器本质上是一个函数,它接收不…...
大学之大:韩国科学技术研究院2025.4.28
韩国科学技术研究院(KAIST)作为韩国理工科教育与科研的旗舰机构,其发展历程深刻反映了韩国从工业化到科技强国的转型轨迹。以下从历史沿革、学科优势、教学特色、科研创新、教育规模、资源投入及未来战略等维度展开全面分析: 一、…...
【QT】QT控制硬件
QT控制硬件 1.上位机程序开发2.具体例子控制led灯3. linux中的函数跟QT类里面的函数同名,发生冲突4.示例代码 1.上位机程序开发 QT做一个上位机程序,控制底层的硬件设备(下位机) 总结: 在构造函数里面去初始化,打开硬件驱动在析…...
Spring的BeanFactory和FactoryBean的区别
BeanFactory和FactoryBean在Spring框架中扮演着不同的角色,具有不同的功能和用途。 定义与角色 BeanFactory:BeanFactory是Spring IoC容器的核心接口,用于管理和维护Bean的定义、创建和生命周期。它是Spring IoC容器的基础&…...
【JavaScript】if语句
JS中的程序是从上到下一行一行执行的。 通过流程控制语句可以控制程序执行流程,使程序可以根据一定的条件来选择执行语句。 语句的分类: 1、条件判断语句 2、条件分支语句 3、循环语句 条件判断语句:使用条件判断语句可以在执行某个语句之前进…...
PostgreSQL oracle_fdw 扩展解析
PostgreSQL oracle_fdw 扩展解析 oracle_fdw 是 PostgreSQL 的一个外部数据包装器(Foreign Data Wrapper)扩展,允许 PostgreSQL 直接连接和操作 Oracle 数据库。以下是全面详细的使用指南: 一、安装与配置 1. 前置要求 Oracle 客户端库:必…...
从信息传输到智能互动,融云的全球智能通信云服务进化
4 月 24 日-25 日,GTC2025 全球流量大会在深圳福田会展中心举办,融云携全球智能通信云解决方案亮相。 在大会首日的开幕式峰会上,融云高级研发总监李宏博受邀分享《从信息传输到智能互动,融云的全球智能通信云服务进化》。 作为连…...
关于https请求丢字符串导致收到报文解密失败问题
加密方法:AES两次URLEncoder 问题现象:服务端收到的报文中少了类似%25这样的字符,导致解密失败 问题分析:用RequestBody接受 也有可能是springboot自动做了一次解码URLDecoder,自己只需要解码一次就好了...
Rust 学习笔记:修复所有权常见错误
Rust 学习笔记:修复所有权常见错误 Rust 学习笔记:修复所有权常见错误错误一:返回栈上的引用错误二:没有足够的权限错误三:别名和可变性错误四:从集合中拷贝一个元素(转移所有权)错误…...
Unity3D引擎框架及用户接口调用方式相关分析及汇总
分析目的 目前外网3D手游绝大部基于Unity3D引擎进行开发,Unity3D引擎属于商业引擎,引擎整理框架的运行机制较为神秘,本文介绍Unity引擎框架、对象组织方式、用户接口与引擎交互方式等原理,通过本文的分析和介绍可了解Unity3D框架中大致执行原理。 实现原理 Unity引擎作为…...
喷泉码在物联网场景下的案例分析
在物联网复杂场景下,无线传感器网络作为信息感知前端,面临能量受限、信道不稳定、多跳传输可靠性差等难题,严重制约物联网系统运行效能。传统基于反馈重传的通信机制在无线传感器网络中难以为继。其 ACK 确认操作频繁,大幅增加能耗,且在动态网络拓扑中,反馈易丢失,致使数…...
OpenCV 图形API(69)图像与通道拼接函数------将一个 GMat 类型的对象转换为另一个具有不同深度GMat对象函数convertTo()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将一个矩阵转换为另一种数据深度,并可选择进行缩放。 该方法将源像素值转换为目标数据深度。最终应用 saturate_cast<> 以避免…...
考研系列-计算机组成原理第七章、输入/输出系统
一、I/O接口 1.I/O接口概念 现在的I/O接口有些集成在南桥芯片上...
使用vue3 脚手架创建项目
1.创建项目 并 运行 1.1 创建项目 vue create abcd 1.2 运行 创建好项目后,命令行会提示你运行项目 npm run serve 2.介绍各个目录 node_modules : 项目依赖包,其中包括很多基础依赖,自己也可以根据需要安装其他依赖 assets文件夹&a…...
云服务器被黑客攻击应急响应与加固指南(上)
一、入侵检测与应急处理 1. 异常行为检测 # 查看异常登录记录 sudo lastb | awk {print $3} | sort | uniq -c | sort -nr sudo grep "Failed password" /var/log/auth.log | awk {print $11} | sort | uniq -c# 检查可疑进程 ps auxf | grep -E (curl|wget|bash|s…...
联合体union的特殊之处
一个联合体union的长度等于其内部长度最大的成员的长度。 union的所有成员共享同一块内存空间,可以利用这个特性读取数据的字节存储方式。 #include <stdio.h>int check_endian() {union {short s; // 2 字节(short)char c[2]…...
Spring系列五:手动实现Spring底层机制 第三部分
💗实现任务阶段5 🍚bean后置处理器实现 bean后置处理器实现 思路:先完成原生Spring 使用Bean后置处理器的案例, 然后实现自己的bean后置处理器 bean的生命周期~传送门 在idea中 shortcuts: shiftshift , 输入 InitializingBean, 搜索. 在zzw-spring…...
AGV、AMR机器人控制器x86/RK3588/NV各有什么优劣势?
以下是关于AGV/AMR机器人控制器解决方案中x86、RK(瑞芯微)、NV(英伟达)平台优劣势的综合分析: 一、核心性能对比 平台优势局限性适用场景x861. 多核高频CPU支持复杂算法运算,适合大规模路径规划及多机…...
[ACTF2020 新生赛]Include [ACTF2020 新生赛]Exec
[ACTF2020 新生赛]Include 因为前端过滤的太多了 所以直接使用 日志包含 搞 包含这个 /var/log/nginx/access.log [ACTF2020 新生赛]Include蚁剑连接 翻看 flag{1ce7a81e-0339-44ef-a398-a7784d3efe37} [ACTF2020 新生赛]Exec [ACTF2020 新生赛]Exec 127.0.0.1 |echo <?…...
23种设计模式 -- 工厂模式
Java 工厂模式示例代码 下面我将展示三种常见的工厂模式实现:简单工厂模式、工厂方法模式和抽象工厂模式。 1. 简单工厂模式 java // 产品接口 interface Shape {void draw(); }// 具体产品类 class Circle implements Shape {Overridepublic void draw() {System…...
【25软考网工】第四章(2)WLAN通信技术、WLAN频谱与信道
目录 一、WLAN通信技术 1. 扩展频谱通信 1)扩频通信种类 2)技术关系 2. 应用案例 1)例题:扩频通信概念判定 2)例题:跳频扩频技术描述 3)例题:扩频通信技术标准 3.知识小结 二、WLAN频谱与信道 1. WLAN网络分…...
MetaEditor - 自动交易和技术指标编辑器
功能特点 代码编辑功能:支持多种编程语言,如 MQL4 和 MQL5,方便交易者根据自己的需求编写自动交易策略和技术指标。它提供了代码高亮、自动缩进、语法检查等功能,有助于提高代码编写的效率和准确性。调试与测试工具:配…...
关于华为云OneAccess登录认证过程介绍
这里主要介绍的是OAuth2认证的一个流程,分享一下实际开发过程中的实现逻辑 1、后端先根据接口文档的细节内容,然后拼接好url并且以String的类型返回给前端 2、此时前端会访问本连接,然后就会跳转到第三方页面,用户进行登录后&am…...
Spring - 简单实现一个 Spring 应用
一、为什么需要学习Spring框架? 1.企业级开发标配 超过60%的Java项目都使用Spring生态(数据来源:JetBrains开发者报告)。 2.简化复杂问题 通过IoC和DI,告别new关键字满天飞的代码。 3.职业竞争力 几乎所有Java岗…...
数据展示功能界面设计与实现及终端控制界面思路(17)
文章目录 一、本章说明二、传感数据展示功能实现2.1 实现目标2.2 具体实现2.2.1 需要在.pro 文件添加2.2.2 mainwindow.h 头文件2.2.3 mainwindow.cpp 文件2.2.4 实现界面展示三、项目源码文件四、终端节点控制五、Qt打包EXE一、本章说明 注:本节为【基于STM的环境监测系统(…...
opendds编译开发(c#封装)
opendds是对DDS协议的开源实现,具体可以查阅官网。 我使用的是源码编译开发,博文只针对windows平台。 环境准备 环境安装 1.visual studio 2022,我是企业版,安装需要选择c 2.Per下载安装,下载链接:https://strawberryperl.com…...
电子监管码预检剔除装置提示盒尺寸过短
问题:电子监管码预检剔除装置提示盒尺寸过短 现象:自动线监控程序报警提示“盒尺寸过短”。 原因:分盒设备拨盒的力度和距离、盒子在传送带的角度或传送带速度有所变化都会导致自动线出现“盒尺寸过短” 解决方法:根据传送带的速…...
【C++11特性】Lambda表达式(匿名函数)
一、函数对象 在C中,我们把所有能当作函数使用的对象当作函数对象。 一般来说,如果我们列出一个对象,而它的后面又跟有由花括号包裹的参数列表,就像fun(arg1, arg2, …),这个对象就被称为函数对象。函数对象大致可分为…...
【北京】昌平区某附小v3700存储双控故障维修案例
2025年4月22日,接到一位通过网络找到我们的北京老师求助,反馈该学校一台V3700存储的磁盘分区无法正常读取了,老师在机房检查时发现存储后面2个控制器均亮警告灯。急需修复该设备读取里面资料用于周末运动会所需。于是在网上找到我们协助进行排…...
汤晓鸥:计算机视觉的开拓者与AI产业化的先行者
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 汤晓鸥:计算机视觉的开拓者与AI产业化的先行者 一、学术与创业之路 1. 从…...
MATLAB实现神经网络的OCR识别
使用说明: 运行要求: MATLAB R2020b 或更新版本已安装 Deep Learning Toolbox推荐使用GPU加速(训练时在代码开头添加 gpuDevice(1)) 代码特点: 使用MATLAB自带的MNIST手写数字数据集包含数据可视化、网络架构…...
车载软件架构 --- AUTOSAR的方法论
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...
Java 的创新与变革之路:从 JDK 7 到 JDK 23
Java 作为一种广泛应用的编程语言,其发展历程与 JDK(Java Development Kit)的演进紧密相连。自 JDK 7 起,Java 语言不断引入重大特性,持续重塑开发格局,推动性能、功能和开发体验的提升。本文将深入剖析 JD…...
LangChain、LlamaIndex、MCP、Spring AI、Ollama 和 DeepSeek 的定义、关系及典型架构设计
以下是 LangChain、LlamaIndex、MCP、Spring AI、Ollama 和 DeepSeek 的定义、关系及典型架构设计解析: 一、核心组件定义与功能 1. LangChain 定位:构建复杂 大语言模型(LLM)应用的通用框架。功能: 支持链式调用&am…...
Docker安装的mysql限制ip访问
1.问题背景 docker安装了mysql服务,服务器为Redhat9,我们希望通过防火墙规则直接限制访问的来源ip,只允许特定ip进行访问,其余ip需要被禁止。 2.排查过程 1.首先尝试了通过firewalld方式添加对应的防火墙规则, sud…...
怎么样才能在idea中写入spark程序
一、准备环境 1.安装Scala插件 专业版IDEA自带Scala插件,社区版需手动安装 确保插件版本与IDEA版本匹配 2.选择用哪个构建工具 sbt:适用于依赖管理简单、快速迭代的项目,需提前安装sbt工具24。 Maven:适合熟悉Java生态…...
MySQL的数据类型
目录 数据类型分类 数值类型 tinyint bit 编辑 小数(float) 小数(decimal) 字符串类型 char varchar 日期和时间类型 String类型 enum set find_ in_ set函数 我们今天来学习MySQL的数据分类。 数据类型分类 MySQL的字符型就是相当于字符串类型,所…...
Vue 中局部指令(directives)的用法详解
在 Vue.js 中,指令是一种特殊的属性,用于在 DOM 元素上绑定特殊行为。除了 Vue 内置的指令(如v-model、v-if),还可以自定义指令来封装可复用的功能。 什么是局部指令? 局部指令是在单个组件中定义和使用的…...
mac 基于Docker安装minio服务器
在 macOS 上基于 Docker 安装 MinIO 是一个高效且灵活的方案,尤其适合本地开发或测试环境。以下是详细的安装与配置步骤,结合了最佳实践和常见问题的解决方案: 一、安装 Docker Desktop 下载安装包 访问 Docker 官网,下载适用于 …...
Redis常用数据结构解析:从原理到实战应用
作为一名开发者,我深知Redis在缓存、队列等场景中的重要性。但要用好Redis,必须对其核心数据结构有透彻理解。本文将结合我的实践经验,详细讲解Redis五种最常用的数据结构及其典型应用场景,帮助你在开发中游刃有余。 一、String&…...