图46.3.3.1 SD卡模拟U盘工程分组
上图中位于components文件夹下的是我们自己编写的一些外设驱动,main文件夹下包含了一个APP文件与一个后缀为.yml的文件。APP文件夹下包含的是SD卡模拟U盘(USB)代码,而后缀为.yml的文件其主要作用是将项目中各组件的依赖项定义在单独的清单文件中,并以上图所示的方式进行命名。在我们的例程中提现出的作用就是简化了整个工程结构。我们在编译的过程中,系统便会帮我们自动生成USB外设所需要的依赖库:espressif_esp_tinyusb以及espressif_tinyusb。做到了即能简化项目工程,又能有效规避了在编译中遇到的错误,但前提是运行时得确保个人的电脑处于联网状态。
46.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驱动的正确性和可用性,为后续的开发工作提供了坚实的基础。
46.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 SD TEST", RED);
lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
lcd_show_string(30, 110, 200, 16, 16, "status:", RED);
while (sd_spi_init()) /* 检测不到SD卡 */
{
lcd_show_string(30, 110, 200, 16, 16, "SD Card Error!", RED);
vTaskDelay(500);
lcd_show_string(30, 130, 200, 16, 16, "Please Check! ", RED);
vTaskDelay(500);
}
tud_usb_sd(); /* USB初始化 */
while(1)
{
if ((g_usbdev.status & 0x0f) == 0x01)
{
lcd_show_string(110,
110,
lcd_self.width,
16,
16,
"connect success.....",
BLUE);
}
else if ((g_usbdev.status & 0x0f) == 0x00)
{
lcd_show_string(110,
110,
lcd_self.width,
16,
16,
"connect fail........",
BLUE);
}
LED_TOGGLE();
vTaskDelay(500);
}
}
此部分代码比较简单,通过tud_usb_sd()等函数初始化USB。由于该实验例程需要系统将storage分区模拟成U盘,所以在该函数中需要初始化SPIFFS分区,其次是用USB设备安装函数,用以USB设备登记。同时,LCD显示实验信息,LED闪烁以示程序正在运行。
46.4 下载验证
将程序下载到开发板后(注意:USB数据线,要插在USB端口!而不是UART端口!),我们打开设备管理器(我用的是WIN10),在端口(COM和LPT)里面可以发现多出了一个COM25的设备,这就是USB虚拟的串口设备端口,如下图所示:
图46.4.1 通过设备管理器查看USB虚拟的串口设备端口
如图46.4.1,ESP32通过SD卡模拟U盘,被电脑识别了,通用串行总线控制器显示的是:USB大容量存储设备(其实也不算大,也就差不多4MB...)。此时,开发板的LED在闪烁,提示程序运行。开发板的LCD显示“connect success.....”,如下图所示:
图46.4.2 USB虚拟串口连接成功
至此,SD卡模拟U盘实验就完成了,通过本实验,我们就可以利用ESP32的USB,直接和电脑进行数据互传了,具有广泛的应用前景。