1. 确认 ESP32 的 SPI 引脚
ESP32 有两个硬件 SPI 总线:
SPI 总线 | SCK (CLK) | MISO | MOSI | CS (SS) |
---|---|---|---|---|
VSPI (默认) | GPIO 18 | GPIO 19 | GPIO 23 | 用户指定 |
HSPI | GPIO 14 | GPIO 12 | GPIO 13 | 用户指定 |
2. 修改方案(二选一)
方案 1:将 SD 卡切换到 HSPI
#include <SPI.h>
#include <SD.h>
#define HSPI_SCK 14 // HSPI 的 SCK
#define HSPI_MISO 12 // HSPI 的 MISO
#define HSPI_MOSI 13 // HSPI 的 MOSI
#define SD_CS 5 // SD 卡的 CS 引脚(不变)
SPIClass hspi(HSPI); // 创建一个 HSPI 对象
void setup() {
Serial.begin(115200);
// 初始化 HSPI 用于 SD 卡
hspi.begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, SD_CS); // 指定 HSPI 引脚
if (!SD.begin(SD_CS, hspi)) { // 使用 HSPI 初始化 SD 卡
Serial.println("SD 卡初始化失败!");
return;
}
Serial.println("SD 卡初始化成功(使用 HSPI)");
// TFT 屏幕仍然使用默认的 VSPI(无需修改)
tft.begin();
// ... 其他初始化代码
}
方案 2:将 TFT 屏幕切换到 HSPI
如果你的屏幕库(如 TFT_eSPI
)支持自定义 SPI,可以修改它的引脚:
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#define HSPI_SCK 14
#define HSPI_MISO 12 // 如果屏幕不需要 MISO,可以忽略
#define HSPI_MOSI 13
#define TFT_CS 15 // 屏幕的 CS 引脚
void setup() {
// 初始化 HSPI 用于屏幕
tft.begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, TFT_CS); // 部分库支持自定义 SPI 引脚
tft.setRotation(3);
// SD 卡仍然使用默认的 VSPI
SPI.begin();
if (!SD.begin(SD_CS)) {
Serial.println("SD 卡初始化失败!");
}
}
⚠️ 注意:
部分屏幕库(如
TFT_eSPI
)需要在 用户配置文件(如TFT_eSPI/User_Setup.h
)中手动修改 SPI 引脚。如果库不支持动态引脚修改,可能需要直接修改库代码。
以下是路径及更改方法:
// 原 VSPI 引脚(默认)
// #define TFT_MOSI 23 // VSPI MOSI (GPIO 23)
// #define TFT_SCLK 18 // VSPI SCK (GPIO 18)
// 改为 HSPI 引脚
#define TFT_MOSI 13 // HSPI MOSI (GPIO 13)
#define TFT_SCLK 14 // HSPI SCK (GPIO 14)
#define TFT_CS 4 // 片选引脚(保持不变)
#define TFT_DC 16 // 数据/命令引脚(保持不变)
#define TFT_RST 17 // 复位引脚(保持不变)
#define TFT_BL 22 // 背光控制(保持不变)
关于TFT屏幕有一部分是雪花的解决方法:根据自己的屏幕找到自己屏幕对应的rotation.h
我的屏幕是ST7735S,所以改以下代码注释部分左边的数值,调整到屏幕没有雪花屏即可
switch (rotation) {
case 0:
if (tabcolor == INITR_BLACKTAB) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
} else if(tabcolor == INITR_GREENTAB2) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
colstart = 2;
rowstart = 1;
} else if(tabcolor == INITR_GREENTAB3) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
colstart = 2;
rowstart = 3;
} else if(tabcolor == INITR_GREENTAB128) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_COLOR_ORDER);
colstart = 2;//横向偏移
rowstart = 0;//纵向偏移
} else if(tabcolor == INITR_GREENTAB160x80) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_COLOR_ORDER);
colstart = 26;
rowstart = 1;
} else if(tabcolor == INITR_REDTAB160x80) {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MH | TFT_MAD_COLOR_ORDER);
colstart = 24;
rowstart = 0;
} else if(tabcolor == INITB) {
writedata(TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
} else {
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
}
_width = _init_width;
_height = _init_height;
break;