You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 09:15:54