ESP32-S3-Touch-LCD-2 SPI显示屏与SD卡无法同时工作求助
ESP32-S3-Touch-LCD-2开发板显示屏与SD卡无法同时工作(SPI资源冲突问题)
我使用Waveshare ESP32-S3-Touch-LCD-2开发板,该板集成显示屏、SD卡槽和摄像头。目标是在显示屏上显示摄像头实时画面,并通过按键触发保存图像。但显示屏和SD卡无法同时正常工作,二者总有一个故障,单独使用时均能正常运行。推测是SPI资源冲突导致,但不知道如何修复,求相关提示。
测试代码
仅SD卡测试代码
#include "FS.h" #include "SD.h" #include "SPI.h" // Pin-Konfiguration für SD-Karte (SPI) #define SD_CS 41 #define SD_SCK 39 #define SD_MOSI 38 #define SD_MISO 40 void setup() { Serial.begin(115200); delay(2000); Serial.println("\n--- Minimaler SD-Karten-Test ---"); // Den SPI-Bus explizit für die SD-Karte initialisieren SPI.begin(SD_SCK, SD_MISO, SD_MOSI, -1); Serial.println("Versuche, die SD-Karte zu initialisieren..."); if (SD.begin(SD_CS)) { Serial.println("\nERFOLG! Die SD-Karte wurde erkannt!"); Serial.print("Kartentyp: "); uint8_t cardType = SD.cardType(); if(cardType == CARD_MMC){ Serial.println("MMC"); } else if(cardType == CARD_SD){ Serial.println("SDSC"); } else if(cardType == CARD_SDHC){ Serial.println("SDHC"); } else { Serial.println("UNKNOWN"); } uint64_t cardSize = SD.cardSize() / (1024 * 1024); Serial.printf("Kartengroesse: %llu MB\n", cardSize); } else { Serial.println("\nFEHLER: Die SD-Karte konnte nicht initialisiert werden."); } } void loop() { // Bleibt leer. }
仅显示屏测试代码
#include <Arduino_GFX_Library.h> #include "SPI.h" // Pin-Konfiguration für Display (SPI) #define GFX_BL 1 #define GFX_CS 45 #define GFX_SCK 39 #define GFX_MOSI 38 #define GFX_MISO 40 // Oft nicht zwingend notwendig, aber zur Sicherheit anschließen #define GFX_DC 42 Arduino_DataBus *bus = new Arduino_ESP32SPI(GFX_DC, GFX_CS, GFX_SCK, GFX_MOSI, GFX_MISO); Arduino_GFX *gfx = new Arduino_ST7789(bus, -1, 2, true, 240, 320); void setup() { Serial.begin(115200); delay(2000); pinMode(GFX_BL, OUTPUT); digitalWrite(GFX_BL, HIGH); gfx->begin(); // Wenn der Code hier ankommt, ist die Initialisierung erfolgreich. Serial.println("gfx->begin() wurde ausgefuehrt."); gfx->fillScreen(GREEN); // Eindeutiger Test mit einer Farbe gfx->setCursor(10, 10); gfx->setTextColor(BLACK); gfx->setTextSize(3); gfx->println("Display"); gfx->println("FUNKTIONIERT!"); Serial.println("Display-Test beendet. Sie sollten jetzt einen grünen Bildschirm mit schwarzem Text sehen."); } void loop() { // Bleibt leer. }
显示屏与SD卡联合测试代码
#include <Arduino_GFX_Library.h> #include "FS.h" #include "SD.h" #include "SPI.h" // Pin-Konfiguration für Display (SPI) #define GFX_BL 1 #define GFX_CS 45 #define GFX_SCK 39 #define GFX_MOSI 38 #define GFX_MISO 40 #define GFX_DC 42 Arduino_DataBus *bus = new Arduino_ESP32SPI(GFX_DC, GFX_CS, GFX_SCK, GFX_MOSI, GFX_MISO); Arduino_GFX *gfx = new Arduino_ST7789(bus, -1, 2, true, 240, 320); // Pin-Konfiguration für SD-Karte (SPI) #define SD_CS 41 // SCK, MOSI, MISO werden mit dem Display geteilt void setup() { Serial.begin(115200); // Warten Sie einen Moment, damit der Serielle Monitor verbunden werden kann delay(2000); Serial.println("\n--- Minimaler SD-Karten & Display Test ---"); // 1. Manuelle Steuerung der CS-Pins: Beide Geräte deaktivieren (HIGH) pinMode(GFX_CS, OUTPUT); pinMode(SD_CS, OUTPUT); digitalWrite(GFX_CS, HIGH); digitalWrite(SD_CS, HIGH); Serial.println("Schritt 1: Beide CS-Pins auf HIGH gesetzt."); delay(100); // 2. SPI-Bus initialisieren SPI.begin(GFX_SCK, GFX_MISO, GFX_MOSI, -1); Serial.println("Schritt 2: SPI-Bus initialisiert."); // 3. Display als ERSTES initialisieren und testen pinMode(GFX_BL, OUTPUT); digitalWrite(GFX_BL, HIGH); gfx->begin(); gfx->fillScreen(BLACK); gfx->setCursor(10, 10); gfx->setTextColor(WHITE); gfx->setTextSize(2); gfx->println("Display OK"); Serial.println("Schritt 3: Display scheint OK zu sein."); // 4. SD-Karte als ZWEITES initialisieren gfx->println("Initialisiere SD..."); Serial.println("Schritt 4: Versuche SD.begin()..."); if (!SD.begin(SD_CS)) { Serial.println("FEHLER: SD.begin() ist fehlgeschlagen!"); gfx->setTextColor(RED); gfx->println("SD Fehler!"); // Der Code stoppt hier, damit Sie die Fehlermeldung sehen können while(1); } Serial.println("Schritt 5: SD-Karte erfolgreich initialisiert."); gfx->setTextColor(GREEN); gfx->println("SD-Karte OK!"); // 5. Kartengröße auslesen und auf dem Display anzeigen uint64_t cardSize = SD.cardSize() / (1024 * 1024); Serial.printf("Schritt 6: SD Kartengroesse: %llu MB\n", cardSize); gfx->setTextColor(WHITE); gfx->println("Groesse:"); gfx->printf("%llu MB", cardSize); } void loop() { // Bleibt für diesen Test absichtlich leer. }
联合测试输出
步骤1:两个CS引脚已设为HIGH。
步骤2:SPI总线已初始化。
修复建议
1. 严格控制SPI设备切换时的CS引脚与总线参数
gfx->begin()可能会修改SPI的时钟频率或模式,导致SD卡初始化失败。在SD卡初始化前,手动禁用显示屏并重置SPI参数:
// 在SD.begin()前添加以下代码 digitalWrite(GFX_CS, HIGH); // 强制禁用显示屏 SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); // SD卡初始化常用低速参数 if (!SD.begin(SD_CS)) { Serial.println("FEHLER: SD.begin() ist fehlgeschlagen!"); gfx->setTextColor(RED); gfx->println("SD Fehler!"); while(1); } SPI.endTransaction();
2. 重新初始化SPI总线
尝试在SD卡初始化前关闭并重新初始化SPI总线,避免显示屏库遗留的参数影响:
// SD卡初始化前执行 SPI.end(); SPI.begin(GFX_SCK, GFX_MISO, GFX_MOSI, -1);
3. 为其中一个设备使用软件SPI
如果硬件SPI冲突无法解决,可为SD卡分配额外引脚使用软件SPI,避开硬件总线冲突:
// 引入软件SPI库 #include <SoftwareSPI.h> // 定义SD卡软件SPI引脚(可自行选择未占用的引脚) #define SD_SCK_SW 10 #define SD_MOSI_SW 11 #define SD_MISO_SW 12 // 初始化软件SPI对象 SoftwareSPI sdSPI(SD_SCK_SW, SD_MISO_SW, SD_MOSI_SW); // 使用软件SPI初始化SD卡 SD.begin(SD_CS, sdSPI);
4. 参考开发板官方示例
检查开发板官方文档,确认是否有同时使用显示屏与SD卡的现成示例,官方代码通常已处理SPI资源冲突问题。
内容的提问来源于stack exchange,提问作者bennnil
相关产品推荐
相关产品推荐

