跳到主要内容

ESP-IDF 开发

本章节包含以下内容,请按需阅读:

ESP-IDF 入门教程

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

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

配置 ESP-IDF 开发环境

信息

ESP32-C5-Touch-LCD-1.69 示例工程需要 ESP-IDF v5.3 或更新版本。

备注

以下内容以 Windows 系统为例,使用 VS Code + ESP-IDF 扩展 的方式进行开发。Mac/Linux 用户请参考 官方说明

版本选择

此部分图示以安装 ESP-IDF V5.5.2 为例示范,安装时请选用与您开发板示例匹配的 ESP-IDF 版本。

安装 ESP-IDF 开发环境

  1. 前往 ESP-IDF Installation Manager 下载 ESP-IDF 安装管理器。这是乐鑫最新推出的跨平台安装工具,下文将演示如何使用其离线安装功能。

    在页面中点击 Offline Installer 标签,然后在筛选栏中选择 Windows 操作系统和你需要的 ESP-IDF 版本(图示仅为参考,请以实际为准)。

    下载 EIM 和整合包

    确认选择无误后,点击下载按钮。浏览器将自动同时下载两个文件:一个是 ESP-IDF 离线整合包(.zst),另一个是 ESP-IDF 安装器(.exe)

    下载 EIM 和整合包2

    请耐心等待两个文件下载完成。

  2. 下载完成后,双击运行 ESP-IDF 安装器(eim-gui-windows-x64.exe)

    启动后,可在右上角将界面语言切换为中文。

    切换 EIM 语言

    安装工具会自动检测同一目录下是否存在离线整合包。点击 从存档安装

    自动检测整合包

    接下来,选择安装路径。建议使用默认路径;若需自定义,请确保路径中不包含中文或空格。确认无误后,点击 开始安装

    选择安装路径
  3. 当看到如下界面时,表示 ESP-IDF 已安装成功。

    安装成功
  4. 建议同时安装驱动程序。点击 完成安装,然后点击 安装驱动程序

    用 ESP-IDF 安装管理器安装驱动

安装 Visual Studio Code 与 ESP-IDF 扩展

  1. 下载并安装 Visual Studio Code

  2. 安装时建议勾选 通过 Code 打开操作添加到 Windows 资源管理器文件上下文菜单,以便快速打开项目文件夹。

  3. 在 VS Code 中,点击侧边活动栏中的 扩展图标 扩展图标(或使用快捷键 Ctrl + Shift + X)打开 扩展 视图。

  4. 在搜索框中输入 ESP-IDF,找到 ESP-IDF 扩展并点击安装。

    在 VS Code 中搜索并安装 ESP-IDF 扩展

  5. ESP-IDF 扩展版本 ≥ 2.0 时,扩展会自动检测并识别上述步骤中安装的 ESP-IDF 环境,无需手动配置。

注意

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

编译和烧录

进入 ESP-IDF 示例工程目录后执行:

cd example/esp-idf
idf.py build flash monitor

如果需要指定串口,请将 COMx 替换为实际串口号,例如 COM5

idf.py -p COMx build flash monitor

示例程序

ESP-IDF 示例位于工程的 example/esp-idf/main/examples 目录,工程入口为 example/esp-idf/main/main.c。同一时间只保留一个示例或应用宏为 1,其他宏保持为 0

#define EXAMPLE_RGB_TEST 1
#define EXAMPLE_MIC_SPEAKER_TEST 0
#define EXAMPLE_IMU_TEST 0
#define EXAMPLE_BAT_TEST 0
#define EXAMPLE_RTC_TEST 0
#define EXAMPLE_LVGL_DEMO_TEST 0
#define EXAMPLE_Brookesia_TEST 0

#define APPS_WIFI_Connect 0
#define APPS_Clock 0
#define APPS_Honeycomb_Demo 0

默认配置运行 RGB 刷色测试。如需运行其他示例,将目标示例对应宏改为 1,并将其他宏改为 0

示例程序基础例程说明
01_RGB_Test屏幕刷色测试
02_Mic_Speaker_Test麦克风与扬声器测试
03_IMU_TestIMU 测试
04_Bat_Test电池检测测试
05_RTC_TestRTC 测试
06_LVGL_Demo_TestLVGL 示例测试
07_Brookesia_TestBrookesia 示例测试
08_WIFI_ConnectWi-Fi 配网应用
09_Clock_Display时钟显示应用
10_Honeycomb_Demo蜂窝图标交互演示

01_RGB_Test

硬件连接

  • 使用 USB 线将开发板接入电脑。

代码分析

RGB 刷色测试代码
void rgb_test_run(void)
{
static const uint16_t colors[] = { RGB565_RED, RGB565_GREEN, RGB565_BLUE };
static const char *color_names[] = { "red", "green", "blue" };
bsp_display_cfg_t display_cfg = {0};
esp_lcd_panel_handle_t panel = NULL;
uint16_t *draw_buffer = NULL;
size_t color_index = 0;

ESP_ERROR_CHECK(bsp_display_new(&display_cfg, &panel, NULL));
ESP_ERROR_CHECK(bsp_display_brightness_init());
ESP_ERROR_CHECK(bsp_display_brightness_set(100));

draw_buffer = heap_caps_malloc(BSP_LCD_H_RES * RGB_TEST_BLOCK_LINES * sizeof(uint16_t), MALLOC_CAP_DMA);

while (true) {
ESP_LOGI(TAG, "show color: %s", color_names[color_index]);
rgb_test_draw_color(panel, draw_buffer, colors[color_index]);
vTaskDelay(pdMS_TO_TICKS(RGB_TEST_DELAY_MS));

color_index++;
if (color_index >= (sizeof(colors) / sizeof(colors[0]))) {
color_index = 0;
}
}
}

代码解释

  • bsp_display_new(&display_cfg, &panel, NULL):初始化 LCD 面板,返回 panel 句柄。
  • bsp_display_brightness_init() / bsp_display_brightness_set(100):初始化并设置背光亮度为 100%。
  • heap_caps_malloc(..., MALLOC_CAP_DMA):分配 DMA 兼容的绘制缓冲区,用于批量像素传输。
  • rgb_test_draw_color(panel, draw_buffer, colors[color_index]):将指定颜色按 20 行分块写入 LCD,逐块刷新整屏。
  • vTaskDelay(pdMS_TO_TICKS(RGB_TEST_DELAY_MS)):每种颜色停留 1 秒。

运行效果

  • 屏幕依次显示红、绿、蓝三种颜色,每种停留 1 秒后切换。
  • 串口每秒输出一次当前颜色名称。

ESP32-C5-Touch-LCD-1.69 IDF 01 RGB


02_Mic_Speaker_Test

硬件连接

  • 使用 USB 线将开发板接入电脑。

代码分析

麦克风回环播放代码
void mic_speaker_test_run(void)
{
uint8_t audio_buffer[MIC_SPEAKER_TEST_FRAME_BYTES];
esp_codec_dev_handle_t speaker = NULL;
esp_codec_dev_handle_t microphone = NULL;
esp_codec_dev_sample_info_t codec_fs = {
.sample_rate = BSP_AUDIO_OUTPUT_SAMPLE_RATE_HZ,
.bits_per_sample = 16,
.channel = 1,
};

ESP_ERROR_CHECK(bsp_audio_init(NULL));

speaker = bsp_audio_codec_speaker_init();
microphone = bsp_audio_codec_microphone_init();

ESP_ERROR_CHECK(esp_codec_dev_open(speaker, &codec_fs));
ESP_ERROR_CHECK(esp_codec_dev_set_out_vol(speaker, MIC_SPEAKER_TEST_VOLUME));
ESP_ERROR_CHECK(esp_codec_dev_set_in_gain(microphone, MIC_SPEAKER_TEST_GAIN));

ESP_LOGI(TAG, "microphone loopback to speaker");

while (true) {
ESP_ERROR_CHECK(esp_codec_dev_read(microphone, audio_buffer, sizeof(audio_buffer)));
ESP_ERROR_CHECK(esp_codec_dev_write(speaker, audio_buffer, sizeof(audio_buffer)));
}
}

代码解释

  • bsp_audio_init(NULL):初始化 I2S 总线和 ES8311 编解码器。
  • bsp_audio_codec_speaker_init() / bsp_audio_codec_microphone_init():分别初始化扬声器和麦克风编解码设备。
  • esp_codec_dev_open(speaker, &codec_fs):以 16bit 单声道格式打开扬声器设备。
  • esp_codec_dev_set_out_vol(speaker, 70):设置扬声器音量为 70。
  • esp_codec_dev_set_in_gain(microphone, 18):设置麦克风增益为 18dB。
  • esp_codec_dev_read(...) / esp_codec_dev_write(...):从麦克风读取 1024 字节数据并写入扬声器,实现实时回环。

运行效果

  • 串口输出 microphone loopback to speaker
  • 对着麦克风说话,可从扬声器实时听到回放声音。

03_IMU_Test

硬件连接

  • 使用 USB 线将开发板接入电脑。

代码分析

QMI8658 数据读取代码
void imu_test_run(void)
{
qmi8658_data_t data = {0};

ESP_ERROR_CHECK(bsp_i2c_init());
ESP_ERROR_CHECK(bsp_qmi8658_init());

while (true) {
ESP_ERROR_CHECK(bsp_qmi8658_get_data(&data));
ESP_LOGI(TAG, "accel: %.2f %.2f %.2f m/s2", data.accelX, data.accelY, data.accelZ);
ESP_LOGI(TAG, "gyro: %.2f %.2f %.2f rad/s", data.gyroX, data.gyroY, data.gyroZ);
ESP_LOGI(TAG, "temp: %.2f C", data.temperature);
vTaskDelay(pdMS_TO_TICKS(IMU_TEST_DELAY_MS));
}
}

代码解释

  • bsp_i2c_init():初始化 I2C 总线(SDA=GPIO8,SCL=GPIO9,400kHz)。
  • bsp_qmi8658_init():初始化 QMI8658 六轴传感器,I2C 地址 0x6B。
  • bsp_qmi8658_get_data(&data):读取加速度、陀螺仪和温度数据到 qmi8658_data_t 结构体。
  • ESP_LOGI(TAG, ...):通过串口输出加速度(m/s²)、陀螺仪(rad/s)和温度(℃)数据。
  • vTaskDelay(pdMS_TO_TICKS(IMU_TEST_DELAY_MS)):按宏设定的间隔读取一次数据。

运行效果

  • 串口每 500ms 输出一行加速度、陀螺仪和温度数据。
  • 轻微倾斜或转动开发板时,数据会随姿态变化。

ESP32-C5-Touch-LCD-1.69 IDF 03 IMU


04_Bat_Test

硬件连接

  • 使用 USB 线将开发板接入电脑。
  • 连接锂电池到开发板。

代码分析

电池信息读取与显示代码
void bat_test_run(uint16_t battery_capacity_mah)
{
bsp_bat_info_t bat_info = {0};
lv_display_t *display = NULL;
lv_obj_t *label = NULL;

display = bsp_display_start();
ESP_ERROR_CHECK(bsp_display_brightness_set(100));
ESP_ERROR_CHECK(bsp_bat_init(battery_capacity_mah));

ESP_ERROR_CHECK(bsp_display_lock(0));
label = lv_label_create(lv_screen_active());
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10);
bsp_display_unlock();

while (true) {
ret = bsp_get_bat_info(&bat_info);
if (ret != ESP_OK) {
ESP_LOGW(TAG, "battery info update failed: %s", esp_err_to_name(ret));
continue;
}

battery_state = (bat_info.ma > 0) ? "Charging" : ((bat_info.ma < 0) ? "Discharging" : "Idle");

ESP_ERROR_CHECK(bsp_display_lock(0));
lv_label_set_text_fmt(label,
"Battery Test\n"
"State: %s\n"
"Voltage: %u mV\n"
"Current: %d mA\n"
"SOC: %u %%\n"
"Temp: %u C\n"
"Capacity: %u mAh\n"
"%s",
battery_state,
bat_info.mv,
bat_info.ma,
bat_info.soc,
bat_info.tc,
battery_capacity_mah,
battery_note);
bsp_display_unlock();

vTaskDelay(pdMS_TO_TICKS(BAT_TEST_DELAY_MS));
}
}

代码解释

  • bsp_display_start():启动 LVGL 显示。
  • bsp_bat_init(battery_capacity_mah):初始化 BQ27220 电量计,设置电池容量(入口参数传入,默认 1000mAh)。
  • bsp_get_bat_info(&bat_info):读取电池信息(电压/电流/SOC/温度/容量等)。
  • bsp_display_lock(0) / bsp_display_unlock():获取/释放 LVGL 互斥锁,确保 UI 操作线程安全。
  • lv_label_set_text_fmt(label, ...):格式化并更新电池信息标签,包含状态、电压、电流、SOC、温度和容量。

运行效果

  • 屏幕显示电池状态信息:状态(Charging/Discharging/Idle)、电压(mV)、电流(mA)、SOC(%)、温度(℃)、容量(mAh)。
  • 串口同步输出电池数据。
  • 接入电池后,电流不为 0 时状态为 Charging 或 Discharging;未接电池或充满时状态为 Idle。

ESP32-C5-Touch-LCD-1.69 IDF 04 Battery


05_RTC_Test

硬件连接

  • 使用 USB 线将开发板接入电脑。

代码分析

RTC 初始化与时间读取代码
void rtc_test_run(void)
{
char datetime_str[32];
pcf85063a_datetime_t time = {
.year = 2026,
.month = 1,
.day = 1,
.dotw = 4,
.hour = 12,
.min = 0,
.sec = 0,
};

ESP_ERROR_CHECK(bsp_rtc_init());
ESP_ERROR_CHECK(bsp_set_rtc_time_date(time));

while (true) {
ESP_ERROR_CHECK(bsp_get_rtc_time_date(&time));
ESP_ERROR_CHECK(bsp_datetime_to_str(datetime_str, sizeof(datetime_str), time));
ESP_LOGI(TAG, "rtc time: %s", datetime_str);
vTaskDelay(pdMS_TO_TICKS(RTC_TEST_DELAY_MS));
}
}

代码解释

  • bsp_rtc_init():初始化 PCF85063A RTC 芯片。
  • bsp_set_rtc_time_date(time):设置 RTC 初始时间(示例中设为 2026-01-01 12:00:00)。
  • bsp_get_rtc_time_date(&time):从 RTC 读取当前时间到 pcf85063a_datetime_t 结构体。
  • bsp_datetime_to_str(datetime_str, ...):将时间结构体转换为字符串,便于输出显示。
  • vTaskDelay(pdMS_TO_TICKS(RTC_TEST_DELAY_MS)):按宏设定的间隔读取一次时间。

运行效果

  • 串口每秒输出一次 rtc time: YYYY-MM-DD HH:MM:SS 格式的时间。

ESP32-C5-Touch-LCD-1.69 IDF 05 RTC


06_LVGL_Demo_Test

硬件连接

  • 使用 USB 线将开发板接入电脑。

代码分析

LVGL Widgets Demo 代码
void lvgl_test_run(void)
{
lv_display_t *display = NULL;

display = bsp_display_start();
ESP_ERROR_CHECK(display ? ESP_OK : ESP_FAIL);
ESP_ERROR_CHECK(bsp_display_brightness_set(100));

ESP_ERROR_CHECK(bsp_display_lock(0));

/* Running Widgets Demo */
lv_demo_widgets();
bsp_display_unlock();

ESP_LOGI(TAG, "LVGL demo started");

while (true) {
vTaskDelay(pdMS_TO_TICKS(LVGL_TEST_DELAY_MS));
}
}

代码解释

  • bsp_display_start():启动 LVGL 显示,初始化 LCD 面板和 LVGL 核心。
  • bsp_display_brightness_set(100):设置背光亮度为 100%。
  • bsp_display_lock(0) / bsp_display_unlock():获取/释放 LVGL 互斥锁,确保 UI 操作线程安全。
  • lv_demo_widgets():启动 LVGL Widgets 演示,展示按钮、滑块、开关、图表等常用控件。

运行效果

  • 屏幕显示 LVGL Widgets 演示界面,包含按钮、滑块、开关、图表等控件。
  • 可通过触摸屏与界面控件进行交互。

ESP32-C5-Touch-LCD-1.69 IDF 06 LVGL Demo


07_Brookesia_Test

硬件连接

  • 使用 USB 线将开发板接入电脑。

代码分析

Brookesia Phone 初始化代码
bool init_phone_system(void)
{
ESP_Brookesia_PhoneStylesheet_t *stylesheet = nullptr;

bsp_display_lock(0);

phone = new (std::nothrow) ESP_Brookesia_Phone(display);
stylesheet = new (std::nothrow) ESP_Brookesia_PhoneStylesheet_t(ESP_BROOKESIA_PHONE_DEFAULT_DARK_STYLESHEET());

stylesheet->core.manager.flags.enable_app_save_snapshot = 0;
stylesheet->core.manager.app.max_running_num = 1;
stylesheet->home.flags.enable_recents_screen = 0;

phone->addStylesheet(stylesheet);
phone->activateStylesheet(stylesheet);
phone->setTouchDevice(bsp_display_get_input_dev());

phone->registerLvLockCallback(phone_lvgl_lock, 0);
phone->registerLvUnlockCallback(phone_lvgl_unlock);

phone->begin();
phone->installApp(&minimal_app);

bsp_display_unlock();
return true;
}

代码解释

  • ESP_Brookesia_Phone(display):创建 Brookesia Phone 实例,绑定 LVGL 显示。
  • ESP_Brookesia_PhoneStylesheet_t(...):使用默认深色主题样式表。
  • phone->addStylesheet(stylesheet) / phone->activateStylesheet(stylesheet):添加并激活样式表。
  • phone->setTouchDevice(bsp_display_get_input_dev()):设置触摸输入设备。
  • phone->registerLvLockCallback(...) / phone->registerLvUnlockCallback(...):注册 LVGL 锁回调,确保线程安全。
  • phone->begin():启动 Phone 界面框架。
  • phone->installApp(&minimal_app):安装最小化示例应用(显示 "Hello Brookesia" 文本)。

运行效果

  • 屏幕显示 Brookesia Phone 界面,包含状态栏和应用启动器。
  • 可点击应用图标进入 "Hello Brookesia Minimal App" 页面。

ESP32-C5-Touch-LCD-1.69 IDF 07 Brookesia


08_WIFI_Connect

硬件连接

  • 使用 USB 线将开发板接入电脑。

代码分析

Wi-Fi AP 与 Captive Portal 代码
void wifi_connect_test_run(void)
{
lv_display_t *display = NULL;

wifi_connect_init_stack();
wifi_connect_start_network();

ESP_ERROR_CHECK(bsp_display_set_partial_mode(true, 40));

display = bsp_display_start();
ESP_ERROR_CHECK(bsp_display_brightness_set(100));
ESP_ERROR_CHECK(bsp_display_lock(0));
wifi_connect_create_screen();
bsp_display_unlock();

while (true) {
vTaskDelay(pdMS_TO_TICKS(WIFI_CONNECT_IDLE_MS));
}
}

代码解释

  • wifi_connect_init_stack():初始化 NVS、网络接口和默认事件循环。
  • wifi_connect_start_network():创建 AP(SSID 基于 MAC 地址),启动 HTTP 服务器和 DNS 服务器,实现 Captive Portal。
  • bsp_display_set_partial_mode(true, 40):设置 LVGL 局部刷新模式,降低显存占用。
  • wifi_connect_create_screen():创建包含二维码和状态栏的配网页面,二维码包含 AP 的 SSID 和密码。
  • 用户手机连接 AP 后,自动弹出配网页面,输入家庭 Wi-Fi 信息后设备自动连接。

运行效果

  • 屏幕显示二维码和 AP 信息,手机扫码连接 AP 后自动弹出配网页面。
  • 在配网页面输入家庭 Wi-Fi SSID 和密码,设备自动连接 Wi-Fi 并在屏幕显示连接状态和 IP 地址。

ESP32-C5-Touch-LCD-1.69 IDF 08 WiFi Connect


09_Clock_Display

硬件连接

  • 使用 USB 线将开发板接入电脑。

代码分析

时钟应用初始化代码
void clock_test_run(void)
{
lv_display_t *display = NULL;

ESP_ERROR_CHECK(bsp_i2c_init());
ESP_ERROR_CHECK(bsp_rtc_init());
ESP_ERROR_CHECK(bsp_display_set_partial_mode(true, 40));

display = bsp_display_start();
ESP_ERROR_CHECK(bsp_display_brightness_set(100));
ESP_ERROR_CHECK(bsp_display_lock(0));
clock_app_create_screen();
bsp_display_unlock();

while (true) {
vTaskDelay(pdMS_TO_TICKS(CLOCK_APP_IDLE_MS));
}
}

代码解释

  • bsp_i2c_init() / bsp_rtc_init():初始化 I2C 总线和 PCF85063A RTC,为时钟提供时间源。
  • bsp_display_set_partial_mode(true, 40):设置 LVGL 局部刷新模式,降低显存占用。
  • bsp_display_start():启动 LVGL 显示。
  • bsp_display_brightness_set(100):设置背光亮度为 100%。
  • bsp_display_lock(0) / bsp_display_unlock():获取/释放 LVGL 互斥锁,确保 UI 操作线程安全。
  • clock_app_create_screen():创建时钟界面,加载 Classic 表盘并启动定时器刷新指针位置。
  • vTaskDelay(pdMS_TO_TICKS(CLOCK_APP_IDLE_MS)):按宏设定的间隔进入空闲等待。

运行效果

  • 屏幕显示模拟时钟表盘,时针、分针、秒针随 RTC 时间实时移动。

ESP32-C5-Touch-LCD-1.69 IDF 09 Clock


10_Honeycomb_Demo

硬件连接

  • 使用 USB 线将开发板接入电脑。

代码分析

蜂窝图标布局代码
void honeycomb_demo_run(void)
{
lv_display_t *display = NULL;

display = bsp_display_start();
ESP_ERROR_CHECK(bsp_display_brightness_set(100));
ESP_ERROR_CHECK(bsp_display_lock(0));
honeycomb_demo_create_screen();
bsp_display_unlock();

while (true) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

static void honeycomb_demo_drag_event_cb(lv_event_t *event)
{
lv_indev_t *indev = lv_indev_active();
lv_point_t vector = {0};

lv_indev_get_vect(indev, &vector);
honeycomb_offset.x += vector.x;
honeycomb_offset.y += vector.y;
honeycomb_demo_refresh_layout();
}

代码解释

  • bsp_display_start():启动 LVGL 显示。
  • honeycomb_demo_create_screen():创建蜂窝布局界面,生成 25 个圆形图标,按 5 列蜂窝阵排列。
  • honeycomb_demo_drag_event_cb(...):触摸拖拽回调,根据手指滑动偏移量更新图标位置。
  • honeycomb_demo_refresh_layout():刷新图标布局,根据图标到屏幕中心的距离计算缩放比例,越靠近中心图标越大。
  • honeycomb_demo_calculate_scale(distance):基于距离的二次方衰减计算图标缩放值,实现鱼眼放大效果。

运行效果

  • 屏幕显示蜂窝状排列的彩色圆形图标,中心图标放大,边缘图标缩小。
  • 手指拖拽可平移图标阵列,图标随位置动态缩放,呈现鱼眼交互效果。

ESP32-C5-Touch-LCD-1.69 IDF 10 Honeycomb