跳到主要内容

ESP-IDF 开发

本章节包含以下内容:

  • ESP-IDF 入门与快速配置
  • 配置开发环境(Windows)
  • 常用示例说明(简要概览与代码说明)

ESP-IDF 入门教程

初次接触 ESP32 ESP-IDF 开发,想要快速上手?我们为您准备了一套通用的 入门教程

请注意:该教程使用 ESP32-S3-Zero 作为教学示例,所有硬件代码均基于其引脚布局。在动手实践前,建议您对照手中的开发板引脚图,确认引脚配置无误。

配置开发环境

备注

以下说明以 Windows 10/11 为主。macOS / Linux 请参阅 Espressif 官方指南: https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/get-started/index.html

  1. 安装 Visual Studio Code: https://code.visualstudio.com/

  2. 在 VS Code 中安装 ESP-IDF 扩展(扩展视图 Ctrl+Shift+X,搜索 ESP-IDF 并安装)。

    安装完成后,侧栏会出现 Espressif 图标,打开后选择 Configure ESP-IDF Extension,进入配置向导。

  3. 建议使用快速(Express)配置,按需选择:

    • 下载服务器:Espressif(国内镜像)或 GitHub
    • ESP-IDF 版本:按项目要求选择;若无特殊需求,选用最新稳定版本。注意:部分示例在较旧/特定 IDF 版本上测试通过。
    • 安装路径:尽量使用无空格且仅含 ASCII 字符的路径(例如 C:\Users<用户名>\esp),以避免路径相关问题。
  4. 点击 Install 开始自动下载与安装 ESP-IDF、工具链和创建 Python 虚拟环境,等待安装完成提示即可。

注意

若安装失败或需重装,可尝试删除 C:\Users\%Username%\espC:\Users\%Username%\.espressif 后重试。

示例程序

ESP-IDF 示例程序包 位于 examples/esp-idf 中

下面给出每个示例的目的、要点说明与运行效果(以便快速上手)。

示例程序基础例程说明依赖库
01_i2c使用 I2C 控制 IO 扩展芯片,从而周期性控制 LCD 背光的开关,形成闪烁效果。-
02_rtc使用板载 RTC 芯片,实现实时时钟显示与闹钟提醒功能。-
03_lcd初始化 LCD 并显示各种图形、文本和图片。-
04_isolation_io通过显示器验证隔离 IO 功能是否正常。-
05_sd通过显示器输出 SD 卡的挂载情况。-
06_touch演示了如何使用 5 点触摸。-
07_display_bmp展示了如何从 SD 卡读取并显示 BMP 图片。-
08_wifi_scan扫描附近 Wi-Fi 并在屏幕显示 SSID 列表。-
09_wifi_sta以 STA 模式连接 AP 并显示 IP 信息。-
10_wifi_ap使用屏幕显示热点的连接情况,显示连接设备的 MAC 地址。-
11_speaker_microphone录音与播放示例(codec、I2S)。-
12_lvgl_transplantLVGL 移植并运行官方 demo。LVGL
13_lvgl_codecLVGL 与音频结合示例。LVGL
14_tcp_udp_ntp展示 TCP/UDP 通信与 NTP 时间同步示例。LVGL

01_i2c

本示例演示如何通过 I2C 控制 IO 扩展芯片,从而周期性控制 LCD 背光的开关,形成闪烁效果。

硬件连接

  • 使用 USB 线把板子接入电脑

代码

Details
/*
* 完整代码请参考示例包中的 source code
* The full code can be found in the example package
*/

#include "driver/i2c.h"
// ... other includes

void app_main()
{
// Initialize the I2C interface and configure it for IO EXTENSION communication
DEV_I2C_Init();

/*
* After initializing I2C, a device name and slave address need to be created.
* This step corresponds to the specific slave device you want to communicate with.
* Note: The function `DEV_I2C_Set_Slave_Addr` is not explicitly called here,
* because `IO_EXTENSION_Init` already sets the slave address internally.
* Example:
* DEV_I2C_Set_Slave_Addr(i2c_master_dev_handle_t *dev_handle, uint8_t Addr)
*/
IO_EXTENSION_Init();
vTaskDelay(10 / portTICK_PERIOD_MS);
// Enter an infinite loop to control the backlight
while (1)
{
// Set the IO_EXTENSION_IO_2 pin to high (turn on the backlight)
IO_EXTENSION_Output(IO_EXTENSION_IO_2, 1); // Turn on backlight
vTaskDelay(500 / portTICK_PERIOD_MS); // Wait for 500 milliseconds

// Set the IO_EXTENSION_IO_2 pin to low (turn off the backlight)
IO_EXTENSION_Output(IO_EXTENSION_IO_2, 0); // Turn off backlight
vTaskDelay(500 / portTICK_PERIOD_MS); // Wait for 500 milliseconds
}
}

代码解释

  • DEV_I2C_Init():初始化 I2C 驱动,通过 i2c_config_t 结构体定义 SDA/SCL 引脚及频率,并调用 i2c_driver_install 注册驱动。
  • IO_EXTENSION_Init():初始化 IO 扩展芯片,内部通过 I2C 接口设置芯片的默认寄存器状态与引脚模式。
  • IO_EXTENSION_Output():通过 i2c_master_write_to_device 向扩展芯片发送控制指令,利用位运算修改特定引脚的电平状态。

运行效果

  • 背光按固定周期亮灭切换;串口可输出当前背光状态或 I2C 读写结果。

02_rtc

本示例演示板载 PCF85063 的时间读写与闹钟功能。

硬件连接

  • 使用 USB 线把板子接入电脑

代码

Details
void app_main()
{
datetime_t Now_time;

// Initialize the I2C interface
DEV_I2C_Init();

// Initialize external IO extension chip
IO_EXTENSION_Init();

// Initialize PCF85063A RTC
PCF85063A_Init();

// Set current time
PCF85063A_Set_All(Set_Time);

// Set alarm time
PCF85063A_Set_Alarm(Set_Alarm_Time);

// Enable alarm interrupt
PCF85063A_Enable_Alarm();

while (1)
{
// Read current time from RTC
PCF85063A_Read_now(&Now_time);

// Format current time as a string
datetime_to_str(datetime_str, Now_time);
ESP_LOGI(TAG, "Now_time is %s", datetime_str);

// Poll external IO pin for alarm (low level = alarm triggered)
if (IO_EXTENSION_RTC_INT_READ() == 0)
{
// Re-enable alarm if repeated alarms are required
PCF85063A_Enable_Alarm();
ESP_LOGI(TAG, "The alarm clock goes off.");
}

// Wait for 1 second
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}

代码解释

  • PCF85063A_Init():初始化 PCF85063A 实时时钟,配置 I2C 地址、使能 oscillator 并设置为 24-hour 模式。
  • PCF85063A_Set_All():设置 PCF85063A 所有寄存器值,包括时间、闹钟时间、控制寄存器等。
  • PCF85063A_Read_now():从 PCF85063A 读取当前时间,将 BCD 编码转换为十进制格式。

运行效果

  • 串口或屏幕显示当前时间;闹钟触发时输出提示信息。

03_lcd

本示例演示 LCD 初始化与基础绘制流程,验证 RGB LCD 显示链路与帧缓冲刷新。

硬件连接

  • 使用 USB 线把板子接入电脑

代码

Details
void app_main()
{
// Initialize I2C communication and CH422G hardware interface
DEV_I2C_Init();
IO_EXTENSION_Init();

// Initialize the Waveshare ESP32-S3 RGB LCD
waveshare_esp32_s3_rgb_lcd_init();

// Turn on the LCD backlight
wavesahre_rgb_lcd_bl_on();
// Uncomment the following line to turn off the backlight if needed
// wavesahre_rgb_lcd_bl_off();

// Allocate memory for the screen's frame buffer
UDOUBLE Imagesize = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * 2; // Each pixel takes 2 bytes in RGB565
UBYTE *BlackImage;
if ((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) // Allocate memory
{
printf("Failed to apply for black memory...\r\n");
exit(0); // Exit the program if memory allocation fails
}

// Create a new image canvas and set its background color to white
Paint_NewImage(BlackImage, EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, 0, WHITE);

// Set the canvas scale
Paint_SetScale(65);
Paint_SetRotate(ROTATE);
// Clear the canvas and fill it with a white background
Paint_Clear(WHITE);
}

代码解释

  • waveshare_esp32_s3_rgb_lcd_init():调用 esp_lcd_new_rgb_panel 创建面板句柄,配置 RGB 接口时序参数以适配 4.3 寸屏幕的分辨率。
  • malloc():使用 MALLOC_CAP_SPIRAM 标志在外部 PSRAM 中分配 Framebuffer,解决高分辨率显示对 SRAM 占用过大的问题。
  • Paint_NewImage():将分配的显示坐标与绘图上下文绑定。

运行效果

  • 屏幕依次显示颜色渐变、基础图形与文字内容。

04_isolation_io

本示例验证隔离 IO 功能。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 根据示例连接 DO/DI 引脚测试隔离功能。

代码

Details
void app_main()
{
// Initialize I2C communication and CH422G hardware interface
DEV_I2C_Init();
IO_EXTENSION_Init();

IO_EXTENSION_IO_Mode(DI0 | DI5); // Set EXIO0 and EXIO5 to input mode

// Initialize the Waveshare ESP32-S3 RGB LCD
waveshare_esp32_s3_rgb_lcd_init();

// Turn on the LCD backlight
wavesahre_rgb_lcd_bl_on();
// Uncomment the following line to turn off the backlight if needed
// wavesahre_rgb_lcd_bl_off();

// Allocate memory for the screen's frame buffer
UDOUBLE Imagesize = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * 2; // Each pixel takes 2 bytes in RGB565
UBYTE *BlackImage;
if ((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) // Allocate memory
{
printf("Failed to apply for black memory...\r\n");
exit(0); // Exit the program if memory allocation fails
}

// Create a new image canvas and set its background color to white
Paint_NewImage(BlackImage, EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, 0, WHITE);

// Set the canvas scale
Paint_SetScale(65);
Paint_SetRotate(ROTATE);
// Clear the canvas and fill it with a white background
Paint_Clear(WHITE);
}

代码解释

  • IO_EXTENSION_IO_Mode():配置扩展芯片的引脚工作模式,如将特定引脚设置为输入模式以读取隔离 DI 信号。
  • IO_EXTENSION_Output():控制扩展芯片的输出引脚电平,例如驱动隔离 DO 端口输出高/低电平以控制外部继电器或负载。
  • IO_EXTENSION_Read():实时读取扩展芯片输入引脚的状态,用于获取隔离 DI 端口的外部传感器或开关量反馈。

运行效果

  • 烧录成功后,屏幕会根据背部接线情况显示红色还是绿色。
  • 当正确接线,屏幕显示绿色。
  • 当错误接线,屏幕显示红色。

05_sd

本示例演示 SD 卡 挂载与文件系统访问,并在屏幕上显示挂载状态与基础信息。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 插入 TF/SD 卡.

代码

Details
void app_main()
{
// Initialize I2C communication and configure the IO EXTENSION GPIO expander
DEV_I2C_Init(); // Initialize the I2C bus
IO_EXTENSION_Init(); // Initialize IO EXTENSION chip

IO_EXTENSION_Output(IO_EXTENSION_IO_4, 1); // Set CS (chip select) pin high

// Initialize the Waveshare ESP32-S3 RGB LCD
waveshare_esp32_s3_rgb_lcd_init();
wavesahre_rgb_lcd_bl_on(); // Turn on the LCD backlight
// wavesahre_rgb_lcd_bl_off(); // Uncomment to turn off the backlight if needed

// Allocate memory for the LCD's frame buffer
UDOUBLE Imagesize = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * 2; // Each pixel uses 2 bytes in RGB565 format
UBYTE *BlackImage;
if ((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) // Allocate memory for the image
{
printf("Failed to allocate memory for frame buffer...\r\n");
exit(0); // Exit if memory allocation fails
}

// Create a new image canvas and set its background color to white
Paint_NewImage(BlackImage, EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, 0, WHITE);
Paint_SetScale(65); // Set the canvas scale
Paint_Clear(WHITE); // Clear the canvas with a black background

// Draw static text on the canvas
Paint_DrawString_EN(150, 130, "SD TEST", &Font48, BLACK, WHITE);
Paint_DrawString_EN(150, 180, "Waveshare ESP32 S3", &Font24, BLACK, WHITE);
Paint_DrawString_EN(150, 210, "https://www.waveshare.com", &Font24, BLACK, WHITE);

char Total[100], Available[100]; // Buffers for formatted text
}

代码解释

  • esp_vfs_fat_sdmmc_mount():将 SD 卡挂载到虚拟文件系统(VFS),允许使用标准 POSIX 接口(如 fopen)访问 FATFS 分区。
  • sd_mmc_init():初始化 SDMMC 主机控制器,配置 1-bit 或 4-bit 总线模式,并根据硬件设计设置工作频率。
  • esp_vfs_fat_sdcard_unmount():将 SD 卡从虚拟文件系统中卸载,释放资源并允许重新挂载。

运行效果

  • 屏幕提示挂载成功/失败,并显示卡容量、文件列表或测试文件读写结果。

06_touch

本示例演示触摸控制器驱动与 5 点触摸 读取,验证触摸坐标与屏幕坐标映射。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 手指在屏幕上触摸。

代码

Details
int app_main()
{
touch_gt911_point_t point_data; // Structure to store touch point data

// Initialize the GT911 touch screen controller
touch_gt911_init();

// Initialize the Waveshare ESP32-S3 RGB LCD hardware
waveshare_esp32_s3_rgb_lcd_init();

// Turn on the LCD backlight
wavesahre_rgb_lcd_bl_on();

// Frame buffer pointers for double buffering
void *buf1 = NULL;
void *buf2 = NULL;

// Retrieve pointers to the frame buffers
waveshare_get_frame_buffer(&buf1, &buf2);
if (buf1 == NULL || buf2 == NULL) {
printf("Error: buf1 and buf2 are NULL!\n");
return;
}

// Initialize the graphics canvas with buf2
Paint_NewImage(buf2, EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, 0, WHITE);

// Set the scale for the graphical canvas
Paint_SetScale(65);

// Clear the canvas and fill it with a white background
Paint_Clear(WHITE);

// Copy buf2 content to buf1 to sync buffers
memcpy(buf1, buf2, EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * 2);

// Display the initial blank screen on the LCD
wavesahre_rgb_lcd_display(buf1);

// Arrays to store previous touch point positions and their active states
static uint16_t prev_x[ESP_LCD_TOUCH_MAX_POINTS];
static uint16_t prev_y[ESP_LCD_TOUCH_MAX_POINTS];
static bool active[ESP_LCD_TOUCH_MAX_POINTS]; // Track if a touch point is active
static uint16_t color[ESP_LCD_TOUCH_MAX_POINTS] = {
0x7DDF, 0xFBE4, 0x7FE0, 0xEC1D, 0xFEE0
}; // Predefined colors for touch points
}

代码解释

  • touch_gt911_init():初始化触摸控制器,配置 I2C 从机地址,并通过复位引脚触发芯片自检。
  • touch_gt911_read_point():读取状态寄存器获取当前触点数量,并依次提取 5 组触点的 X/Y 坐标数据。
  • Paint_DrawCircle():在指定坐标绘制一个指定半径和颜色的圆。

运行效果

烧录成功后,显示 5 点触摸读取,并根据触点坐标实时绘制圆形。

07_display_bmp

本示例从 SD 卡读取 BMP 文件并显示到屏幕,验证文件读取、解码与显示刷新链路。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 插入含 BMP 文件的 TF/SD 卡。

代码

Details
void app_main()
{
touch_gt911_point_t point_data; // Structure to store touch point data

// Initialize the GT911 touch screen controller
touch_gt911_init();

// Initialize the Waveshare ESP32-S3 RGB LCD hardware
waveshare_esp32_s3_rgb_lcd_init();

// Turn on the LCD backlight
wavesahre_rgb_lcd_bl_on();

// EXAMPLE_PIN_NUM_TOUCH_INT
// Allocate memory for the LCD's frame buffer
UDOUBLE Imagesize = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * 2; // Each pixel uses 2 bytes in RGB565 format
UBYTE *BlackImage;
if ((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) // Check if memory allocation is successful
{
printf("Failed to allocate memory for frame buffer...\r\n");
exit(0); // Exit if memory allocation fails
}

// Initialize the graphics canvas with the allocated buffer
Paint_NewImage(BlackImage, EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, 0, WHITE);

// Set the scale for the graphical canvas
Paint_SetScale(65);

// Clear the canvas and fill it with a white background
Paint_Clear(WHITE);
}

代码解释

  • GUI_ReadBmp():从 SD 卡读取 BMP 文件,解析文件头获取图像尺寸与像素数据偏移。
  • Paint_Clear():清除画布,填充为指定颜色。
  • Paint_DrawLine():在指定坐标绘制一条线,可设置颜色、线宽、样式。

运行效果

  • 屏幕显示 SD 卡中的 BMP 图片;串口输出图片信息与加载耗时。

08_wifi_scan

本示例扫描周围 Wi‑Fi 热点并在屏幕上展示 SSID/RSSI/加密方式 等信息。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 确保周围存在可扫描到的 Wi‑Fi。

代码

Details
int app_main()
{
// Initialize Wi-Fi settings
wifi_init();
uint8_t chinese_num = 0; // Counter for Wi-Fi networks with Chinese SSIDs

// Display static information on the LCD screen
Paint_DrawString_EN(10, 160, "ESP32-S3-Touch-LCD-4.3C", &Font24, RED, WHITE); // Display title
Paint_DrawString_EN(10, 200, "WiFi SCAN Test", &Font24, RED, WHITE); // Display Wi-Fi scan message
Paint_DrawString_EN(10, 240, "800x480", &Font24, RED, WHITE); // Display screen resolution
Paint_DrawLine(400, 0, 400, 480, BLUE, DOT_PIXEL_2X2, LINE_STYLE_SOLID); // Draw a vertical line to separate sections
Paint_DrawString_EN(440, 0, "Scanning now...", &Font24, BLACK, WHITE); // Show scanning status message
wavesahre_rgb_lcd_display(BlackImage); // Refresh the display with the updated image

// Clear the top section of the screen to display scanning results
Paint_ClearWindows(440, 0, 800, 25, WHITE);

// Start Wi-Fi scanning to find available networks
wifi_scan();

// Loop through the Wi-Fi APs found and display them on the screen
for (int i = 0; i < DEFAULT_SCAN_LIST_SIZE; i++) {
// Skip SSID with Chinese characters
if (contains_chinese((const char *)ap_info[i].ssid)){
chinese_num++; // Increment the count for networks with Chinese SSIDs
printf("Skipping SSID with Chinese characters: %s \r\n", ap_info[i].ssid);
}
else {
// Display the SSID (Wi-Fi network name) on the screen
Paint_DrawString_EN(440, (i - chinese_num) * 24, (const char *)ap_info[i].ssid, &Font24, BLACK, WHITE);
}
}

// Update the screen with the new image (BlackImage is the framebuffer being drawn to)
wavesahre_rgb_lcd_display(BlackImage); // Refresh the display to show the updated list of networks
}

代码解释

  • wifi_init(): 初始化 Wi-Fi 驱动程序,分配资源并启动低功耗无线射频管理任务。
  • wifi_scan():启动周围接入点的扫描流程,支持全频道轮询或特定频道扫描,并配置最大返回结果数量。
  • contains_chinese():检查字符串是否包含中文字符,返回 truefalse

运行效果

  • 屏幕列出周围热点信息;串口输出扫描数量与每个 AP 的简要数据。

09_wifi_sta

本示例以 STA 模式连接指定 AP,并在屏幕上显示连接状态与 IP 信息。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 准备可连接的 Wi‑Fi(SSID/密码)。

代码

Details
#define USER_SSID "SSID"  // Wi-Fi SSID (network name)
#define USER_PASS "PASSWORD" // Wi-Fi password

void app_main()
{
// Initialize the Non-Volatile Storage (NVS) for Wi-Fi settings
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// If NVS has no free pages or a new version is found, erase and reinitialize NVS
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}

// Initialize I2C communication and IO EXTENSION hardware interface for GPIO control
DEV_I2C_Init(); // Initialize I2C
IO_EXTENSION_Init(); // Initialize GPIO control using the IO EXTENSION chip

// Initialize the Waveshare ESP32-S3 RGB LCD display
waveshare_esp32_s3_rgb_lcd_init();

// Turn on the LCD backlight
wavesahre_rgb_lcd_bl_on();
// Uncomment the next line to turn off the backlight if needed
// wavesahre_rgb_lcd_bl_off();

// Allocate memory for the screen's framebuffer (image buffer)
UDOUBLE Imagesize = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * 2; // Each pixel takes 2 bytes in RGB565 format
UBYTE *BlackImage;
if ((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) { // Allocate memory for the framebuffer
printf("Failed to apply for black memory...\r\n");
exit(0); // Exit the program if memory allocation fails
}

// Create a new image canvas and set its background color to white
Paint_NewImage(BlackImage, EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, 0, WHITE);

// Set the canvas scale and rotation for the display
Paint_SetScale(65); // Set the scale for the image
Paint_SetRotate(ROTATE); // Set the rotation (0 degrees)

// Clear the canvas and fill it with a white background
Paint_Clear(WHITE);

// Initialize Wi-Fi settings (connect to the specified Wi-Fi network)
wifi_init();

// Display some information on the LCD screen
Paint_DrawString_EN(10, 160, "ESP32-S3-Touch-LCD-4.3C", &Font24, RED, WHITE); // Display title
Paint_DrawString_EN(10, 200, "WiFi STA Test", &Font24, RED, WHITE); // Display Wi-Fi test message
Paint_DrawString_EN(10, 240, "800x480", &Font24, RED, WHITE); // Display screen resolution
Paint_DrawString_EN(440, 160, "wifi connecting......", &Font24, BLACK, WHITE); // Display Wi-Fi connection status
Paint_DrawLine(400, 0, 400, 480, BLUE, DOT_PIXEL_2X2, LINE_STYLE_SOLID); // Draw a vertical line on the display

wavesahre_rgb_lcd_display(BlackImage); // Refresh the display with the updated image (BlackImage is the framebuffer)

// Initialize Wi-Fi in STA mode and attempt to connect to the specified SSID and password
wifi_sta_init((uint8_t *)USER_SSID, (uint8_t *)USER_PASS, WIFI_AUTH_WPA2_PSK);

// Update the screen with the new image (BlackImage is the framebuffer being drawn to)
wavesahre_rgb_lcd_display(BlackImage); // Refresh the display again to show the updated image
}

代码解释

  • nvs_flash_init():初始化非易失性存储(NVS),用于持久化保存 Wi-Fi 连接配置(如 SSID 和密码)。
  • wifi_sta_init():配置 Wi-Fi 为 Station 模式,并设置认证加密方式(如 WPA2_PSK),发起连接请求。
  • wifi_init():初始化 Wi-Fi 驱动程序,分配资源并启动低功耗无线射频管理任务。

运行效果

  • 屏幕显示连接成功与分配到的 IP;断开时提示重连状态。

10_wifi_ap

本示例启用 SoftAP 热点,并在屏幕上显示连接设备信息(如 MAC、连接数量)。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 手机/电脑连接到开发板热点。

代码

Details
// Initialize SoftAP (Wi-Fi Access Point) with SSID, password, and channel
int app_main(void)
{
wifi_ap_init((uint8_t *)USER_SSID, (uint8_t *)USER_PASS, 1);

static uint8_t connection_num = 0; // Variable to track the number of connected stations
while (1)
{
esp_err_t ret = esp_wifi_ap_get_sta_list(&sta_list); // Get the list of connected stations (devices)
if (ret == ESP_OK)
{
// If the number of connected stations has changed, update the UI
if (connection_num != sta_list.num)
{
char station_num[32];
char station_mac[32]; // Buffer to hold formatted MAC address string


Paint_ClearWindows(430, 160, 800, 480, WHITE); // Clear the section of the screen displaying the connection info

snprintf(station_num, sizeof(station_num), "Connected: %d", sta_list.num); // Format the number of connected stations
Paint_DrawString_EN(430, 160, station_num, &Font24, BLACK, WHITE); // Display the number of connected devices
if (sta_list.num == 0)
{
ESP_LOGE(TAG_AP, "No device connected."); // Log error if no devices are connected
}
else
{
for (int i = 0; i < sta_list.num; i++)
{
wifi_sta_info_t sta_info = sta_list.sta[i]; // Get station info (MAC address, RSSI, etc.)

// Format the MAC address and display it in the list
snprintf(station_mac, sizeof(station_mac), MACSTR, MAC2STR(sta_info.mac));
Paint_DrawString_EN(430, 200 , "MAC:", &Font24, BLACK, WHITE); // Label for MAC address
Paint_DrawString_EN(430, 240 + (i * 40), station_mac, &Font24, BLACK, WHITE); // Display MAC address

// Log information about the connected stations
ESP_LOGI(TAG_AP, "STA %d: MAC Address: " MACSTR, i, MAC2STR(sta_info.mac)); // Log MAC address
ESP_LOGI(TAG_AP, "STA %d: RSSI: %d", i, sta_info.rssi); // Log signal strength (RSSI)
}
}
// Update the screen with the new image (BlackImage is the framebuffer being drawn to)
wavesahre_rgb_lcd_display(BlackImage); // Refresh the display again to show the updated image
connection_num = sta_list.num; // Update the connection number variable
}
}
else
{
ESP_LOGE(TAG_AP, "Failed to get STA list"); // Log error if failed to get list of connected stations
}
// Delay for 10ms before the next loop iteration
vTaskDelay(100); // Short delay to avoid overloading the CPU
}
}

代码解释

  • wifi_ap_init():初始化软热点(SoftAP)模式,设置 SSID、密码及工作信道,并配置最大接入客户端数量。
  • esp_wifi_ap_get_sta_list():定期查询已连接的站点列表,获取当前连接设备的数量及其硬件 MAC 地址。
  • MACSTR/MAC2STR():使用格式化宏将 6 字节的原始 MAC 地址转换为易读的字符串格式,以便在 UI 上展示。

运行效果

  • 屏幕显示热点状态与已连接设备信息;串口同步输出连接/断开日志。

11_speaker_microphone

本示例演示音频采集与播放链路,包含 麦克风录音扬声器播放Codec + I2S)。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 通过板载麦克风录音并从扬声器回放。

代码

Details
void app_main()
{
touch_gt911_point_t point_data;
DEV_I2C_Init();
IO_EXTENSION_Init();
touch_gt911_init(DEV_I2C_Get_Bus_Device());
waveshare_esp32_s3_rgb_lcd_init();
wavesahre_rgb_lcd_bl_on();

// Allocate LCD frame buffer
UDOUBLE Imagesize = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * 2;
BlackImage = (UBYTE *)malloc(Imagesize);
if (!BlackImage)
{
printf("Failed to allocate memory for frame buffer...\r\n");
exit(0);
}

Paint_NewImage(BlackImage, EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, 0, WHITE);
Paint_SetScale(65);
Paint_Clear(WHITE);

// Draw initial red record button
Paint_DrawCircle(405, 450, 15, RED, DOT_PIXEL_2X2, DRAW_FILL_FULL);
Paint_DrawString_EN(100, 150, "Click to start recording", &Font48, BLACK, WHITE);
wavesahre_rgb_lcd_display(BlackImage);

// Initialize speaker codec
codec_init();
speaker_codec_volume_set(100, NULL);
microphone_codec_gain_set(30, NULL);

// Allocate memory for recording buffer
record_buffer = heap_caps_malloc(BUFFER_SIZE * sizeof(int16_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
if (!record_buffer)
{
ESP_LOGE(TAG, "Failed to allocate buffer");
vTaskDelete(NULL);
return;
}

// Touch handling loop
static uint16_t prev_x;
static uint16_t prev_y;
bool is_playing = false;

while (1)
{
point_data = touch_gt911_read_point(1);
if (point_data.cnt == 1)
{
if (prev_x == point_data.x[0] && prev_y == point_data.y[0])
{
continue;
}
else if (point_data.x[0] > 390 && point_data.x[0] < 420 &&
point_data.y[0] > 420 && point_data.y[0] < 480)
{
Paint_Clear(WHITE);
is_playing = !is_playing;
play_or_pause(is_playing);

prev_x = point_data.x[0];
prev_y = point_data.y[0];
}
}
vTaskDelay(30 / portTICK_PERIOD_MS);
}
}

代码解释

  • codec_init():初始化音频编解码芯片,配置采样频率、位宽以及输入输出路由(如开启麦克风增益和扬声器功放)。
  • heap_caps_malloc():在 PSRAM 中分配大容量录音缓冲区,支持长时间音频采集而不会耗尽内部 SRAM。

运行效果

  • 可听到回放音频;串口输出录音/播放状态与音频参数。

12_lvgl_transplant

本示例完成 LVGL 基础移植,验证显示驱动、触摸输入与 LVGL 刷新流程,并运行官方 demo。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 可触摸屏幕交互。

代码

Details
void app_main()
{
static esp_lcd_panel_handle_t panel_handle = NULL; // Declare a handle for the LCD panel
static esp_lcd_touch_handle_t tp_handle = NULL;

DEV_I2C_Init(); // Initialize I2C port
IO_EXTENSION_Init(); // Initialize the IO EXTENSION GPIO chip

wavesahre_rgb_lcd_bl_off(); // Turn off the LCD backlight

tp_handle = touch_gt911_init(DEV_I2C_Get_Bus_Device()); // Initialize the GT911 touch screen controller
panel_handle = waveshare_esp32_s3_rgb_lcd_init(); // Initialize the Waveshare ESP32-S3 RGB LCD hardware
ESP_ERROR_CHECK(lvgl_port_init(panel_handle, tp_handle)); // Initialize LVGL with the panel and touch handles

ESP_LOGI(TAG, "Display LVGL demos");

// Lock the mutex due to the LVGL APIs are not thread-safe
if (lvgl_port_lock(-1)) {
// lv_demo_stress();
// lv_demo_benchmark();
// lv_demo_music();
lv_demo_widgets();
// Release the mutex
lvgl_port_unlock();
}
wavesahre_rgb_lcd_bl_on(); // Turn on the LCD backlight
}

代码解释

  • lvgl_port_init():封装 LVGL 核心组件的初始化,包括内存池分配、计时器注册以及显示/输入设备的抽象绑定。
  • lvgl_port_lock():由于 LVGL 核心 API 非线程安全,在跨任务调用 UI 更新时必须通过互斥锁确保原子操作。
  • lv_timer_handler():UI 主循环处理函数,负责计算动画、刷新脏区域像素以及处理用户输入事件。

运行效果

  • 屏幕显示 LVGL demo 界面,可触摸交互;串口输出 LVGL 初始化与刷新信息。

13_lvgl_codec

本示例将 LVGL UI 与音频功能结合,演示 UI 控制音量/播放状态等交互。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 扬声器与麦克风可用。

代码

Details
void app_main()
{
static esp_lcd_panel_handle_t panel_handle = NULL; // Declare a handle for the LCD panel
static esp_lcd_touch_handle_t tp_handle = NULL;

DEV_I2C_Init(); // Initialize I2C port
IO_EXTENSION_Init(); // Initialize the IO EXTENSION GPIO chip

wavesahre_rgb_lcd_bl_off(); // Turn off the LCD backlight

tp_handle = touch_gt911_init(DEV_I2C_Get_Bus_Device()); // Initialize the GT911 touch screen controller
panel_handle = waveshare_esp32_s3_rgb_lcd_init(); // Initialize the Waveshare ESP32-S3 RGB LCD hardware
ESP_ERROR_CHECK(lvgl_port_init(panel_handle, tp_handle)); // Initialize LVGL with the panel and touch handles

ESP_LOGI(TAG, "Display LVGL demos");

// Initialize SD card
if (sd_mmc_init() == ESP_OK)
{
ESP_LOGI(TAG, "SD Card OK!");
ESP_LOGI(TAG, "Click the arrow to start.");

list_files(MOUNT_POINT"/music");
if (mp3_num == 0)
{
ESP_LOGI(TAG, "No MP3 file found in SD card.");
return;
}
else
{
ESP_LOGI(TAG, "music start");
}
}
else
{
ESP_LOGI(TAG, "SD Card Fail!");
return;
}

// Initialize speaker and audio player
speaker_codec_init();
speaker_codec_volume_set(50, NULL);
speaker_player_register_callback(speaker_callback, NULL);
speaker_player_init();

// Lock the mutex due to the LVGL APIs are not thread-safe
if (lvgl_port_lock(-1)) {
user_lv_demo_music();
// Release the mutex
lvgl_port_unlock();
}
wavesahre_rgb_lcd_bl_on(); // Turn on the LCD backlight
}

代码解释

  • sd_mmc_init():初始化 SDMMC 控制器并挂载 FATFS 分区,用于从 SD 卡检索和加载 MP3 音乐文件。
  • speaker_player_init():创建音频播放后台任务,通过生产者-消费者模型实现音频文件的流式解码与播放。
  • lv_obj_add_event_cb():为 UI 控件绑定交互回调,当用户操作滑块或按钮时,通过消息机制动态调整播放器状态。

运行效果

  • 屏幕显示音频控制界面并可操作;播放状态与音量变化实时生效。

14_tcp_udp_ntp

本示例演示基础网络通信(TCP/UDP)与 NTP 对时流程,验证网络栈与时间同步功能。

硬件连接

  • 使用 USB 线把板子接入电脑;
  • 需先确保 Wi‑Fi 已连接。

代码

Details
/*
* 示例代码结构参考
* Structure reference for TCP/UDP/NTP
*/

void peripheral_init(void)
{
// Initialize NVS
esp_err_t ret = nvs_flash_init();
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);
ESP_ERROR_CHECK(esp_event_loop_create_default());
// Initialize Hardware
DEV_I2C_Init();
IO_EXTENSION_Init();
// Initialize LCD and Touch
esp_lcd_panel_handle_t panel_handle = waveshare_esp32_s3_rgb_lcd_init();
wavesahre_rgb_lcd_bl_on();
esp_lcd_touch_handle_t tp_handle = touch_gt911_init(DEV_I2C_Get_Bus_Device());
// Initialize LVGL
ESP_ERROR_CHECK(lvgl_port_init(panel_handle, tp_handle));
// Initialize UI
ui_init();
ui_log("System Initialized. Waiting for WiFi...");
// Initialize WiFi
wifi_init_sta();
// Wait for WiFi connection
xEventGroupWaitBits(get_wifi_event_group(), WIFI_CONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
// Initialize NTP
initialize_sntp();
}

代码解释

  • peripheral_init():作为系统外设初始化总入口,依次完成 NVS、事件循环、I2C 扩展、LCD/触摸、LVGL UI、Wi‑Fi 和 NTP 初始化,为后续网络通信和时间同步打好基础。
  • wifi_init_sta():将 Wi‑Fi 配置为 STA 模式并发起连接,为 TCP/UDP 通信和 NTP 对时提供稳定的网络通道。
  • initialize_sntp():在确认 Wi‑Fi 已联网后启动 SNTP 客户端,从上游 NTP 服务器同步系统时间,为 localtime 等时间相关接口提供正确的基础时间。

运行效果

  • 串口输出连接信息;使用网络调试助手设置对应 IP 地址和端口号,可以进行基本数据交互;并且屏幕显示网络状态与当前时间。