第3节 创建项目
本教程的核心逻辑适用于所有 ESP32 开发板,但所有操作步骤均以 微雪 ESP32-S3-Zero 迷你开发板 为例进行讲解。如果您使用其他型号的开发板,请根据实际情况修改相应设置。
本节讲解如何使用 VS Code 创建 ESP-IDF 项目,并通过实践点亮 ESP32 开发板上的一颗 LED。
1. 搭建电路
需要使用的器件有:
- LED * 1
- 330Ω 电阻 * 1
- 面包板 * 1
- 导线
- ESP32 开发板 (微雪 ESP32-S3-Zero 迷你开发板)
按照下面接线图连接电路:
ESP32-S3-Zero 引脚图

2. 从模板创建项目
-
打开 VS Code,点击 ESP-IDF 扩展,在 "Advanced" 中打开 "新项目向导"。
-
选择 ESP-IDF 的版本。
-
设置项目名称,存放位置以及相关参数。开发板相关参数可以在创建项目后修改。设置完成后点击 "Choose Template"。
注意项目路径中不要包含空格、中文或特殊符号。
-
选择 "template-app" 模板,然后点击 "Create project using template template-app"。
-
项目创建完成后,会弹出通知窗口询问是否打开新创建的项目。点击打开新项目。
3. 编写代码
ESP-IDF 会为项目生成许多文件和文件夹。在本入门指南中,建议保持所有默认文件不变,我们只需修改 main.c
文件。
-
写入下面代码:
#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const gpio_num_t led_pin = GPIO_NUM_7;
void app_main(void)
{
gpio_reset_pin(led_pin); // 重置引脚
gpio_set_direction(led_pin, GPIO_MODE_OUTPUT); // 设置引脚为输出模式
while (1)
{
gpio_set_level(led_pin, 1); // 设置引脚为高电平,点亮 LED
printf("LED state: ON\n"); // 打印 LED 的当前状态
vTaskDelay(pdMS_TO_TICKS(1000)); // 任务延时 1000 毫秒 (1秒)
gpio_set_level(led_pin, 0); // 设置引脚为低电平,熄灭 LED
printf("LED state: OFF\n"); // 打印 LED 的当前状态
vTaskDelay(pdMS_TO_TICKS(1000)); // 再次任务延时 1000 毫秒 (1秒)
}
} -
代码导航与语法高亮
对于代码导航和 C/C++ 语法高亮,推荐使用 Microsoft C/C++ 扩展。
安装该插件后,VS Code 通常能自动进行代码高亮并识别宏定义、库变量等。如果在编写代码过程中相关库出现红色波浪线提示未定义等问题,一般构建一次项目即可解决,也可以通过下面的方法修复:
-
通常,C/C++ 语言扩展依赖于一个名为
compile_commands.json
的文件,该文件位于项目构建目录中。可以使用ESP-IDF: 运行 idf.py reconfigure 任务
来生成此文件。 -
使用快捷键 Ctrl + Shift + P 打开 VS Code 命令面板。然后运行
ESP-IDF: 运行 idf.py reconfigure 任务
。
-
4. 构建并烧录代码
-
配置烧录选项
首先,在构建和烧录之前,请务必检查并设置正确的目标设备、串口和烧录方式。参考 第 2 节 运行示例 1.3 。
-
点击
一键自动依次执行构建、烧录和监视这三个步骤。
-
烧录完成后,您会看到 LED 开始闪烁。同时,串口监视器会启动并输出如下日志信息:
5. 代码解析
-
首先包含所需的库:
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"stdio.h
: C 语言标准输入输出库,我们用它来调用printf
函数向串口打印信息。driver/gpio.h
: ESP-IDF 提供的 GPIO 驱动库,包含了配置和操作 GPIO 引脚所需的函数,例如设置引脚方向、读写引脚电平等。freertos/FreeRTOS.h
和freertos/task.h
: ESP-IDF 使用 FreeRTOS 作为其实时操作系统。这两个头文件提供了操作系统核心和任务管理相关的 API。在这里,我们主要使用vTaskDelay
函数来实现精确的延时。
-
GPIO 引脚定义
static const gpio_num_t led_pin = GPIO_NUM_7;
- 这行代码定义了一个常量
led_pin
来表示 LED 所连接的 GPIO 引脚号。 gpio_num_t
是 ESP-IDF 中用于表示 GPIO 编号的枚举类型。GPIO_NUM_7
是该枚举中的一个取值,表示编号为 7 的通用 IO 引脚(GPIO7)。从可读性与类型安全角度,建议使用GPIO_NUM_7
而不是直接写字面值7
。
备注不同芯片对 GPIO7 的可用性与限制不同,请检查所用你的开发板的引脚定义。
- 这行代码定义了一个常量
-
GPIO 初始化
gpio_reset_pin(led_pin); // 重置引脚
gpio_set_direction(led_pin, GPIO_MODE_OUTPUT); // 设置引脚为输出模式在
app_main
函数内部,首先对 GPIO 引脚进行初始化设置。gpio_reset_pin(led_pin);
: 在配置引脚前先将其重置为默认状态,可以避免一些意外问题。gpio_set_direction(led_pin, GPIO_MODE_OUTPUT);
: 这行代码将选定的led_pin
(GPIO 7) 设置为输出模式。
-
无限循环
while(1)
在 FreeRTOS 任务函数中,通常会使用
while(1)
实现任务的持续运行。这样任务会一直被 FreeRTOS 调度器管理,除非主动调用vTaskDelete()
删除任务,否则不会退出。无限循环配合vTaskDelay()
等函数,可以让任务周期性地执行操作,同时让出 CPU 给其他任务,实现多任务并发。while (1)
{
gpio_set_level(led_pin, 1); // 设置引脚为高电平,点亮 LED
printf("LED state: ON\n"); // 打印 LED 的当前状态
vTaskDelay(pdMS_TO_TICKS(1000)); // 任务延时 1000 毫秒 (1秒)
gpio_set_level(led_pin, 0); // 设置引脚为低电平,熄灭 LED
printf("LED state: OFF\n"); // 打印 LED 的当前状态
vTaskDelay(pdMS_TO_TICKS(1000)); // 再次任务延时 1000 毫秒 (1秒)
}-
gpio_set_level(led_pin, 1);
: 设置led_pin
引脚的输出高电平。 -
printf()
:ESP-IDF 支持标准 C 语言的printf()
,可将信息输出到串口终端,便于调试和状态监控。 -
vTaskDelay(pdMS_TO_TICKS(1000));
:该函数让当前 FreeRTOS 任务延时指定的 tick 数,延时期间任务进入阻塞态,释放 CPU 使用权。
pdMS_TO_TICKS(1000)
宏将 1000 毫秒转换为 tick 数,确保延时为 1000 毫秒。此过程是非阻塞的,详情参考 此链接。
-