ESP32S2应用开发——USB通信(CDC类)

目录

  • ESP32S2应用开发——USB通信(CDC类)
    • 前言
    • 1 硬件介绍
      • 1.1 硬件连接
    • 2 软件开发
      • 2.1 安装开发板
      • 2.2 安装库
      • 2.3 运行示例代码
      • 2.4 USB传输速度测试
    • 结束语

前言

ESP32-S2是继ESP32之后新出的一款的MCU,而USB接口是ESP32-S2的一大特色,虽然使用的只是USB1.1协议,但是相比于串口而言传输速度还是要快很多的。对于音频或者视频等数据的传输,使用usb明显是比串口有优势的。
因为前段时间项目需求,需要用到ESP32-S2的USB,于是就花了些时间研究了一下,发现网上关于ESP32-S2 USB的介绍很少而且大多资料都过时了,于是就有了这篇博客。
好了,废话不多说了,马上开始讲解。

1 硬件介绍

本文的硬件配置如下:

模块 型号 说明
ESP32-S2 ESP32-S2-WROVER 这是乐鑫的一款模组,内部主要是用乐鑫的ESP32-S2再加上一个4M FLASH和2M PSRAM组成,开发板用的是乐鑫的ESP32-S2-SAOLA

ESP32-S2的引脚很多我就不一一介绍了,这一讲主要用到的UART0和USB(GPIO19,GPIO20)。

1.1 硬件连接

我这里用的是开发板,硬件连接比较简单。
UART0通过USB转TTL芯片连接到PC端。
USB通过GPIO19和GPIO20直连PC端的USB接口。

引脚 描述 说明
GPIO19 USB D- USB信号线,直连PC端即可,不需要接转换芯片
GPIO20 USB D+ USB信号线,直连PC端即可,不需要接转换芯片
U0TXD 串口TX 方便调试使用,需要接USB转换TTL才能连接到PC端
U0RXD 串口RX 方便调试使用,需要接USB转换TTL才能连接到PC端

2 软件开发

2.1 安装开发板

关于ESP32-S2 Arduino的环境搭建我之前出过教程了,这里就不多说了,不懂的同学可以先看下我之前的博客。

2.2 安装库

打开Arduino IDE,依次打开 工具 -> 管理库…
在搜索框输入需要安装的库名称,找到对应的库,点击安装即可。

本文需要使用的Arduino库如下:

Arduino库 版本 说明
ESP32TinyUSB 1.3.4 USB相关库,使用该库要确保ESP32库版本在2.0.0以上
esp32 2.0.1 建议使用该版本,v2.0.2有个usb相关的结构体定义改了,跟ESP32TinyUSB库不兼容。
如果非要用2.0.2以上版本就需要在ESP32TinyUSB和esp32两者之前选择一个把client_event_callback的定义改掉

2.3 运行示例代码

ESP32TinyUSB库自带很多examples,我们打开一个cdc的示例代码先测试一下USB通讯。
示例代码如下:

/*** Simple CDC device connect with putty to use it* author: chegewara* Serial - used only for logging* Serial1 - can be used to control GPS or any other device, may be replaced with Serial*/
#include "cdcusb.h"
#if CFG_TUD_CDC
CDCusb USBSerial;class MyUSBCallbacks : public CDCCallbacks {void onCodingChange(cdc_line_coding_t const* p_line_coding){int bitrate = USBSerial.getBitrate();Serial.printf("new bitrate: %d\n", bitrate);}bool onConnect(bool dtr, bool rts){Serial.printf("connection state changed, dtr: %d, rts: %d\n", dtr, rts);return true;  // allow to persist reset, when Arduino IDE is trying to enter bootloader mode}void onData(){int len = USBSerial.available();Serial.printf("\nnew data, len %d\n", len);uint8_t buf[len] = {};USBSerial.read(buf, len);Serial.write(buf, len);}void onWantedChar(char c){Serial.printf("wanted char: %c\n", c);}
};void setup()
{Serial.begin(115200);USBSerial.setCallbacks(new MyUSBCallbacks());USBSerial.setWantedChar('x');if (!USBSerial.begin())Serial.println("Failed to start CDC USB stack");}void loop()
{while (Serial.available()){int len = Serial.available();char buf1[len];Serial.read(buf1, len);int a = USBSerial.write((uint8_t*)buf1, len);}
}#endif


运行结果如下:
设备管理器能看到两个com口(一个是串口转换芯片,一个是ESP32-S2的USB)。

用串口助手先打开UART对应的端口,波特率115200。再打开一个串口助手,连接USB虚拟串口对应的com口,此时能看到UART会出现一些log。

USB连接上之后,两个串口助手之间可以互发数据,说明USB通讯是没问题的。

提示:如果烧录程序之后出现一直重启的现象,可能是因为MCU原本出厂的固件有一部分没有被擦除导致的,可以使用乐鑫的flash烧录工具对整个MCU进行擦除之后再烧录Arduino的程序。

2.4 USB传输速度测试

简单写一个测试代码用来测试USB数据传输的速度。
示例代码如下:

#include "cdcusb.h"
#include "Arduino.h"
#include <esp_heap_caps.h>#define FILE_SIZE 971240   // 测试文件的大小
uint8_t *rx_buf;
uint32_t rx_num = 0;
uint8_t first_time_flag = 1;
long lTime;CDCusb CDCUSBSerial;class MyCDCCallbacks : public CDCCallbacks {void onCodingChange(cdc_line_coding_t const* p_line_coding){int bitrate = CDCUSBSerial.getBitrate();Serial.printf("new bitrate: %d\n", bitrate);}bool onConnect(bool dtr, bool rts){Serial.printf("connection state changed, dtr: %d, rts: %d\n", dtr, rts);return true;  // allow to persist reset, when Arduino IDE is trying to enter bootloader mode}void onData(){if(first_time_flag){first_time_flag = 0;lTime = micros();}int len = CDCUSBSerial.available();CDCUSBSerial.read(&rx_buf[rx_num], len);rx_num += len;if(rx_num >= FILE_SIZE){lTime = micros() - lTime;Serial.printf("time: %f s \n", lTime / 1000000.0);Serial.printf("speed:%f kb/s", ((float)FILE_SIZE / 1024.0) / (lTime / 1000000.0));first_time_flag = 1;rx_num = 0;}}
};void setup()
{Serial.begin(115200);if (!CDCUSBSerial.begin())Serial.println("Failed to start CDC USB stack");CDCUSBSerial.setCallbacks(new MyCDCCallbacks());rx_buf = (uint8_t*)ps_malloc(FILE_SIZE);
}void loop()
{}

通过串口助手往USB发送一个大文件(971240字节,约948.5kb)。
提示:这里串口助手打开文件时显示的时间是按当前波特率估算出来的,但是实际上我们用的是虚拟串口,USB传输是没有波特率这个参数的,这里波特率不管设置为多少,实际的速度都一样,都是以USB传输速度为准。

通过ESP32-S2的串口0打印实际的传输的时间和速度。

经过sscom这个串口助手传输文件测试,ESP32-S2 USB的最大传输速度在190kb/s左右,实际上加上一些应用代码之后,速度会有所下降,约160kb/s左右(这个速度跟具体的应用有关)。
因为USB接收是中断处理的,MCU如果一直处于闲置状态,那USB的数据传输速度可以达到最大。反之,MCU如果一直在运行其他应用代码,那么在接收USB数据时只能通过频繁的中断来完成数据的读取,此时接收的效率明显是要下降一些的。另外,传输速度跟MCU的接收方式也有关系,USB1.1最大支持一次接收64字节,所以MCU在进入回调函数时,应该根据把当前收到的所有数据一次性读取完,而不是每次回调只读一个字节。

后期测试补充:
在使用sscom这个串口助手时,文件的传输速度跟设置的波特率无关,但是后来用另外一个串口助手(UartAssist)时发现用这个工具设置的波特率跟实际传输速度有关联,这就很奇怪了,因为这个只是虚拟串口,实际上是按照USB1.1协议来传输数据的,理论上不应该出现这种情况的。然后我测试了多种不同的波特率,发现波特率较小时,实际传输速度与波特率基本一致,波特率越大速度越快,当波特率增大到2M时,速度与之前sscom串口助手测试的速度接近。继续增大波特率到某个值之后,不管波特率设置多少,速度都不再增大了。最大传输速度在270kb/s左右。
从目前的现象来看,USB的传输速度跟串口工具本身也有关系,具体的原因还没搞清楚,有懂的老哥解答一下吗?

结束语

好了,关于ESP32-S2 USB的使用就介绍到这里。如果这篇文章对你有帮助,可以点赞收藏,如果还有什么问题,欢迎在评论区留言或者私信给我。

补充说明:
最近我经常收到一些私信,这是不是真的USB?这是串口转USB吧?
所以我这里统一补充说明一下,如何区分USB CDC和串口。
CDC类USB和HID不同,它枚举出来的设备确实是一个串行设备,看着是很像串口,但实际上是不一样的。
主要有以下几个区别:

区别 USB 串口
1 两个USB之间是直连的,不需要转换电平 串口是TTL电平的,如果没有转换芯片,是没法直接连接PC端的USB接口的。常用的转换IC如:CH340、CP2102、PL2303、FT232、MAX232等
2 传输速度快 传输速度慢
3 遵循USB协议(可通过逻辑分析仪抓取和解析) 遵循串口协议(可通过逻辑分析仪抓取和解析)
4 USB有枚举过程(可通过BusHound抓取通讯过程) 串口不存在枚举过程

Arduino开发教程汇总:
https://blog.csdn.net/ShenZhen_zixian/article/details/121659482

ESP32-S2应用开发——USB通信(CDC类)相关推荐

  1. C# 开发USB通信、串口通信、Socket通信(适用于打印机的指令操作等)

    背景:公司最近需要用到外接打印机(型号:东芝标签打印机B-FV4T,采用东芝自定义的TPCL指令格式),现在市场上可以购买到的主流打印机一般都是支持一下通信模式的. 1:USB通信 2:网络通信 3: ...

  2. 在进行USB CDC类开发时,无法发送64整数倍的数据

    1 前言 本文将基于STM32F4DISCOVERY板,介绍如何使用USB的CDC类进行开发,以及在开发过程中碰到发送64整数倍数据时会失败的问题分析及解决方案. 2 硬件介绍 在创建工程之前,我们首 ...

  3. STM32 USB使用记录:使用CDC类虚拟串口(VCP)进行通讯

    文章目录 目的 基础说明 使用STM32CubeIDE配置生成代码 用户代码分析 回环测试 串口参数设置 USB HS使用与演示 通讯速率测试 测试代码 USB FS测试 USB HS测试 影响速度的 ...

  4. TI Cortex-M4 USB Host CDC 驱动详解及源代码

    1. USB CDC介绍 USB的CDC类是USB通信设备类(Communication Device Class)的简称.CDC类是USB组织定义的一类专门给各种通信设备(电信通信设备和中速网络通信 ...

  5. 在进行USB CDC类开发时,无法发送64整数倍的数据(续)

    1 前言 此文延续之前相同文章的话题,是对上篇文章的补充,之所以会有此文,主要是之前发现问题是在STM32F4上,解决方案也是基于CubeF4,但是,当相同问题出现在STM32F0上时,使用之前的代码 ...

  6. 如何让CDC类USB设备批量接收64字节以上数据

    很多STM32开发者在实现CDC类虚拟串口与PC主机通信过程中,有时会遇到点麻烦而不得其解.那就是当主机端单次发送的数据不超过64字节时,接收正常.一旦发送数据量大于64字节时就接收失败,总是出现丢包 ...

  7. 【ESP32 S2 烧录AT固件 串口与USB两种方式】

    ESP32 S2 烧录AT指令固件 串口与USB两种方式 什么是AT指令? 固件和工具下载 USB完整固件烧录 串口完整固件烧录 AT测试 本文主要介绍了对ESP32 S2进行AT指令固件烧录的具体操 ...

  8. 基于AOA协议的android USB通信

    摘 要:AOA协议是Google公司推出的用于实现Android设备与外围设备之间USB通信的协议.该协议拓展了Android设备USB接口的功能,为基于Android系统的智能设备应用于数据采集和设 ...

  9. ESP32在WIN7下USB调试串口驱动安装 解决USB JTAG/serial debug unit (Interface 0)无法安装驱动的问题

    使用WIN7开发ESP32, 但一直不能解决USB烧录问题,  就是USB serial 总是无法安装, 虽然可以在WIN10下使用, 但切换虚拟机也麻烦 经常仔细对比查找分析, 问题解决, 顺利安装 ...

最新文章

  1. 详解Spring中Bean的自动装配~
  2. mysql 冷热数据分离_elasticsearch冷热数据读写分离
  3. 去年领了163亿薪资的马斯克,刚推出智能召唤功能就被吐槽:遇到人开的车就蒙圈...
  4. 【云栖大会夺宝攻略】在线PK、打卡领奖、抢offer,开发者专属玩法在这里
  5. php文件引用问题,Php引用文件引起的空白行问题(UTF-8)
  6. 86-Spark2.2源码:RDD中WithScope是什么?
  7. 守护线程C语言windows,C言语如何利用子线程刷新主线程
  8. 系统集成Nacos和Feign
  9. mysql行转列sql函数_(转)行变列SQL语句(MSSQL) - jack - 博客园
  10. 革命性新特性 | 单一应用跨多Kubernetes集群的部署与管理 1
  11. appium+python实现手势密码
  12. Captin for mac(大小写切换悬浮窗提示)
  13. MarkDown图床助手: 截图-传图-生成url 一步到位
  14. 如何利用U盘进行重装win10系统[亲测有效]
  15. python操作excel编号自增加1
  16. 移动的项目,在tunnel为888696的情况下创建业务
  17. 关于财务业务模型的思考
  18. MATLAB图像基本操作(信息查询/文件读取/写入/显示)
  19. Ristretto—SqueezeNet示例详解
  20. Oracle算老几?敢用甲骨文这个名字自居?

热门文章

  1. 安卓新浪微博授权分享 小米8Android9的坑。解决web网页授权无法正确回调bug。
  2. 【2021-05-23】7-3 模拟2048游戏(1)--单行向左移动叠加 个人题解
  3. MFC 中Invalidate的使用
  4. 怎么在水果音乐制作软件播放列表中排列样式
  5. 林超文大师PCB设计经验、技巧分享(一)
  6. 计算机基础知识专插本,计算机基础专插本复习资料.pdf
  7. Linux系统无线网卡的安装【转】
  8. Gumbel 分布介绍(耿贝尔分布)
  9. 初学TypeScript之接口定义
  10. 2020.03.19基于ES6.8.5,IK6.8.5,Kibana6.8.5的测试命令