前言
之前已经用 ESP32-S3 模块做了不少项目,会经常使用到 SPI 总线来驱动外设,想起来有两个坑需要注意,这里记录一下供大家参考~
两个坑都跟 GPIO 使用有关系:
-
N16R8 版本的 ESP32-S3 模块,GPIO 35/36/37 被内部 PSRAM 占用,绝对不能拿来做 SPI
-
SPI 只有走 IOMUX 固定引脚才能跑到 80MHz;一旦用 GPIO Matrix 重映射,最高只有 40MHz
坑一:N16R8 的 GPIO 35/36/37 不能碰
N16R8 是什么
ESP32-S3 有很多封装版本,N16R8 的意思是:板载 16MB Flash + 8MB PSRAM。听起来很香,内存大、Flash 大,DIY 项目首选。
但它有个代价:片内的 Octal Flash 和 Octal PSRAM 需要占用更多 GPIO 引脚。普通版本(比如 N8)只占用 GPIO 27-32,而 N16R8 额外还要占用 GPIO 35、36、37。
文档中说明如下:
SPI0/1:GPIO26-32 通常用于 SPI flash 和 PSRAM,不推荐用于其他用途。当使用八线 flash 或八线 PSRAM 或同时使用两者时,GPIO33~37 会连接到 SPIIO4 ~ SPIIO7 和 SPIDQS。因此,对于内嵌 ESP32-S3R8 或 ESP32-S3R8V 芯片的开发板,GPIO33~37 也不推荐用于其他用途。
EDA 中要注意
在 LCEDA 中直接使用 N16R8 模块器件时,并不会额外标明这几个引脚不能使用,因此在设计原理图时需要特别注意,不要把这几个引脚用来当作普通 GPIO 或者 SPI 总线的引脚来使用。
解决方案
绕开 35/36/37,改用其他 GPIO。
选 pin 时可以参考这个范围:GPIO 0-21、GPIO 38-48。
部分引脚是 Strapping 管脚,同样需要注意,建议使用前先仔细阅读数据手册是否有影响。
坑二:GPIO Matrix 把速度砍了一半
ESP32-S3 相比其他 MCU 最方便的就是外设的 IO 可以随意使用,不是固定外设与固定引脚配对,但是这里也就会有一个小坑。
两种 SPI 信号路由方式
ESP32-S3 的 SPI 信号有两种走法:
ESP32-S3 的 SPI2(FSPI)有一组固定的 IOMUX 引脚:
只要你把 SPI 脚分配到这几个固定引脚,硬件自动走 IOMUX,可以跑满 80 MHz。
一旦你换了任何一个脚,哪怕只换了一个 CS,信号就全部绕道 GPIO Matrix,整组 SPI 速度上限跌到 40 MHz。
踩坑现象
代码里写的是 SPI.setFrequency(80000000),但用逻辑分析仪一量,CLK 实际频率 40 MHz,少了整整一半。
在之前测试 JPEG 解码(ESP32-S3 JPEG 实测:从解码库对比到 DMA 优化,最终到达 SPI 上限)中也说到,因为用了 GPIO Matrix,SPI 刷屏速度最高也只能 43 FPS。
怎么确认走的是哪种路由
方法一:看引脚分配,对照 SPI2 的 IOMUX 表,每个脚都在固定位置才是 IOMUX。
方法二:用逻辑分析仪实测,设 80MHz,实际量出来 40MHz 就说明走了 Matrix。
方法三:查 ESP-IDF 日志,驱动初始化时会打印使用的模式(需要开 debug 级别日志)。
怎么避开这两个坑
总结一下选 pin 的原则:
-
用 N16R8 时,GPIO 35/36/37 列为禁区,原理图里直接加上非连接标记
-
SPI 想跑 80MHz,必须全部用 IOMUX 固定引脚,一个都不能换;如果板子布线不允许,就接受 40MHz 的上限
后续打算
之前测试 JPEG 解码是用了以前做好的开发板,后面手动连接到固定引脚,看看在 80Mbps 下刷屏速度能提升到多少。
参考资料
-
https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32s3/api-reference/peripherals/spi_master.html
-
https://docs.espressif.com/projects/esp-idf/zh_CN/v5.0/esp32s3/api-reference/peripherals/gpio.html
GPIO 35/36/37 能不能用, 似乎不是和 flash 大小 关联的,
是取决于 模块内是不是用了 Octal Flash 和 Octal PSRAM ??
有的模块, 即使 是 ESP32-S3-N16R8, 只要不是用的 Octal (八线的) FLASH/PSRAM
GPIO 35,36,37 就不会在模块内被占用.
您的理解非常准确,GPIO 35/36/37 是否被占用,本质上取决于内部 Flash 或 PSRAM 是否采用 Octal(八线)SPI 接口,而非单纯由存储容量决定。
在乐鑫官方标准模组(如 ESP32-S3-WROOM-1 系列)中,带有“R8”后缀的型号通常默认封装了 Octal PSRAM,因此市售的绝大多数 N16R8 成品模块确实会占用这些引脚。
正如您所指出的,如果是开发者自行设计 PCB 并采用 Quad(四线)SPI 走线,或者使用了特定配置的非八线模组,这几个引脚确实是空闲可用的。
感谢您的补充,这一严谨的指正能有效避免读者产生“大容量模组必定占用该引脚”的误区。