跳到主要内容

ESP-IDF 开发

本章节包含以下两部分,请按需阅读:

配置开发环境

备注

以下环境设置适用于 Windows 10/11 系统,Mac/Linux 用户请参考 官方说明

  1. 下载并安装 Visual Studio Code

  2. 在 VSCode 中,通过点击 VSCode 侧边活动栏中的 扩展图标 或使用快捷键(Ctrl+Shift+X)来打开 扩展 视图。然后,搜索 ESP-IDF 扩展并安装。

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

  3. 安装扩展后,VS Code 左侧活动栏中会出现 Espressif 图标 图标,点击该图标可查看 ESP-IDF 扩展的基本命令列表,在 Advanced 中选择 配置 ESP-IDF 扩展

    选择“配置 ESP-IDF 拓展”

  4. 选择 Express 进入快速配置模式:

    选择快速配置模式

  5. 根据需要修改以下选项。

    • 选择下载服务器
      • Espressif:使用乐鑫中国服务器,下载速度更快。
      • Github:使用 GitHub 官方发布链接。
    • ESP-IDF 版本:通常根据开发板要求选择对应版本,如无特殊要求建议使用最新的正式版本。对于 ESP32-P4-Module-DEV-KIT ,建议 Espressif IDF 版本 ≥ v5.3.1。
    • ESP-IDF 容器安装地址:建议使用默认地址,或使用纯英文路径且路径中不包含空格。
    • ESP-IDF 所需的工具安装地址:建议使用默认地址,或使用纯英文路径且路径中不包含空格。

    ESP-IDF 拓展快速配置模式选项

  6. 点击 Install 开始安装。你将看到一个显示安装进度的页面,包括 ESP-IDF 下载、ESP-IDF 工具下载安装以及 Python 虚拟环境创建的进度状态。

    安装进度

  7. 如果安装正确,你会看到所有设置已配置完成的提示,即可开始使用该扩展程序。

    安装成功

注意

注意:如果 ESP-IDF 安装失败或需要重新安装,可以尝试删除 C:\Users\%Username%\espC:\Users\%Username%\.espressif 文件夹后重试。

示例程序

ESP-IDF 示例程序位于 示例程序包ESP-IDF 目录中。

入门

学习一门语言或开发环境的最好方式是从入门开始,在本章节详细介绍如何创建项目、从现有项目开发、以及嵌入式经典教程 HelloWorld 和常用接口 I2C 的使用。

1. ESP-IDF 项目的基本结构介绍

  • 项目结构:

    • 打开 ESP-IDF 插件,点击 New project,选择 ESP-IDF 示例 ——> sample_project ——> 点击创建

    • 新建并在窗口中打开可以查看到 VSCode 的结构如下:

      ├── CMakeLists.txt
      ├── main
      │ ├── CMakeLists.txt
      │ └── main.c
      └── README.md
  • ESP-IDF 工程项目详解:

    • 组件(Component):ESP-IDF 中的组件是构建应用的基本模块,每个组件通常是相对独立的代码库或库,能实现特定的功能或服务,可以被应用程序或是其他组件重复使用,类似于 Python 开发中的库的定义。

      • 组件的引用:Python 开发环境中引入库只需要“import 库名或路径”即可,而 ESP-IDF 基于 C 语音基础,引入库是通过 CMakeLists.txt 进行配置和定义的。

      • 当我们使用在线组件时,通常使用idf.py add-dependency <componetsName>来为项目添加在线组件,这会生成一个idf_component.yml文件用于管理组件。

      • CmakeLists.txt 的作用:ESP-IDF 编译时编译工具 CMake 会首先通过读取工程目录的顶层 CMakeLists.txt 的内容来读取构建规则,识别需要编译的内容。当在 CMakeLists.txt 中引入了需要的组件、程序后,编译工具 CMake 会根据索引导入每个所需要编译的内容。编译过程如:

        ESP-IDF 编译过程

  • VSCode 用户界面底部工具栏说明:

    打开 ESP-IDF 工程时,底部会自动加载环境。对于 ESP32-P4-Module-DEV-KIT 开发,底部工具栏非常重要,如图所示:

    VSCode 用户界面底部工具栏说明

    • ①ESP-IDF 开发环境版本管理器:当我们的工程需要区分开发环境版本时,可以通过安装不同版本的 ESP-IDF 来分别管理,当工程使用特定版本时,可以通过使用它来切换
    • ② 设备烧录 COM 口,选择以将编译好的程序烧录进芯片上
    • ③set-target 芯片型号选择:选择对应的芯片型号,如:ESP32-P4-Module-DEV-KIT 需要选择 esp32p4 为目标芯片
    • ④menuconfig:点击修改 sdkconfig 配置文件内容
    • ⑤fullclean 清理按钮:当工程编译报错或其他操作污染编译内容时,通过点击清理全部编译内容
    • ⑥Build 构建工程:当一个工程满足构建时,通过此按钮进行编译
    • ⑦flash 烧录按钮:当一个工程 Build 构建通过时,选择对应开发板 COM 口,点击此按钮可以将编译好的固件烧录至芯片
    • ⑧monitor 开启烧录口监控:当一个工程 Build—>Flash 后,可通过点击此按钮查看烧录、调试口输出的 log,以便观察应用程序是否正常工作
    • ⑨Build Flash Monitor 一键按钮:用于连续执行 Build—>Flash—>Monitor,常被称作小火苗

2. HelloWorld 示例

了解完 VSCode 用户界面底部工具栏说明后,通过 Hello World 工程可以快速入门和了解 ESP32 开发环境的基础项目。它演示了如何使用 ESP-IDF 来创建一个基本的应用程序,并且涵盖了 ESP32 的开发流程,包括编译、烧录和监视器调试的步骤。

  1. 打开示例工程 HelloWorld 后,设置好目标端口、芯片类型(此处注意,选择好芯片类型时右下角有加载动作,这是 ESP-IDF 正在执行 idf.py set-target esp32p4 的操作指令,它需要从包管理器拉取对应芯片的架构包环境,需要一定时间处理,请一定要耐心等待,如果此时点击构建等操作会有报错!!!)

  2. 通过底部工具 🔥 一键构建、烧录、监视,可以查看到终端输出 Hello World!

  3. 代码内容解析

    1. 代码中仅有一个 app_main 主函数,通过条件判断来确定打印内容输出,并在末尾添加了循环,实现 10s 重启芯片。
    2. app_main 函数是 ESP-IDF(Espressif IoT Development Framework)开发框架中用户应用程序的入口点。它是 ESP-IDF 项目的核心函数,相当于 C 语言标准程序中的 main 函数。在 ESP32 开发中,app_main 函数是由实时操作系统(FreeRTOS)调度的第一个任务,这也是用户代码执行的起始点。

3. I2C 示例

I2C 是一个较常用的串行通信总线,它可以通过两条线进行通信,一根数据线(SDA, Serial Data)和一根时钟线(SCL, Serial Clock),并支持多主多从模式。在 ESP32-P4 上一共有 2 个 I2C 总线接口,芯片内部通过 GPIO 交换矩阵可配置使用任意 GPIO 管脚,这个特性可以让我们自由的使用任意 GPIO 作为 I2C 的引脚控制,当然 ESP32-P4 I2C 支持 Slave、Master 模式,以下主要使用 I2C 主机(Master)模式,用于 ESP32-P4 启动通信、控制并向从设备(可以是任何 I2C 接口的传感器)发送数据请求或接收数据。 ESP32-P4-Module-DEV-KIT 的 I2C 引脚默认使用 SCL(GPIO8)SDA(GPIO7)

I2C 工作接线

ESP-IDF 中,I2C 总线需要 i2c_master_bus_config_t 指定配置:

  • i2c_master_bus_config_t::clk_source 选择 I2C 总线的源时钟,使用默认 I2C 时钟源(通常都使用默认时钟源)则为 I2C_CLK_SRC_DEFAULT 即可
  • i2c_master_bus_config_t::i2c_port 设置控制器使用的 I2C 端口,正如上述说明,ESP32-P4 的 I2C 是有两个的,当有两个不同的 I2C 需要同时启用,则需要使用其来区分
  • i2c_master_bus_config_t::scl_io_num 设置串行时钟总线 (SCL) 的 GPIO 编号,在 ESP32-P4-Module-DEV-KIT 上,为 8
  • i2c_master_bus_config_t::sda_io_num 设置串行数据总线 (SDA) 的 GPIO 编号,在 ESP32-P4-Module-DEV-KIT 上,为 7
  • i2c_master_bus_config_t::glitch_ignore_cnt 设置 Master Bus 的 Glitch Period,如果线路上的 Glitch Period 小于此值,可以过滤掉,通常值为 7
  • i2c_master_bus_config_t::enable_internal_pullup 启用内部 pullups,在 ESP32-P4-Module-DEV-KIT 上,已经有额外的 I2C 上拉,无需启用内部上拉

经上所述,I2C 配置为:

   i2c_master_bus_config_t i2c_bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = I2C_NUM_0,
.scl_io_num = 8,
.sda_io_num = 7,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = false,
};
  1. 打开 i2c_tools 工程,选择好 COM 口和芯片型号,点击 ⚙️ 进入设置,这里会打开一个新的标签:SDK Configuration editor 也就是 menuconfig,我们直接在搜索栏中搜索 I2C,看到此时内容已经检索,并且示例例程中的 SCL GPIO Num、SDA GPIO Num 已经对应上了 SCL(GPIO8)SDA(GPIO7)

  2. 接下来可以直接通过点击 🔥 编译、烧录、监视,完成后会在终端查看到命令菜单,当我们执行 i2cdetect 后,会打印出所有的 I2C 地址,如果有设备存在则会显示数字(I2C 地址 18 设备是板载的 ES8311 Codec 音频芯片,此芯片会在 I2S 部分详细说明),如图:

    i2cdetect

  3. 上述步骤已经实现了 I2C 设备通信的基础,在 I2C 通信协议设备中,常常需要通过 I2C 总线向对应地址的设备写寄存器配置以实现 I2C 设备的功能,此时我们需要在程序中写好 I2C 设备的初始化程序以便驱动 I2C 设备。不同的 I2C 设备存在不同的 I2C 地址,在开发中我们可以通过 i2ctools 工具查询接入的 I2C 地址,然后通过阅读其芯片手册查询寄存器、配置等内容实现 I2C 总线的通信。

进阶

1. 以太网 示例

以太网基本概念

  • 以太网是一种异步的带冲突检测的载波侦听多路访问 (CSMA/CD) 协议/接口。通常来说,以太网不太适用于低功耗应用。然而,得益于其广泛的部署、高效的网络连接、高数据率以及范围不限的可扩展性,几乎所有的有线通信都可以通过以太网进行。目前以太网根据速度等级分类大概分为:标准以太网(10Mbit/s),快速以太网(100Mbit/s),千兆以太网(1000Mbit/s),以及更快的万兆以太网(10Gbit/s)。

  • 以太网接口类型有 RJ45 接口,RJ11 接口(电话线接口)等。其中 RJ45 接口使我们最常用的以太网接口(电脑接口),也是 ESP32-P4-Module-DEV-KIT 板载网口类型。

  • ESP32-P4-Module-DEV-KIT 可以引用网络模型来解释:

    OSI 网络模型

    • ESP32-P4-Module-DEV-KIT 的网络接口层:是由 ESP32-P4 通过 RMII 接口连接 IP101GRI,并通过网络变压器引出 RJ45 接口网口,而开发板由 ESP32-P4 芯片内部集成的 MAC 层管理数据帧的封装、校验和 MAC 地址。
    • ESP32-P4-Module-DEV-KIT 的网络层、传输层:由 ESP32-P4 驱动 IP101GRI 实现
    • ESP32-P4-Module-DEV-KIT 的应用层:当成功与网络建立连接,ESP32-P4 就可以实现 HTTP 请求,使用 MQTT 等通信 server。

示例演示

此示例演示了 Ethernet driver 与 esp_netif 的基本用法。 Ethernet driver 的初始化包含在该项目的单独子组件中,以清楚地区分驱动程序的初始化和 esp_netif 初始化。该示例的工作流程如下:

ESP32P4 以太网 IP 地址通信的流程图

  1. RMII 定义: 上述内容中提到 ESP32-P4-Module-DEV-KIT 的 ESP32-P4 芯片与 IP101GRI 芯片之间是通过 RMII 接口建立连接的,接口定义如下:

    • TXD[1:0]:发送数据线,由 GPIO34GPIO35 控制
    • RXD[1:0]:接收数据线,由 GPIO30GPIO29 控制
    • TX_EN:发送启用信号,由 GPIO49 控制
    • CRS_DV:载波检测和数据有效信号,由 GPIO28 控制
    • REF_CLK:参考时钟,由 GPIO50 控制,50MHz 由 PHY 外侧连接的 25 MHz 无源晶振经过倍频产生
    • MDIOMDC:用于以太网的管理数据接口(控制和配置 PHY),由 GPIO52GPIO31 控制
    • RESET:控制 IP101GRI 复位,由 GPIO51 控制
  2. 打开 ethernetbasic 工程,选择好 COM 口和芯片型号,点击 ⚙️ 进入设置,这里会打开一个新的标签:SDK Configuration editor 也就是 menuconfig,我们直接在搜索栏中搜索 ETH,看到此时内容已经检索,将下图中参数与之对应,即可:

    配置 ETH 参数

  3. 接下来可以直接通过点击 🔥 编译、烧录、监视,完成后会在终端查看到程序启动,插入网线后可以获取到 IP,拔掉网线后断开动作,如图:

    以太网示例输出日志

  4. 从路由器上可以查看到一个设备名为 espressif 的设备已经连接,此时 ESP32-P4-Module-DEV-KIT 已经连上网络了。

    路由器界面查看 ESP32-P4 连接

2. SDMMC 示例

ESP32-P4-Module-DEV-KIT 板载了一个 4-Wire SDIO3.0 的卡槽,可拓展片外存储

  • 支持的速率模式

    • 默认速率 (20 MHz)
    • 高速模式(40 MHz)
  • 配置总线宽度和频率

    ESP-IDF 中,使用 sdmmc_host_tsdmmc_slot_config_t 设置配置,如设置默认 20MHz 通信频率、4 线宽度通信,则为:

    sdmmc_host_t host = SDMMC_HOST_DEFAULT();
    sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();

    在支持 40 MHz 频率通信的设计中,可以调整 sdmmc_host_t 结构体中的 max_freq_khz 字段,提升总线频率:

    sdmmc_host_t host = SDMMC_HOST_DEFAULT();
    host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;

    ESP32-P4-Module-DEV-KIT 上的 SDMMC 4 线连接定义应该为:

    sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
    slot_config.width = 4;
    slot_config.clk = 43;
    slot_config.cmd = 44;
    slot_config.d0 = 39;
    slot_config.d1 = 40;
    slot_config.d2 = 41;
    slot_config.d3 = 42;
    slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
    1. 打开 sdmmc 工程,选择好 COM 口和芯片型号,因为 demo 工程将引脚定义为宏,所以需要进行配置,当然也可以直接填入引脚数值。点击 ⚙️ 进入设置,这里会打开一个新的标签:SDK Configuration editor 也就是 menuconfig,我们直接在搜索栏中搜索 sd,看到此时内容已经检索,并且示例配置已经配置,勾选上默认初始化且默认创建示例文件:

      ESP-IDF 配置 SDMMC

    2. 接下来插入准备好的 SD 卡,通过点击 🔥 编译、烧录、监视,完成后会在终端查看到命令菜单输出了目录下的文件内容:

      SDMMC 示例输出

3. WIFI 联网示例

ESP32-P4 本身不带 WIFI/BT 功能,而 ESP32-P4-Module-DEV-KIT 通过 SDIO 连接了一块 ESP32-C6 模组来拓展 WIFI 功能。ESP32-C6 作为 Slave,通过一系列指令集支持 ESP32-P4 作为 Host 通过 SDIO 来使用 WIFI 6/BT 5 功能,通过添加两个组件后,可以做到无缝使用 esp_wifi

// 在一个 WIFI 工程下,通过 ESP-IDF 组件管理工具添加下述两个组件
idf.py add-dependency "espressif/esp_wifi_remote"
idf.py add-dependency "espressif/esp_hosted"
  1. 打开 wifistation 工程,进行组件的添加

    添加 espressif/esp_wifi_remote 和 espressif/esp_hosted 组件

  2. 如上图所示,是添加组件的具体步骤

    1. 打开 ESP-IDF Terminal。
    2. 在 Terminal 里将所需要的组件进行添加。
    3. 成功添加后,在工程项目中的 main 文件夹中会多出一个 idf_component.yml,此文件的作用已经在 ESP-IDF 工程目录章节说明过是用于管理项目组件的
    4. 打开后,可以看到已经添加上了 espressif/esp_hosted: "*"espressif/esp_wifi_remote: "*" 两个组件,在构建项目时,它们会被添加到项目中。
  3. 接下来可以通过点击 ⚙️ 打开设置,输入 Example 检索,这里设置好要连接 WIFI 的 ssidpassword注意 ESP32-C6 是支持 2.4GHz 的 WiFi-6,在选择目标 WiFi 时要确认好频率是 2.4GHz 的,修改完之后需要保存,否则会出错!

    配置 Wi-Fi 信息

  4. 接下来可以直接通过点击 🔥 编译、烧录、监视,完成后会在终端查看到如下结果,此时 ESP32-P4-Module-DEV-KIT 已经接入 WIFI 并且联网了:

    Wi-Fi 联网示例输出

4. I2S 音频示例

I2S(Inter-IC Sound) 是一种用于传输音频数据的数字通信协议。I2S 是一种串行总线接口,主要用于音频设备之间的数字音频数据传输,例如数字音频处理器 (DSP)、数字-模拟转换器 (DAC)、模拟-数字转换器 (ADC) 和音频编解码器。 ESP32-P4 包含 1 个 I2S 外设。通过配置这些外设,可以借助 I2S 驱动来输入和输出采样数据。

ESP32-P4-Module-DEV-KIT 板载了 es8311 Codec 芯片和 NS4150B 功放芯片组合,I2S 总线和引脚分布如下:

  • MCLK (Master Clock):主时钟信号。这个时钟通常由外部设备(如 MCU 或 DSP)提供给 ES8311,用于为其内部的数字音频处理模块提供时钟源。
  • SCLK (Serial Clock) :串行时钟信号。这个信号通常用于 I2S 数据传输的时钟同步,由主设备生成,用于指示数据的传输速率。每个音频样本的每一位的传输都需要一个时钟周期。
  • ASDOUT (Audio Serial Data Output)DOUT:音频数据输出引脚。ES8311 将解码后的数字音频数据输出到该引脚,然后传输给功放芯片或其他音频设备。
  • LRCK (Left/Right Clock)WS (Word Select):左右声道选择信号,用于指示当前数据样本属于左声道还是右声道。通常在 I2S 协议中,一个时钟周期表示左声道数据,另一个时钟周期表示右声道数据。
  • DSDIN (Digital Serial Data Input)DIN:数字音频数据输入引脚。该引脚接收来自外部音频设备或主设备的音频数据。ES8311 将这些数据解码,并通过内部的数字信号处理模块处理这些音频信号。

ESP32-P4 与 ES8311 编解码器以及 NS4150B 功放组成的音频信号处理框图

功能引脚ESP32-P4-Module-DEV-KIT 引脚
MCLKGPIO13
SCLKGPIO12
ASDOUTGPIO11
LRCKGPIO10
DSDINGPIO9
PA_Ctrl(功放芯片使能脚,高电平有效)GPIO53

ESP32-P4-Module-DEV-KIT es8311 驱动使用了 ES8311 组件,使用时可以通过 IDF Component Manager 来添加。

idf.py add-dependency "espressif/es8311"
  1. 打开 i2scodec 工程,进行组件的添加

    添加 espressif/es8311 组件

    1. 打开 ESP-IDF Terminal。
    2. 在 Terminal 里将所需要的组件进行添加
    3. 成功添加后,在工程项目中的 main 文件夹中会多出一个 idf_component.yml,此文件的作用已经在 ESP-IDF 工程目录章节说明过是用于管理项目组件的
    4. 打开后,可以看到已经添加上了 espressif/es8311 组件,在构建项目时,它们会被添加到项目中
  2. 接下来可以通过点击 ⚙️ 打开设置,搜索 Example,调整合适的音量

    配置音量

  3. 接上喇叭,可以直接通过点击 🔥 编译、烧录、监视,完成后会在终端查看到如下结果,此时 ESP32-P4-Module-DEV-KIT 已经在播放音频了

    I2S 音频示例输出

  4. 当在设置中设置 echo 模式时,音频将由麦克风收录,扬声器输出

    设置 echo 模式

5. MIPI-DSI 点屏示例

ESP32-P4-Module-DEV-KIT 使用 ESP32-P4NRW32 芯片,具有以下新特性:

  • 符合 MIPI-DSI 协议,使用 D-PHY v1.1 版本,最高 2-lane x 1.5Gbps(共 3Gbps)
  • 支持 RGB888、RGB565、YUV422 输入
  • 支持 RGB888、RGB666、RGB565 输出
  • 使用 video mode 输出视频流,支持输出固定图像 pattern

MIPI-DSI 图像处理还可以使用 2D-DMA 控制器处理,支持 PPA 和 JPEG 编解码外设。

MIPI-DSI LCD 驱动原理

MIPI-DSI LCD 驱动原理

所需硬件

  • 配套 10.1 寸显示屏及其配件
  • ESP32-P4-Module-DEV-KIT 开发板

点屏步骤

  1. 配套屏幕驱动已封装为组件,组件位置位于 ESP Component Registry

  2. 选择对应工程打开,选择 esp32p4 核心,接下来可以直接通过点击 🔥 编译、烧录、监视,完成后可以查看屏幕已经点亮刷新色条了:

    屏幕显示色条

高级

1. ETH To WIFI

此示例演示如何使用 ESP32-P4-Module-DEV-KIT 板载的 ESP32-C6 作为从机,使 ESP32-P4 驱动 IP101 注册网络后通过 ESP32-C6 实现 WiFi AP 功能

所需硬件

  • ESP32-P4-Module-DEV-KIT 开发板

运行步骤

  1. 打开工程后,选择 esp32p4 核心,接下来可以直接通过点击 🔥 编译、烧录、监视,完成后可以接上网线,查看 WiFi 进行上网。如果有选配合适的 PoE 模块则可以接上 PoE 交换机直接取电上网。

2. LVGL HMI 人机交互

本示例展示了 ESP32-P4 通过 MIPI DSI 接口将 LVGL 图像显示,可充分体现 ESP32-P4 强大的图像处理能力

所需硬件

  • 配套 10.1 寸显示屏及其配件
  • ESP32-P4-Module-DEV-KIT 开发板

点屏步骤

  1. 配套屏幕驱动已封装为组件,并且从 BSP 进行调用驱动。

  2. 打开工程后,通过 menuconfig Display 配置对应参数,选择 esp32p4 核心,接下来可以直接通过点击 🔥 编译、烧录、监视,完成后可以查看屏幕:

    LVGL HMI人机交互 图1LVGL HMI人机交互 图2
    LVGL HMI人机交互 图3LVGL HMI人机交互 图4
    LVGL HMI人机交互 图5LVGL HMI人机交互 图6

综合玩法

1. ESP-Phone

本示例基于 ESP_Brookesia,展示了一个类似 Android 的界面,其中包含许多不同的应用程序。该示例使用了开发板的 MIPI-DSI 接口、MIPI-CSI 接口、ESP32-C6、SD 卡和音频接口。基于此示例,可以基于 ESP_Brookesia 创建一个使用案例,从而高效开发多媒体应用程序。

所需硬件

  • 配套 10.1 寸显示屏及其配件
  • OV5647 或 SC2336 摄像头及排线
  • 8Ω 2W 喇叭
  • ESP32-P4-Module-DEV-KIT 开发板

点屏步骤

  1. 配套屏幕驱动已封装为组件,组件位置位于 ESP Component Registry

  2. 打开工程后,选择 esp32p4 核心,接下来可以直接通过点击 🔥 编译、烧录、监视,完成后可以查看屏幕:

    ESP-Phone 示例图1ESP-Phone 示例图2
    ESP-Phone 示例图3ESP-Phone 示例图4
    ESP-Phone 示例图5ESP-Phone 示例图6