《ESP32-S3使用指南—IDF版 V1.6》第四十四章 USB虚拟串口(Slave)实验

136 阅读9分钟

第四十四章 USB 虚拟串口 (Slave) 实验

本章,我们将向大家介绍如何利用USB在开发板实现一个USB虚拟串口,通过USB与电脑数据数据交互。

本章分为如下几个小节:

44.1 USB虚拟串口简介

44.2 硬件设计

44.3 程序设计

44.4 下载验证

44.1 USB 虚拟串口简介

USB虚拟串口,简称VCP,是Virtual COM Port的简写,它是利用USB的CDC类来实现的一种通信接口。CDC(Communication Device Class)类是 USB2.0 标准下的一个设备类,定义了通信相关设备的抽象集合。

我们可以利用ESP32自带的USB功能,来实现一个USB虚拟串口,从而通过USB,实现电脑与ESP32的数据互传。上位机无需编写专门的USB程序,只需要一个串口调试助手即可调试,非常实用。

44.2 硬件设计

44.2.1 例程功能

本实验利用ESP32自带的USB功能,连接电脑USB,虚拟出一个USB串口,实现电脑和开发板的数据通信。本例程功能完全同实验4(串口通信实验),只不过串口变成了ESP32的USB虚拟串口。当USB连接电脑(USB线插入USB_SLAVE接口),开发板将通过USB和电脑建立连接,并虚拟出一个串口。

LED闪烁,提示程序运行。USB和电脑连接成功后。

44.2.2 硬件资源

  1. LED灯

LED -IO0

2.独立按键

KEY0(XL9555) - IO1_7

KEY1(XL9555) - IO1_6

KEY2(XL9555) - IO1_5

KEY3(XL9555) - IO1_4

  1. XL9555

IIC_SDA-IO41

IIC_SCL-IO42

  1. SPILCD

CS-IO21

SCK-IO12

SDA-IO11

DC-IO40(在P5端口,使用跳线帽将IO_SET和LCD_DC相连)

PWR- IO1_3(XL9555)

RST- IO1_2(XL9555)

  1. UART_NUM_0(U0TX、U0RX连接至板载USB转串口芯片上)

U0TXD-IO43

U0RXD-IO44

  1. USB

44.2.3 原理图

本章实验使用USB接口与PC进行连接,开发板板载了一个USB接口,用于连接其他USB设备,USB接口与MCU的连接原理图,如下图所示:

   

image001.png

图44.2.3.1 USB接口与MCU的连接原理图

44.3 程序设计

44.3.1 程序流程图

程序流程图能帮助我们更好的理解一个工程的功能和实现的过程,对学习和设计工程有很好的主导作用。下面看看本实验的程序流程图:

image004.png

图44.3.1.1USB虚拟串口实验程序流程图

44.3.2 USB 虚拟串口函数解析

ESP-IDF提供了一套API来配置USB。要使用此功能,需要导入必要的头文件:

#include"tinyusb.h"

#include"tusb_cdc_acm.h"

接下来,作者将介绍一些常用的ESP32-S3中的USB函数,这些函数的描述及其作用如下:

1 USB 设备登记

该函数用给定的配置,来配置USB设备,该函数原型如下所示:

esp_err_ttinyusb_driver_install(consttinyusb_config_t *config);

该函数的形参描述如下表所示:

QQ截图20251028150636.png

表44.3.2.1tinyusb_driver_install ()函数形参描述

该函数的返回值描述,如下表所示:

QQ截图20251028150652.png

表44.3.2.2函数tinyusb_driver_install()返回值描述

该函数使用tinyusb_config_t类型的结构体变量传入,该结构体的定义如下所示:

QQ截图20251028150659.png

表44.3.2.3i2s_pin_config_t结构体参数值描述

完成上述结构体参数配置之后,可以将结构传递给 tinyusb_driver_install () 函数,用以安装USB驱动。

2 USB 设备初始化

该函数用给定的配置,来初始化USB设备,该函数原型如下所示:

esp_err_ttusb_cdc_acm_init(consttinyusb_config_cdcacm_t *cfg);

该函数的形参描述如下表所示:

QQ截图20251028150707.png

表44.3.2.4tusb_cdc_acm_init ()函数形参描述

该函数的返回值描述,如下表所示:

QQ截图20251028150715.png

表44.3.2.5函数tusb_cdc_acm_init ()返回值描述

该函数使用tinyusb_config_cdcacm_t类型的结构体变量传入,该结构体的定义如下所示:

QQ截图20251028150724.png

表44.3.2.6tinyusb_config_cdcacm_t结构体参数值描述

完成上述结构体参数配置之后,可以将结构传递给 tusb_cdc_acm_init () 函数,用以实例化USB。

3 ,注册回调函数

该步骤用以注册回调函数,该函数原型如下所示:

esp_err_ttinyusb_cdcacm_register_callback(tinyusb_cdcacm_itf_titf,

                                            cdcacm_event_type_t event_type);

该函数的形参描述如下表所示:

QQ截图20251028150733.png

表44.3.2.7tinyusb_cdcacm_register_callback ()函数形参描述

该函数的返回值描述,如下表所示:

QQ截图20251028150741.png

表44.3.2.8 函数tinyusb_cdcacm_register_callback()返回值描述

4 ,发送数据 1

该函数将数据从字节数组写入写入缓冲区,该函数原型如下所示:

size_ttinyusb_cdcacm_write_queue(tinyusb_cdcacm_itf_titf,

                                  const uint8_t *in_buf,

                                  size_tin_size);

该函数的形参描述如下表所示:

QQ截图20251028150749.png

表44.3.2.9tinyusb_cdcacm_write_queue ()函数形参描述

该函数的返回值描述,如下表所示:

QQ截图20251028150756.png

表44.3.2.10 函数tinyusb_cdcacm_write_queue()返回值描述

5 ,发送数据 2

该函数从写缓冲区发送所有数据,该函数原型如下所示:

esp_err_ttinyusb_cdcacm_write_flush(tinyusb_cdcacm_itf_titf,

                                     uint32_ttimeout_ticks);

该函数的形参描述如下表所示:

QQ截图20251028150803.png

表44.3.2.11tinyusb_cdcacm_write_flush ()函数形参描述

该函数的返回值描述,如下表所示:

QQ截图20251028150811.png

表44.3.2.12 函数tinyusb_cdcacm_write_flush()返回值描述

44.3.3 USB 虚拟串口驱动解析

在IDF版的33_usb_uart例程中,作者在33_usb_uart\components路径下新增了USB驱动文件。

这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。

本实验,我们将相TinyUSB库文件拷贝到components文件夹下,在APP文件夹下的文件则是我们基于TinyUSB自行编写的代码。最终得到如下图所示的工程:

image005.png

图44.3.3.1 USB虚拟串口工程分组

上图中位于components文件夹下的是我们自己编写的一些外设驱动,main文件夹下包含了一个APP文件与一个后缀为.yml的文件。APP文件夹下包含的是USB模拟串口代码,而后缀为.yml的文件其主要作用是将项目中各组件的依赖项定义在单独的清单文件中,并以上图所示的方式进行命名。在我们的例程中提现出的作用就是简化了整个工程结构。我们在编译的过程中,系统便会帮我们自动生成USB外设所需要的依赖库:espressif_esp_tinyusb以及espressif_tinyusb。做到了即能简化项目工程,又能有效规避了在编译中遇到的错误,但前提是运行时得确保个人的电脑处于联网状态。

44.3.4 CMakeLists.txt 文件

打开本实验BSP下的CMakeLists.txt文件,其内容如下所示:

set(src_dirs

            IIC

            LCD

            LED

            SPI

            XL9555)

set(include_dirs

            IIC

            LCD

            LED

            SPI

            XL9555)

set(requires

            driver)

idf_component_register(SRC_DIRS${src_dirs}

INCLUDE_DIRS ${include_dirs}REQUIRES ${requires})

component_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)

该路径下的CmakeList文件并没有新增内容,主要变化在于main文件。

打开本实验main文件下的CMakeLists.txt文件,其内容如下所示:

idf_component_register(

    SRC_DIRS

        "."

        "app"

    INCLUDE_DIRS

        "."

        "app")

上述的红色app驱动需要由开发者自行添加,以确保USB驱动能够顺利集成到构建系统中。这一步骤是必不可少的,它确保了USB驱动的正确性和可用性,为后续的开发工作提供了坚实的基础。

44.3.5 实验应用代码

打开main/main.c文件,该文件定义了工程入口函数,名为app_main。该函数代码如下。

i2c_obj_ti2c0_master;

/**

* @brief      程序入口

* [@param](http://www.openedv.com/home.php?mod=space&uid=271674)      无

* @retval     无

*/

voidapp_main(void)

{

    esp_err_t ret;

    ret =nvs_flash_init();                             /* 初始化NVS */

   

if (ret ==ESP_ERR_NVS_NO_FREE_PAGES ||

       ret == ESP_ERR_NVS_NEW_VERSION_FOUND)

    {

        ESP_ERROR_CHECK(nvs_flash_erase());

        ret =nvs_flash_init();

    }

    ESP_ERROR_CHECK(ret);

    led_init();                                           /* 初始化LED */

    i2c0_master =iic_init(I2C_NUM_0);                    /* 初始化IIC0 */

    spi2_init();                                          /* 初始化SPI */

    xl9555_init(i2c0_master);                               /* 初始化IO扩展芯片 */  

    lcd_init();                                           /* 初始化LCD */

   

    /* 显示实验信息 */

    lcd_show_string(30, 50, 200, 16, 16, "ESP32-S3", RED);

    lcd_show_string(30, 70, 200, 16, 16, "USBUSART TEST", RED);

    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);

    tud_usb_usart();                                     /* USB初始化 */

   

    while(1)

    {

        LED_TOGGLE();

        vTaskDelay(500);

    }

}

此部分代码比较简单,通过tud_usb_usart()等函数初始化USB,在该函数中需要注册一个调用CDC事件的回调函数。此时,如果回调已经注册,那么它将会被覆盖。同时,LCD显示实验信息,LED闪烁以示程序正在运行。

44.4 下载验证

本例程的测试,不需要安装特定的USB驱动,开发者只需用数据线将USB接口(不是UART接口)与PC端连接起来即可,并打开串口助手,选择对应的端口号进行数据发送操作。我们打开设备管理器(我用的是WIN10),在端口(COM和LPT)里面可以发现多出了一个COM8的设备,这就是USB虚拟的串口设备端口,如图44.3.1所示:

image007.png

图44.4.1 通过设备管理器查看USB虚拟的串口设备端口

如图44.4.1,ESP32通过USB虚拟的串口,被电脑识别了,端口号为:COM8(可变),字符串名字为:USB串行设备(COM8)。此时,开发板的LED闪烁,提示程序运行,如图44.4.2所示:

image009.png

图44.4.2 USB虚拟串口连接成功

然后我们打开XCOM,选择COM8(需根据自己的电脑识别到的串口号选择),并打开串口(注意:波特率可以随意设置),就可以进行测试了,如图44.4.3所示:

image011.png

图44.4.3 ESP32虚拟串口通信测试

可以看到,我们的串口调试助手,按发送按钮,可以收到电脑发送给ESP32的数据(原样返回),说明我们的实验是成功的。

至此,USB虚拟串口实验就完成了,通过本实验,我们就可以利用ESP32的USB,直接和电脑进行数据互传了,具有广泛的应用前景。