1.3. ESP-IDF 编程基础
1.3.1. 日志系统
#include "esp_log.h"
static const char *TAG = "APP";
ESP_LOGE(TAG, "错误信息"); // Error (红色)
ESP_LOGW(TAG, "警告信息"); // Warning
ESP_LOGI(TAG, "普通信息"); // Info
ESP_LOGD(TAG, "调试信息"); // Debug (需开启)
ESP_LOGV(TAG, "冗余信息"); // Verbose
// 设置日志级别
// menuconfig → Component config → Log output → Default log verbosity
// 运行时动态调整
esp_log_level_set(TAG, ESP_LOG_VERBOSE);
1.3.2. GPIO 操作
#include "driver/gpio.h"
#define GPIO_LED GPIO_NUM_2
#define GPIO_BUTTON GPIO_NUM_0
void gpio_init(void)
{
// 配置输出
gpio_reset_pin(GPIO_LED);
gpio_set_direction(GPIO_LED, GPIO_MODE_OUTPUT);
// 配置输入(上拉)
gpio_reset_pin(GPIO_BUTTON);
gpio_set_direction(GPIO_BUTTON, GPIO_MODE_INPUT);
gpio_set_pull_mode(GPIO_BUTTON, GPIO_PULLUP_ONLY);
}
// GPIO 控制
gpio_set_level(GPIO_LED, 1); // 高电平
gpio_set_level(GPIO_LED, 0); // 低电平
int level = gpio_get_level(GPIO_BUTTON); // 读取
// 翻转
gpio_set_level(GPIO_LED, !gpio_get_level(GPIO_LED));
1.3.3. NVS 非易失存储
#include "nvs_flash.h"
#include "nvs.h"
void nvs_example(void)
{
// 初始化 NVS
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES ||
err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
nvs_handle_t handle;
ESP_ERROR_CHECK(nvs_open("storage", NVS_READWRITE, &handle));
// 写入
int32_t counter = 0;
nvs_set_i32(handle, "counter", counter);
nvs_commit(handle);
// 读取
nvs_get_i32(handle, "counter", &counter);
nvs_close(handle);
}
1.3.4. 中断处理
#include "driver/gpio.h"
static QueueHandle_t gpio_evt_queue = NULL;
// 中断处理函数 (在 ISR 上下文中执行)
static void IRAM_ATTR gpio_isr_handler(void *arg)
{
uint32_t gpio_num = (uint32_t)arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
void gpio_isr_init(void)
{
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
// 安装 GPIO ISR 服务
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
// 配置中断触发
gpio_set_intr_type(GPIO_BUTTON, GPIO_INTR_NEGEDGE);
gpio_isr_handler_add(GPIO_BUTTON, gpio_isr_handler,
(void *)GPIO_BUTTON);
}
// 在任务中处理中断事件
void gpio_task(void *arg)
{
uint32_t io_num;
while (1) {
if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
ESP_LOGI(TAG, "GPIO[%d] 中断触发", io_num);
// 处理按键逻辑
}
}
}
1.3.5. 定时器
#include "esp_timer.h"
void periodic_timer_callback(void *arg)
{
ESP_LOGI(TAG, "定时器触发");
}
void timer_init(void)
{
const esp_timer_create_args_t timer_args = {
.callback = &periodic_timer_callback,
.name = "periodic"
};
esp_timer_handle_t timer;
ESP_ERROR_CHECK(esp_timer_create(&timer_args, &timer));
// 每 1000 ms 触发一次
ESP_ERROR_CHECK(esp_timer_start_periodic(timer, 1000000));
}
1.3.6. 看门狗
#include "esp_task_wdt.h"
void task_wdt_example(void)
{
// 在主循环中喂狗
while (1) {
esp_task_wdt_reset();
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
警告
ESP-IDF 默认启用了中断看门狗(Interrupt WDT)和任务看门狗(Task WDT)。 如果任务阻塞超过 5 秒未让出 CPU,Task WDT 会触发复位。 可在 menuconfig 中调整超时或禁用。
1.3.7. 错误处理
esp_err_t err;
// 检查并处理错误
err = gpio_set_level(GPIO_LED, 1);
if (err != ESP_OK) {
ESP_LOGE(TAG, "GPIO 操作失败: %s", esp_err_to_name(err));
return err;
}
// 断言(调试用,Release 版可禁用)
ESP_ERROR_CHECK(err); // 出错时打印并 abort
assert(ptr != NULL); // 标准断言