ESP32-S3 N16R8 + 小智 AI + 2.8寸 TFT 屏开发实战:ESP-IDF环境搭建与硬件避坑指南
记录一次从 Arduino 开发转向 ESP-IDF 的完整过程,包括 ESP32-S3 环境搭建、小智 AI 烧录、I2S 音频调试、TFT 屏幕适配以及硬件踩坑记录。
本文不是"照着官方文档抄一遍"的教程,而是一个开发者从浏览器烧录 → VS Code + ESP-IDF → 硬件调试 → 屏幕白屏排查的全过程踩坑实录。
一、背景
最近尝试使用 ESP32-S3 N16R8 开发板运行小智 AI 语音助手。
目标:
- ESP32-S3 运行小智 AI 固件
- 接入 I2S 麦克风
- 接入 I2S 功放播放
- 添加 TFT 显示屏
- 后续扩展:
- AI 对话
- 实时语音通信
- 本地音频处理
- 音乐播放
开发环境:
- macOS Sequoia
- VS Code
- ESP-IDF Extension
- ESP32-S3 N16R8
资料来源:
二、第一次烧录:从浏览器开始
2.1 浏览器烧录流程
最开始我是跟着文档,用浏览器方式(ESP Launchpad)一步步烧录的。
整个流程很简单:
1.打开 ESP Launchpad 官网
2.选择小智 AI 固件
3.连接开发板
4.点击烧录
2.2 遇到的第一个坑:COM 端口无法连接
但最大的问题是——开发板的端口是否能被识别,直接决定连接能否成功。
我第一次连接时,页面直接报错:
Unable to detect device. Please ensure the device is not connected in
another application.
这个问题的排查思路:
- 检查 USB 线是否是数据线(不是充电线)
- 检查是否有其他程序占用了串口
- 尝试按一下开发板的 BOOT 键再连接
- 换一个 USB 口试试
2.3 烧录成功后的验证
烧录完成后,通过串口日志可以确认基础功能是否正常:
MQTT: Connected to endpoint
Application: Activation done
StateMachine: activating -> idle
说明:
- ✅ WiFi 连接成功
- ✅ MQTT 服务器连接成功
- ✅ AI 服务激活成功
音频模块正常时,日志会出现:
Wake word detected: 你好小智
StateMachine: idle -> listening
StateMachine: listening -> speaking
代表:
- ✅ 麦克风采集正常
- ✅ 唤醒模型运行正常
- ✅ AI 回复正常
三、为什么从浏览器烧录转向 ESP-IDF?
起初我用浏览器烧录的是 bread-compact-wifi(无屏幕版),一切正常。
但问题来了——我买的显示屏模块和博主的不一样:
- 博主的显示屏是 8 排针脚的
- 我的是 7 个针脚的
浏览器烧录只能用预设好的固件,没法自定义屏幕引脚和驱动。
所以我必须放弃浏览器方式,改用 VS Code + ESP-IDF 去修改源码、重新编译烧录。
四、ESP-IDF 开发环境搭建
4.1 VS Code 插件安装
在 VS Code 插件市场搜索并安装:
- ESP-IDF Extension(Espressif 官方)—— 负责编译、烧录、串口监控、menuconfig 配置、调试
- C/C++ Extension(Microsoft)—— 语法支持
4.2 底部快捷工具栏说明
VS Code 状态栏最下方的图标含义如下:
4.3 核心 Command Palette 快捷命令
按 Cmd + Shift + P(Mac)或 Ctrl + Shift + P(Windows)调出命令面板:
- ESP-IDF: Full Clean — 清理所有临时编译文件(修改 sdkconfig 或 .h 头文件未生效时必做)
- ESP-IDF: SDK Configuration Editor (GUI) — 打开可视化 kconfig 设置页面
- ESP-IDF: Select Flash Method and Port — 选择串口和烧录模式(通常选 UART)
4.4 setting.json 优化配置
建议在 settings.json 中加上:
{
"df.flashType": "UART",
"df.flashBaudRate": "921600"
}
提高烧录速度,避免每次烧录等半天。
五、ESP32-S3 N16R8 硬件注意事项
5.1 🚨 致命避坑:PSRAM GPIO 冲突
我的开发板:ESP32-S3 N16R8
带:
- 16MB Flash
- 8MB Octal PSRAM
⚠️ 重要修正:网上很多文章说"GPIO 47 在 N16R8 芯片内部被八路高速内存(PSRAM)总线占用",这个描述不够准确。
更准确的说法是:ESP32-S3 N16R8 使用 Octal PSRAM 时,部分 GPIO 会被 Flash/PSRAM
总线占用,不能作为普通外设 IO 使用。实际可用 GPIO 需要结合芯片封装和官方 datasheet 判断。 不同 ESP32-S3
模组封装可能不同,不要一概而论。
踩坑经历:
最开始我把 TFT 的 SDA/MOSI 接到了 GPIO 47,结果:
- ❌ 屏幕白屏
- ❌ SPI 完全无法通信
原因: GPIO 47 被 PSRAM 总线占用,系统启动 PSRAM 后该引脚会被锁死。
解决方案: 将 SDA/MOSI 挪至空闲管脚 GPIO 1(或 GPIO 11 / 12 等)。
六、I2S 音频模块接线
6.1 麦克风模块
小智默认配置:
#define AUDIO_I2S_MIC_GPIO_WS GPIO_NUM_4
#define AUDIO_I2S_MIC_GPIO_SCK GPIO_NUM_5
#define AUDIO_I2S_MIC_GPIO_DIN GPIO_NUM_6
实际接线:
验证方法:
日志中出现:
AFE Pipeline:
[input] -> VAD -> WakeNet
表示录音链路正常。
6.2 播放模块
小智默认:
#define AUDIO_I2S_SPK_GPIO_DOUT GPIO_NUM_7
#define AUDIO_I2S_SPK_GPIO_BCLK GPIO_NUM_15
#define AUDIO_I2S_SPK_GPIO_LRCK GPIO_NUM_16
实际连接:
真实踩坑过程:
第一次烧录完成后:
- ✅ WiFi 正常
- ✅ MQTT 正常
- ✅ AI 文字回复正常
- ✅ 麦克风唤醒正常
- ❌ 但是没有声音! 排查了半天,最后发现是 播放 I2S GPIO 不匹配。 修改后:
- DIN → GPIO 7
- BCLK → GPIO 15
- LRC → GPIO 16 重新烧录,AI 语音播放恢复正常 🎉
经验总结: 如果 AI 文字回复正常但没有声音,优先检查 I2S 播放 GPIO 是否匹配。
七、2.8 寸 SPI TFT 屏适配
7.1 关于屏幕驱动型号的判断
我的屏幕:7 针 SPI TFT
引脚:CS、DC、RST、SDA、SCK、VCC、GND
⚠️ 注意:购买页面显示"2.8 寸 SPI TFT",并不能直接确定驱动型号。 常见的 2.8 寸屏驱动有:
- ILI9341(最常见,240×320)
- ST7789(也很常见,240×320,IPS 屏常用)
- ILI9488(320×480,分辨率更高) 这几种外观非常接近,可以提前调研看看博主们用的什么,这些都能查到, 别跟我似的瞎猫碰上死耗子,瞎买一通最后显示屏跟博主不一样最后还得修源码烧录进去
我这边最终确认是 ILI9341。
7.2 接线表

💡 注意:这里的 SDA 不是 I2C 的 SDA,而是 SPI 的 MOSI。
八、小智 AI 项目工程配置与板型切换
8.1 sdkconfig 配置文件修改
项目默认开启的是"无屏 Wi-Fi 版",需手动开启"LCD 带屏版":
打开项目根目录下的 sdkconfig,找到 CONFIG_BOARD_TYPE 区域,修改为:
# CONFIG_BOARD_TYPE_BREAD_COMPACT_WIFI is not set
CONFIG_BOARD_TYPE_BREAD_COMPACT_WIFI_LCD=y
8.2 配置文件修改(bread-compact-wifi-lcd/config.h)
打开 main/boards/bread-compact-wifi-lcd/config.h,更新 SPI 引脚和驱动预设:
// 引脚定义(避开 PSRAM 47号管脚)
#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_NC // 7脚屏背光板载硬连VCC,填 NC
#define DISPLAY_MOSI_PIN GPIO_NUM_1 // SDA / MOSI 改为 GPIO 1
#define DISPLAY_CLK_PIN GPIO_NUM_21 // SCL / CLK
#define DISPLAY_DC_PIN GPIO_NUM_40 // DC / RS
#define DISPLAY_RST_PIN GPIO_NUM_45 // RES / RST
#define DISPLAY_CS_PIN GPIO_NUM_41 // CS
// 保底屏幕驱动配置(如 SDK 未选中宏,默认按 2.8寸 ILI9341 驱动加载)
#if !defined(CONFIG_LCD_ST7789_240X320) && !defined(CONFIG_LCD_ST7789_240X320_NO_IPS) && \
!defined(CONFIG_LCD_ILI9341_240X320) && !defined(CONFIG_LCD_ILI9341_240X320_NO_IPS) && \
!defined(CONFIG_LCD_GC9A01_240X240) && !defined(CONFIG_LCD_CUSTOM)
#define CONFIG_LCD_ILI9341_240X320_NO_IPS
#endif
8.3 修改后必须清理缓存!
ESP-IDF 使用 CMake 缓存机制。
修改过以下内容后:
- sdkconfig
- GPIO 定义
- board config
- CMakeLists.txt
必须执行:
ESP-IDF: Full Clean
然后再:
Build → Flash → Monitor
否则可能继续使用旧配置,改了半天没效果,怀疑人生。
九、白屏故障快速排查 CheckList
如果烧录后屏幕仍然白屏,请按以下流程速查:
第一步:查日志板型
打开 VS Code 串口 Monitor,按复位键查看开机日志:
- 必须看到 bread-compact-wifi-lcd
- 如果仍显示 bread-compact-wifi,说明 sdkconfig 没修改成功或缓存未清理
第二步:查 PSRAM 管脚
确认 MOSI 线没有接到以下管脚上:
- GPIO 47 / 48
- GPIO 35-37(部分模组也可能被占用)
第三步:彻底清理缓存
修改过 sdkconfig 或 CMakeLists.txt 后,必须执行 ESP-IDF: Full Clean(或手动删除项目下的 build 文件夹),再重新编译烧录。
第四步:检查驱动型号
如果以上都没问题还是白屏,试试换驱动:
- ILI9341 → ST7789 → GC9A01 逐个试
- 注意分辨率是否匹配(240×320 还是 240×240)
十、最终 GPIO 规划表

十一、调试经验总结
1. 不要只看"烧录成功"
烧录成功 ≠ 硬件正确。
需要分别验证每个模块:
模块验证方式WiFi看日志是否连上路由器MQTT看日志是否 Connected麦克风说唤醒词,看是否触发 Wake word detected播放AI 是否有语音输出屏幕是否正常显示,不是白屏按键GPIO 输入是否响应
2. ESP-IDF 和 Arduino 的区别
ArduinoESP-IDF定位快速验证原型正式产品开发适合场景点灯、传感器、简单项目AI、音频、多任务、DMA、FreeRTOS、硬件驱动学习曲线简单较陡性能一般高
后续如果要做:
- 实时对讲
- 实时音频流
- 本地音频处理
更适合用 ESP-IDF。
十二、下一步开发计划
基于当前环境继续扩展:
- TFT UI 显示自定义界面
- 自定义唤醒词
- ESP32 实时对讲功能
- 音频流传输
- Electron 桌面端控制
- Rust 音频处理模块
ESP32-S3 只是开始,后续将逐步构建完整 AI 硬件系统。
写在最后:
从最开始跟着教程用浏览器烧录,到后来因为屏幕不匹配被迫跳进 ESP-IDF 的坑,再到一步步解决 GPIO 冲突、屏幕白屏、音频无声的问题——
这整个过程,比单纯"学会烧录小智"有价值得多。
我积累的不是"小智烧录笔记",而是在形成一个完整 AI 硬件平台做开发的基础。
为今后对自己扩展知识范围,学习对讲设备、Electron 控制端、Rust 音频服务做基础。
与各位正在折腾 ESP32 的开发者共勉
更多推荐



所有评论(0)