图44.3.1.1 USB虚拟串口实验程序流程图
44.3.2 USB虚拟串口函数解析
ESP-IDF提供了一套API来配置USB。要使用此功能,需要导入必要的头文件:
#include "tinyusb.h"
#include "tusb_cdc_acm.h"
接下来,作者将介绍一些常用的ESP32-S3中的USB函数,这些函数的描述及其作用如下:
1,USB设备登记
该函数用给定的配置,来配置USB设备,该函数原型如下所示:
esp_err_t tinyusb_driver_install(const tinyusb_config_t *config);
该函数的形参描述如下表所示:
表44.3.2.1 tinyusb_driver_install ()函数形参描述
该函数的返回值描述,如下表所示:
表44.3.2.2 函数tinyusb_driver_install ()返回值描述
该函数使用tinyusb_config_t类型的结构体变量传入,该结构体的定义如下所示:
表44.3.2.3 i2s_pin_config_t结构体参数值描述
完成上述结构体参数配置之后,可以将结构传递给 tinyusb_driver_install () 函数,用以安装USB驱动。
2,USB设备初始化
该函数用给定的配置,来初始化USB设备,该函数原型如下所示:
esp_err_t tusb_cdc_acm_init(const tinyusb_config_cdcacm_t *cfg);
该函数的形参描述如下表所示:
表44.3.2.4 tusb_cdc_acm_init ()函数形参描述
该函数的返回值描述,如下表所示:
表44.3.2.5 函数tusb_cdc_acm_init ()返回值描述
该函数使用tinyusb_config_cdcacm_t类型的结构体变量传入,该结构体的定义如下所示:
| 成员变量 | |
| | |
| |
| |
| |
| 指向' tusb_cdcacm_callback_t '类型的函数的指针,该函数将作为回调处理,例程中配置为NULL |
callback_line_state_changed | |
callback_line_coding_changed | |
表44.3.2.6 tinyusb_config_cdcacm_t结构体参数值描述
完成上述结构体参数配置之后,可以将结构传递给 tusb_cdc_acm_init () 函数,用以实例化USB。
3,注册回调函数
该步骤用以注册回调函数,该函数原型如下所示:
esp_err_t tinyusb_cdcacm_register_callback(tinyusb_cdcacm_itf_t itf,
cdcacm_event_type_t event_type);
该函数的形参描述如下表所示:
表44.3.2.7 tinyusb_cdcacm_register_callback ()函数形参描述
该函数的返回值描述,如下表所示:
| |
ESP_OK | 成功 |
ESP_ERR_INVALID_ARG | 参数错误 |
表44.3.2.8 函数tinyusb_cdcacm_register_callback ()返回值描述
4,发送数据1
该函数将数据从字节数组写入写入缓冲区,该函数原型如下所示:
size_t tinyusb_cdcacm_write_queue(tinyusb_cdcacm_itf_t itf,
const uint8_t *in_buf,
size_t in_size);
该函数的形参描述如下表所示:
参数 | 描述 |
| CDC对象的编号 |
| 源数组 |
| 从SRC数组写入的大小 |
表44.3.2.9 tinyusb_cdcacm_write_queue ()函数形参描述
该函数的返回值描述,如下表所示:
| |
ESP_OK | 成功 |
ESP_ERR_INVALID_ARG | 参数错误 |
表44.3.2.10 函数tinyusb_cdcacm_write_queue ()返回值描述
5,发送数据2
该函数从写缓冲区发送所有数据,该函数原型如下所示:
esp_err_t tinyusb_cdcacm_write_flush(tinyusb_cdcacm_itf_t itf,
uint32_t timeout_ticks);
该函数的形参描述如下表所示:
表44.3.2.11 tinyusb_cdcacm_write_flush ()函数形参描述
该函数的返回值描述,如下表所示:
| |
ESP_OK | 成功 |
ESP_ERR_INVALID_ARG | 参数错误 |
表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自行编写的代码。最终得到如下图所示的工程:
图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_t i2c0_master;
/**
* @retval 无
*/
void app_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, "USB USART 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所示:
图44.4.1 通过设备管理器查看USB虚拟的串口设备端口
如图44.4.1,ESP32通过USB虚拟的串口,被电脑识别了,端口号为:COM8(可变),字符串名字为:USB串行设备(COM8)。此时,开发板的LED闪烁,提示程序运行,如图44.4.2所示:
图44.4.2 USB虚拟串口连接成功
然后我们打开XCOM,选择COM8(需根据自己的电脑识别到的串口号选择),并打开串口(注意:波特率可以随意设置),就可以进行测试了,如图44.4.3所示:
图44.4.3 ESP32虚拟串口通信测试
可以看到,我们的串口调试助手,按发送按钮,可以收到电脑发送给ESP32的数据(原样返回),说明我们的实验是成功的。
至此,USB虚拟串口实验就完成了,通过本实验,我们就可以利用ESP32的USB,直接和电脑进行数据互传了,具有广泛的应用前景。