上位机图像处理和嵌入式模块部署(h750 mcu和usb虚拟串口)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        对于mcu usb而言,大部分情况下,它和上位机之间的关系都是device的关系。一般usb,可以分成host和device。如果mcu是host,那么意味着它可以主动访问别的usb设备,比如u盘、相机之类的设备。如果是device呢,这种情况下,mcu就是被别人访问,也就是说mcu会把自己伪装成一个u盘、camera或者串口这样的设备。

        另外不知道大家注意没有,很多的usb模块,里面本身没有usb转232的芯片,但是照样被识别成了com设备,道理就在这。因为mcu固件里面把会usb虚拟成com设备。

1、usb cdc虚拟串口和传统usb转串口的区别

        差别之处其实比较好分辨,前者是通过固件代码的形式实现的;而后者,一般都是需要添加一个usb转232的芯片实现。

2、usb cdc虚拟串口的好处

        把mcu的usb虚拟成一个串口,不仅速度比较快,没有波特率的限制,使用上面也比较简单,也没有额外的成本困扰。

3、cdc的目录结构

        stm32目前大部分mcu都支持cdc结构,大家只需要把对应的代码copy过来,会使用即可,不用过度追究里面的原理。

4、main函数的启动流程

        这部分代码其实和之前其他mcu的代码没有区别。在进行了usb设备的初始化,即调用MX_USB_DEVICE_Init函数之后,就是打印数据和接收数据。当然,mcu启动之后,需要一个type c的线连接到电脑上面。这个时候电脑的设备管理器就会生成一个新的com节点。我们借助于上位机串口打印工具,open这个com点之后,就可以看到对应的发送内容,以及接收的内容。

int main(void)
{
	SCB_EnableICache();		
	SCB_EnableDCache();		
	HAL_Init();					
	SystemClock_Config();	
	LED_Init();					
	
	MX_USB_DEVICE_Init();	
	
	USB_printf("STM32H750 virtual usb test\r\n");	
	
	while (1)
	{
		USB_printf("1234567abcdefg\r\n");
		LED1_Toggle;
		HAL_Delay(1000);
		USB_getf();
	}
}

5、usb发送

        这里面发送的函数就是USB_printf,我们可以简单看下这个函数是怎么实现的。实现的文件来自于usbd_cdc_if.c,

void USB_printf(const char *format, ...)
{
	va_list args;					
	uint32_t length;			
	uint16_t	 USB_TimeOut;	
	uint32_t  Tickstart;			
	
	va_start(args, format);	
	length = vsnprintf((char *)UserTxBufferFS, APP_TX_DATA_SIZE, (char *)format, args);
	va_end(args);					

	USB_TimeOut = 3;	
	if( hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED )		
	{
		USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;	
	
		Tickstart = HAL_GetTick();		
		while(hcdc->TxState !=0)		
		{
			if((HAL_GetTick() - Tickstart) > USB_TimeOut)
			{
				break;
			}
		}
	}		

	CDC_Transmit_FS(UserTxBufferFS, length); 
}

6、usb接收

        大家如果留心一下就会发现,刚才usb发送的时候,都是把数据copy到UserTxBufferFS里面的。其实接收数据也一样,整个接收区的内容,都是放在UserRxBufferFS缓存里面。这就意味着,我们检查UserRxBufferFS空间就可以拿到里面的内容,有数据可以打印出来,没有就算了。

void USB_getf(void)
{
	int num= strlen((const char*)UserRxBufferFS);
	if(num > 0)
	{
		USB_printf("%s", UserRxBufferFS);
		memset(UserRxBufferFS, 0, num+1);
	}
}

7、测试和验证

        和前面几次打印、测试不一样,这一次的打印是通过usb线虚拟的串口实现的。这样的话就不需要实际的usb转串口工具。一个st-link v2烧录器,一个type c的线,就可以和pc电脑之间实现数据通信了。最后,还是建议大家可以把重点放在如何使用cdc、如何使用usb虚拟串口上面。等到用起来,比较熟练了,再去看usb cdc和usb协议的实现细节,这样更加稳妥。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【调试笔记-20240611-Linux-配置 OpenWrt-23.05 支持泛域名 acme 更新】

调试笔记-系列文章目录 调试笔记-20240611-Linux-配置 OpenWrt-23.05 支持泛域名 acme 更新 文章目录 调试笔记-系列文章目录调试笔记-20240611-Linux-配置 OpenWrt-23.05 支持泛域名 acme 更新 前言一、调试环境操作系统:Windows 10 专业版调试环境调试目标 二、调…

Python10 python多线程

1.什么是python多线程 Python的多线程指的是在一个Python程序中同时运行多个线程,以达到并发执行多个任务的目的。线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。 在Python中,多线程的…

【Hudi】基础概念-数据写

目录 数据写写操作写流程(UPSERT)写流程(Insert)写流程(Insert Overwrite)Key生成策略删除策略 数据写 写操作 UPSERT:默认行为,数据先通过index打标,有一些启发式算法决定消息的组织以及优化文件的大小>CDC导入INSERT:跳过index,写入效…

(已解决) Github无法显示图像问题

Github无法显示图像的问题 问题描述初次尝试最终解决 问题描述 今天打开github,创建了一个仓库,想从本地把一些最近做的东西传上来(git add . > git commit -m “xxx” > git push),结果发现东西是成功传上来了,但是图片没…

简单好用的C++日志库spdlog使用示例

文章目录 前言一、spdlog的日志风格fmt风格printf风格 二、日志格式pattern三、sink,多端写入四、异步写入五、注意事项六、自己封装了的代码usespdlog.h封装代码解释使用示例 前言 C日志库有很多,glog,log4cpp,easylogging, eas…

PDF为何成为职场必备?编辑不求人,这几款工具助你一臂之力

不管是工作和学习,我们使用PDF文档的频率非常高,但是说起为什么要用PDF,却又只知其一不知其二。 为什么我们需要PDF? PDF,全称为Portable Document Format(可移植文件格式),是一种…

【电机】PID参数整定方法

1 试凑法 采样周期的选择,要根据所设计的系统的具体情况,用试凑的方法,在试凑过程中根据各种合理的建议来预选采样周期,多次试凑,选择性能较好的一个作为最后的采样周期。早整定参数时必须要认真的观察系统的相应情况…

低代码专题 | 低代码开发平台怎么收费,价格多少?一文揭秘!

低代码开发平台近几年真的火得一塌糊涂,不少企业都开始关注并尝试这种新的开发方式。 然而,关于低代码开发平台的收费问题,却是众说纷纭、信息零散。为了帮助大家更清晰地了解低代码开发平台的收费情况,这篇文章将进行全面的解读…

【STM32】使用标准库检测按键

按键检测使用到GPIO外设的基本输入功能。 1.硬件设计 作者使用的硬件没有按键模块。故使用了一个引脚模拟按键,将PWM1引脚拉低表示按键按下。思路如下:PWM1配置为输入,默认拉高,PWM1手动接地来模拟按下按键,此时PWM&a…

如何做好亚马逊、速卖通自养号测评?这些细节很重要

亚马逊,作为电商领域的领军者,吸引了无数卖家入驻。在这片竞争激烈的土地上,Review成为了卖家们展现实力、赢得消费者信任的关键。 Review不仅反映了产品的质量和卖家的服务,更是消费者选择购买的重要因素。因此,对于卖…

收入公平性评估方法

一、Gini系数## 1.1什么是基尼系数## 基尼系数是国际上用来综合考察居民内部收入分配差异状况的一个重要分析指标。每个人的收入有多有少,差距大时,基尼系数就高;差距小时,基尼系数就低。 1.2基本概念## 基尼系数表示在全部居民收…

js语法---理解防抖原理和实现方法

什么是防抖(节流) 在实际的网页交互中,如果一个事件高频率的触发,这会占用很多内存资源,但是实际上又并不需要监听触发如此多次这个事件(比如说,在抢有限数量的优惠券时,用户往往会提…

golang windows打包为linux可执行文件

使用go的交叉编译功能 set GOOSlinux set GOARCHamd64然后再执行go build 可能会报异常, 所以贴出我的go env配置仅供参考 go env环境配置 D:\GoWork\src\go-tzv>go env set GO111MODULEauto set GOARCHamd64 set GOBIN …

架构师篇-1、总体架构设计

业务架构哲学本质 定位:赋予业务架构设计能力,具备业务架构设计思维模型,掌握业务架构哲学本质,形成以不变应万变的业务架构设计能力。 架构师所需要的能力: 带领业务成功通过框架思维赋能业务架构师知识体系构建掌…

华北水利水电大学-C程序设计作业

目录 基础题 1-1 分析 代码实现 1-2 分析 代码实现 1-3 分析 代码实现 1-4 ​编辑 分析 代码实现 1-5 分析 代码实现 1-6 分析 代码实现 基础题 1-1 从键盘输入10个学生的有关数据,然后把它们转存到磁盘文件上去。其中学生信息包括学号、姓名…

学会python——制作一款天气查询工具(python实例七)

目录 1、认识Python 2、环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3、天气查询工具 3.1 代码构思 3.2 代码示例 3.3 运行结果 4、总结 1、认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的…

pip安装总是失败,如何配置pip安装源,让环境重获新生?

前情提要 公司新项目组报道后,因为用的是公司内网,安装完python 和pycharm 后,发现pip 下载安装包总是报错 具体解决 1.确认python 环境已经安装 2.在cmd中执行如下命令配置参数 pip config set global.index-url https://这里填写自己公…

Linux 软件包管理器 yum

文章目录 yum是什么?Linux(centos)的生态yum的相关操作yum本地配置安装包lrzsz yum是什么? yum可以形象的比喻成一个下载安装管理的一个客户端,比如小米应用商店、华为应用商城 Linux中的安装包是有依赖关系的(比如下载游戏的时候有各种文件…

神经网络模型---ResNet

一、ResNet 1.导入包 import tensorflow as tf from tensorflow.keras import layers, models, datasets, optimizersoptimizers是用于更新模型参数以最小化损失函数的算法 2.加载数据集、归一化、转为独热编码的内容一致 3.增加颜色通道 train_images train_images[...,…

滑动窗口练习1-长度最小的子数组

1.题目链接:209.长度最小的子数组 2.题目描述: 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条…