ESP-IDF 开发
本章节包含以下内容,请按需阅读:
ESP-IDF 入门教程
初次接触 ESP32 ESP-IDF 开发,想要快速上手?我们为您准备了一套通用的 入门教程。
- 第0节 认识 ESP32
- 第1节 搭建环境
- 第2节 运行实例
- 第3节 创建项目
- 第4节 使用组件
- 第5节 调试程序
- 第6节 FreeRTOS
- 第7节 驱动外设
- 第8节 Wi-Fi 编程
- 第9节 BLE 编程
请注意:该教程使用 ESP32-S3-Zero 作为教学示例,所有硬件代码均基于其引脚布局。在动手实践前,建议您对照手中的开发板引脚图,确认引脚配置无误。
配置开发环境
以下内容以 Windows 系统为例,使用 VS Code + ESP-IDF 扩展 的方式进行开发。Mac/Linux 用户请参考 官方说明。
此部分图示以安装 ESP-IDF V5.2.2 为例示范,安装时请选用与您开发板示例匹配的 ESP-IDF 版本。
安装 ESP-IDF 开发环境
-
前往 ESP-IDF Installation Manager 下载 ESP-IDF 安装管理器。这是乐鑫最新推出的跨平台安装工具,下文将演示如何使用其离线安装功能。
在页面中点击 Offline Installer 标签,然后在筛选栏中选择 Windows 操作系统和你需要的 ESP-IDF 版本(图示仅为参考,请以实际为准)。

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

请耐心等待两个文件下载完成。
-
下载完成后,双击运行 ESP-IDF 安装器(eim-gui-windows-x64.exe)。
启动后,可在右上角将界面语言切换为中文。

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

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

-
当看到如下界面时,表示 ESP-IDF 已安装成功。

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

安装 Visual Studio Code 与 ESP-IDF 扩展
-
下载并安装 Visual Studio Code。
-
安装时建议勾选 通过 Code 打开操作添加到 Windows 资源管理器文件上下文菜单,以便快速打开项目文件夹。
-
在 VS Code 中,点击侧边活动栏中的
扩展图标(或使用快捷键 Ctrl + Shift + X)打开 扩展 视图。
-
在搜索框中输入 ESP-IDF,找到 ESP-IDF 扩展并点击安装。

-
当 ESP-IDF 扩展版本 ≥ 2.0 时,扩展会自动检测并识别上述步骤中安装的 ESP-IDF 环境,无需手动配置。
示例程序
ESP-IDF 示例程序位于 示例程序包 的 ESP-IDF 目录中。
| 示例程序 | 基础例程说明 |
|---|---|
| 01_GPIO | 控制引出 GPIO 引脚的电平状态 |
| 02_BlinkRGB | 实现控制 RGB 呈呼吸灯效果 |
| 03_GetchipID | 获取并打印 ESP32-C5-Zero 芯片的硬件信息,包括芯片型号、版本、核心数量以及芯片 ID |
| 04_BLE | 实现通过ESP32-C5-Zero 开发板连接蓝牙 BLE 信标并接收广播数据的功能 |
| 05_UART | 实现通过ESP32-C5-Zero 开发板连接 UART 功能 |
| 06_WIFI_AP | 实现通过ESP32-C5-Zero 开发板设置为 AP 热点 (2.4G),允许其他 WiFi 设备接入联网 |
| 07_WIFI_STA | 实现连接指定 WiFi 并打印连接信息 |
| 08_WIFI_StaticIP | 通过 ESP32-C5-Zero 开发板使用 WIFI 连接,静态分配 IP 地址 |
| 09_ZIGBEE | 通过 ESP32-C5-Zero 开发板使用 Zigbee ,控制开发板的LED亮灭 |
| 10_Mem_Security | 通过 ESP32-C5-Zero 开发板使用内存安全功能 |
01_GPIO
代码
01_GPIO.ino
void app_main(void)
{
// Configure all selected GPIOs as push-pull outputs
gpio_config_t io_conf = {
.intr_type = GPIO_INTR_DISABLE,
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = GPIO_OUTPUT_PIN_SEL,
.pull_down_en = 0,
.pull_up_en = 0,
};
ESP_ERROR_CHECK(gpio_config(&io_conf));
int output_level = 0;
size_t gpio_count = sizeof(gpio_pins) / sizeof(gpio_pins[0]);
ESP_LOGI(log_tag, "Initialization done. Start toggling GPIO pins synchronously...");
while (true) {
// Set all selected pins to the same level
for (size_t i = 0; i < gpio_count; i++) {
ESP_ERROR_CHECK(gpio_set_level(gpio_pins[i], output_level));
}
// Flip output level for next cycle
output_level = !output_level;
vTaskDelay(pdMS_TO_TICKS(500));
}
}
代码解释
- 代码先遍历选中的 GPIO 引脚并统一设置输出电平,再通过
output_level = !output_level实现同步翻转。 vTaskDelay(pdMS_TO_TICKS(500))用于控制闪烁周期,方便观察 GPIO 输出变化。
02_BlinkRGB
代码
02_BlinkRGB.ino
while (true) {
// Calculate current color
led_strip_set_wheel(led_strip, wheel_pos);
// Refresh LED
led_strip_refresh(led_strip);
// Increment position (uint8_t automatically wraps to 0 after 255)
wheel_pos++;
vTaskDelay(pdMS_TO_TICKS(20));
}
代码解释
led_strip_set_wheel()根据wheel_pos计算当前颜色,适合做循环彩虹灯效。- 每次
led_strip_refresh()后延时 20ms,可让颜色变化看起来更平滑。
运行效果
03_GetchipID
代码
03_GetchipID.ino
void app_main(void)
{
ESP_LOGI(log_tag, "--- Chip information example ---");
/* Get chip information */
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
/* Print target and core count */
ESP_LOGI(log_tag, "Target: %s", CONFIG_IDF_TARGET);
ESP_LOGI(log_tag, "Cores: %d", chip_info.cores);
/* Get and print flash size */
uint32_t flash_size;
esp_flash_get_size(NULL, &flash_size);
ESP_LOGI(log_tag, "Flash size: %" PRIu32 " MB (%s)",
flash_size / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
/* Print revision */
ESP_LOGI(log_tag, "Revision: %d", chip_info.revision);
/* Use default MAC address as a unique ID */
uint8_t mac[6];
esp_efuse_mac_get_default(mac);
ESP_LOGI(log_tag, "Unique ID (MAC): %02X:%02X:%02X:%02X:%02X:%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
ESP_LOGI(log_tag, "------------------------");
/* Run forever */
while (true) {
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
代码解释
esp_chip_info()用于读取芯片核心数、版本等基础硬件信息。esp_efuse_mac_get_default()读取默认 MAC 地址,可作为设备的唯一标识输出。
运行效果
![]() |
|---|
04_BLE
代码
04_BLE.ino
void app_main(void) {
// 1. Initialize NVS (required for Bluetooth stack)
if (nvs_flash_init() != ESP_OK) {
nvs_flash_erase();
nvs_flash_init();
}
// 2. Initialize Bluetooth Controller
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
esp_bt_controller_init(&bt_cfg);
esp_bt_controller_enable(ESP_BT_MODE_BLE);
// 3. Initialize Bluedroid Stack
esp_bluedroid_init();
esp_bluedroid_enable();
// 4. Register GAP callback and configure advertising data
esp_ble_gap_register_callback(gap_event_handler);
esp_ble_gap_config_adv_data_raw(adv_data, sizeof(adv_data));
ESP_LOGI(TAG, "BLE stack initialized, setting up advertising...");
}
代码解释
- 代码先初始化 NVS、蓝牙控制器和 Bluedroid 协议栈,这是 BLE 广播运行的基础。
esp_ble_gap_config_adv_data_raw()用于配置原始广播数据,随后设备即可被外部扫描到。
运行效果
![]() |
|---|
05_UART
代码
05_UART.ino
void app_main(void) {
uart_config_t uart_cfg = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
ESP_ERROR_CHECK(uart_param_config(UART_PORT, &uart_cfg));
ESP_ERROR_CHECK(uart_driver_install(UART_PORT, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0));
ESP_ERROR_CHECK(uart_set_pin(UART_PORT, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
xTaskCreate(rx_task, "uart_rx", 4096, NULL, 10, NULL);
xTaskCreate(tx_task, "uart_tx", 4096, NULL, 9, NULL);
}
代码解释
uart_param_config()、uart_driver_install()和uart_set_pin()分别完成串口参数、驱动和引脚映射配置。- 最后通过
xTaskCreate()启动收发任务,让串口接收和发送可以并行运行。
运行效果
![]() |
|---|
06_WIFI_AP
代码
06_WIFI_AP.ino
void app_main(void) {
// 1. Initialize NVS (required for AP mode as well).
if (nvs_flash_init() != ESP_OK) {
nvs_flash_erase();
nvs_flash_init();
}
// 2. Initialize network stack and create the default AP netif.
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_ap();
// 3. Initialize WiFi driver and register event handler.
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_handler, NULL, NULL);
// 4. Configure AP parameters with designated initializer.
wifi_config_t ap_cfg = {
.ap = {
.ssid = SSID,
.password = PWD,
.ssid_len = 0, // Use null-terminated SSID string length.
.channel = 1,
.max_connection = 4,
.authmode = WIFI_AUTH_WPA2_PSK
},
};
// Switch to open mode when password is empty.
if (PWD[0] == '\0') ap_cfg.ap.authmode = WIFI_AUTH_OPEN;
esp_wifi_set_mode(WIFI_MODE_AP);
esp_wifi_set_config(WIFI_IF_AP, &ap_cfg);
esp_wifi_start();
ESP_LOGI(TAG, "AP Mode started. SSID: %s", SSID);
}
代码解释
- 这段代码把开发板配置成 AP 模式,核心是
esp_wifi_set_mode(WIFI_MODE_AP)和esp_wifi_set_config()。 - 如果密码为空,会自动切换成开放热点模式,便于快速测试连接。
运行效果
![]() |
|---|
07_WIFI_STA
代码
07_WIFI_STA.ino
void app_main(void) {
// 1. Initialize NVS (WiFi configuration needs to be stored in NVS)
if (nvs_flash_init() != ESP_OK) {
nvs_flash_erase();
nvs_flash_init();
}
// 2. Initialize network stack and underlying drivers
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
// 3. Register event handlers (handle all WiFi and IP related events)
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID,
&wifi_handler, NULL, NULL);
esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP,
&wifi_handler, NULL, NULL);
// 4. Initialize GPIO26 as output
gpio_reset_pin(GPIO_NUM_26);
gpio_set_direction(GPIO_NUM_26, GPIO_MODE_OUTPUT);
GPIO26_ON();
// 4. Configure and start WiFi
wifi_config_t wifi_cfg = {
.sta =
{
.ssid = SSID,
.password = PWD,
},
};
esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg);
esp_wifi_start();
ESP_LOGI(TAG, "WiFi station started.");
}
代码解释
esp_netif_create_default_wifi_sta()用于创建 STA 网络接口,供开发板连接路由器使用。- 注册 Wi-Fi 与 IP 事件回调后,程序就能在联网成功或掉线时执行对应处理逻辑。
运行效果
08_WIFI_StaticIP
代码
08_WIFI_StaticIP.ino
esp_netif_ip_info_t ip_info = {
.ip.addr = ipaddr_addr("192.168.1.77"),
.gw.addr = ipaddr_addr("192.168.1.1"),
.netmask.addr = ipaddr_addr("255.255.255.0")
};
代码解释
esp_netif_ip_info_t结构体用于一次性配置静态 IP、网关和子网掩码。- 这类写法适合设备地址需要固定的场景,便于局域网内通过已知地址访问开发板。
运行效果
09_ZIGBEE
- 1:准备两块ESP32-C5-Zero 开发板,确保它们供电正常且处于可烧录程序的状态。
- 2:将第一块开发板与电脑连接,使用烧录工具往该开发板烧录 HA_on_off_light 程序(此程序用于控制 RGB 灯),烧录完成后保持开发板上电状态。
- 3:将第二块开发板与电脑连接,使用烧录工具往该开发板烧录 HA_on_off_switch 程序(此程序用于通过 BOOT 按键实现控制功能),烧录完成后保持开发板上电状态。
代码
09_ZIGBEE.ino
void app_main(void)
{
esp_zb_platform_config_t config = {
.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
};
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
}
代码解释
esp_zb_platform_config()完成 Zigbee 平台层初始化,准备好射频与主机配置。xTaskCreate(esp_zb_task, ...)将 Zigbee 主任务独立运行,便于后续扩展网络控制逻辑。
运行效果
10_Mem_Security
代码
10_Mem_Security.ino
print_status();
print_privilege();
test_hw_crypto();
test_tee_apm();
代码解释
- 这几行分别用于查看当前安全状态、权限信息,并测试硬件加密与 TEE/APM 相关功能。
- 适合用来快速验证芯片安全特性是否初始化正常。



