• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

ESP32-S3 работа с двумя SPI одновременно Arduino

enjoynering

Well-known member
Как мы знаем у ESP32-S3 три SPI шины. К первой подключена флешка и не доступна для пользователя. Вторая FSPI имеет независимый DMA. В Arduino используется по умолчанию и висит на GPIO 10, 11, 12, 13. Третья HSPI тоже имеет DMA, который совместно используется другими перифериями. Может быть проброшена к любыми GPIO через "GPIO Matrix". Теперь к сути...

На FSPI у меня экран, который раз в секунду обновляет время. Чтобы ему не мешать, хочу повесить SD карточку на HSPI. Код компилируется, но SD карточка не стартует - "SD.begin()" постоянно возвращает false. Что я делаю не так?

Весь код не выкладываю. Вот основные моменты:

Код:
#include <Arduino.h>
#include <SD.h>
#include <FS.h>
#include <SPI.h>


#define AUDIO_SPI_SD_CS  39  //GPIO5  for ESP32
#define AUDIO_SPI_SCK    40  //GPIO18 for ESP32
#define AUDIO_SPI_MOSI   41  //GPIO23 for ESP32
#define AUDIO_SPI_MISO   42  //GPIO19 for ESP32


SPIClass sdSPI(HSPI); //FSPI, HSPI


void setup()
{
  pinMode(AUDIO_SPI_SD_CS, OUTPUT);
  digitalWrite(AUDIO_SPI_SD_CS, HIGH);                        //disables SPI interface for SD card

  sdSPI.begin(AUDIO_SPI_SCK, AUDIO_SPI_MISO, AUDIO_SPI_MOSI); //start SPI bus
  if (SD.begin(AUDIO_SPI_SD_CS, sdSPI, 4000000) != true)      //start SD card, SPI3(HSPI), 10MHz (default 4MHz)
  {
    Serial.printf_P(PSTR("Oops! unable to set SPI3(HSPI) GPIO%u -> CS, GPIO%u -> SCK, GPIO%u -> MOSI, GPIO%u -> MISO\n"), AUDIO_SPI_SD_CS, AUDIO_SPI_SCK, AUDIO_SPI_MOSI, AUDIO_SPI_MISO);
  }

}

void loop()
{
  vTaskDelay(1); //non-blocking delay allowing other threads to continue running
}
 

pvvx

Активный участник сообщества
DeepSeek: Подключение MicroSD Card к ESP32-S3 через HSPI в Arduino IDE
...
Вот как использовать HSPI (SPI2) для работы с SD-картой.

Пример кода для ESP32-S3 с HSPI
C:
#include <SPI.h>
#include <SD.h>

// Конфигурация пинов HSPI (SPI2) для ESP32-S3
#define HSPI_SCK 12 // SCK
#define HSPI_MISO 13 // MISO
#define HSPI_MOSI 11 // MOSI
#define HSPI_CS 10 // Chip Select (любой GPIO)

// Создаем экземпляр SPI для HSPI (SPI2)
SPIClass hspi(HSPI);

void setup() {
Serial.begin(115200);
while(!Serial); // Ждем готовности Serial

Serial.println("Инициализация SD карты через HSPI...");

// Инициализируем HSPI с пользовательскими пинами
hspi.begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, HSPI_CS);

// Инициализация SD карты с HSPI
if(!SD.begin(HSPI_CS, hspi)) {
Serial.println("Ошибка инициализации SD карты!");
while(1);
}
Serial.println("SD карта инициализирована успешно!");

// Тест записи/чтения
File file = SD.open("/test.txt", FILE_WRITE);
if(file) {
file.println("Тест HSPI на ESP32-S3");
file.close();
Serial.println("Данные записаны в test.txt");
} else {
Serial.println("Ошибка открытия файла!");
}
}

void loop() {
// Чтение и вывод содержимого файла
File file = SD.open("/test.txt");
if(file) {
Serial.println("Содержимое test.txt:");
while(file.available()) {
Serial.write(file.read());
}
file.close();
}
delay(5000);
}
Схема подключения для ESP32-S3
Код:
ESP32-S3 -> SD Card
----------------------
GPIO10 (CS) -> Pin 1 (CS)
GPIO12 (SCK) -> Pin 5 (SCK)
GPIO11 (MOSI) -> Pin 2 (MOSI)
GPIO13 (MISO) -> Pin 7 (MISO)
GND -> Pin 3 (GND)
3.3V -> Pin 4 (VCC)
Особенности HSPI на ESP32-S3
  1. Доступные SPI контроллеры:
    • SPI2 (HSPI) - более гибкий в выборе пинов
    • SPI3 (VSPI) - также доступен для использования
  2. Гибкость выбора пинов:
    • Для HSPI можно использовать различные комбинации GPIO
  3. Рекомендуемые пины:
    Код:
    // Альтернативная конфигурация пинов
    #define HSPI_SCK 36
    #define HSPI_MISO 37
    #define HSPI_MOSI 35
    #define HSPI_CS    34
  4. Оптимизация скорости:
    C:
    // Установка высокой скорости (до 80 MHz)
    hspi.beginTransaction(SPISettings(80000000, MSBFIRST, SPI_MODE0));
  5. Отладка проблем:
    • Если SD карта не определяется, попробуйте:
      • Добавить подтягивающий резистор 10kΩ на линию CS
      • Уменьшить частоту SPI (начать с 1 MHz)
      • Проверить питание SD карты (некоторые требуют стабильного 3.3V)
Для максимальной производительности рекомендуется использовать 4-битный режим SDIO, но HSPI в SPI режиме обеспечивает хороший баланс между простотой подключения и скоростью работы.
 

pvvx

Активный участник сообщества
DeepSeek: Как мы знаем у ESP32-S3 три SPI шины. К первой подключена флешка и не доступна для пользователя. Вторая FSPI имеет независимый DMA. В Arduino используется по умолчанию и висит на GPIO 10, 11, 12, 13. Третья HSPI тоже имеет DMA, который совместно используется другими перифериями. Может быть проброшена к любыми GPIO через "GPIO Matrix". Теперь к сути... На FSPI у меня экран, который раз в секунду обновляет время. Чтобы ему не мешать, хочу повесить SD карточку на HSPI. Код компилируется, но SD карточка не стартует - "SD.begin()" постоянно возвращает false. Что я делаю не так?

Проблема инициализации SD на HSPI ESP32-S3


Проблема с инициализацией SD-карты на HSPI у ESP32-S3 может быть вызвана несколькими причинами. Давайте разберём возможные решения:
1. Правильная настройка пинов HSPI
У ESP32-S3 HSPI использует GPIO Matrix, поэтому нужно явно указать пины в SD.begin(). По умолчанию HSPI использует:
  • MOSI: GPIO13 (но может быть переназначен)
  • MISO: GPIO12
  • SCK: GPIO14
  • CS: Любой GPIO (например, GPIO5)
Попробуйте явно указать пины:
cpp

Copy

Download
#include <SPI.h>
#include <SD.h>

#define HSPI_CS 5 // Любой свободный GPIO
#define HSPI_MISO 12
#define HSPI_MOSI 13
#define HSPI_SCK 14

SPIClass hspi(HSPI); // Создаём объект HSPI

void setup() {
Serial.begin(115200);
hspi.begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, HSPI_CS); // Настраиваем HSPI

if (!SD.begin(HSPI_CS, hspi)) { // Инициализируем SD с HSPI
Serial.println("SD Card Mount Failed");
return;
}
Serial.println("SD Card Initialized");
}
2. Проблема с питанием SD-карты
  • Убедитесь, что SD-карта получает 3.3V (не 5V!).
  • Проверьте, что линия CS правильно подключена и не "плавает".
  • Некоторые SD-карты требуют подтяжки MOSI и MISO к 3.3V (резисторы 10–50 кОм).
3. Скорость SPI
Попробуйте снизить скорость SPI для SD-карты:
cpp

Copy

Download
hspi.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); // 1 MHz
if (!SD.begin(HSPI_CS, hspi)) { ... }
4. Форматирование SD-карты
  • Убедитесь, что карта отформатирована в FAT16/FAT32.
  • Попробуйте другую SD-карту (некоторые карты SDHC/SDXC могут требовать инициализации по-другому).
5. Конфликт с другими перифериями
  • Убедитесь, что DMA HSPI не используется другими устройствами (например, Wi-Fi/Bluetooth).
  • Если у вас включен Wi-Fi, попробуйте временно отключить его в menuconfig (если используете PlatformIO/Arduino-ESP32).
6. Проверка соединений
  • MISO SD-карты должен быть подключён к MISO ESP32-S3 (GPIO12 для HSPI).
  • MOSI → GPIO13, SCK → GPIO14.
  • CS должен быть уникальным для каждого SPI-устройства.
Альтернативный вариант: Software SPI
Если HSPI не работает, можно попробовать Software SPI:
cpp

Copy

Download
#include <SD.h>
#define SD_MISO 2
#define SD_MOSI 3
#define SD_SCK 4
#define SD_CS 5

void setup() {
if (!SD.begin(SD_CS, SD_MOSI, SD_MISO, SD_SCK)) {
Serial.println("SD Card Mount Failed");
}
}
Если проблема остаётся, попробуйте логировать ошибки с помощью SD.errorCode() и SD.errorData() для диагностики.
 

pvvx

Активный участник сообщества
  • Напряжение питания 3.3 В для большинства SD, но некоторые UHS-II могут требовать 1.8 В.
  • Пиковый ток (при инициализации или высокоскоростной записи):
    • До 200–300 мА (особенно для UHS-II и высокоскоростных карт).
 

enjoynering

Well-known member
спасибо, я gpt chat пользоваться умею. кстати он копипастит неправильную инфу. у s3 нету VSPI (пробуйте откомпилировать с таким макросом).

теперь по делу. карточка 2ГБ (года этак 2010), отформатирована в FAT16. пользуюсь microSD card adapter от catalex (схему прикрепил).
 

Вложения

pvvx

Активный участник сообщества
При 3.3 кОм и правильной разводке короткими проводниками (емкость входа пусть будет 20 пф, но скорее всего у этих чипов и ESP она больше)
- Постоянная времени RC-цепи 66 нс.
Заряд/разряд на 99.2% (3В) – 0.33 мкс.
Предельная частота по уровням срабатывания логики ~10МГц.
Так что если проводками соединили через 3.3 кОм - выйдет фигвам
Входная емкость хороших неактивных щупов у осла - 6..16 пФ. К примеру, при 3.3 кОм подтяжках на I2C щуп убивает работу этой шины в 1МГц.
 

pvvx

Активный участник сообщества
я пробовал и 4мгц. не работает
На проводках? -> надо ниже 500 кГц :p А с резисторами в 3.3 кОм -ещё раз в десять ниже.

DeepSeek:
  • Уменьшить частоту SPI (начать с 1 MHz)


Есть ещё такое:
SPIClass hspi(HSPI); // Создаём объект HSPI
если этот-же экземпляр объекта задействуется в другом коде, то будет бардак с пинами...
 

enjoynering

Well-known member
другой (для экрана) я не задаю - использую то, что arduino автоматом в классе прописывает. если я правильно прочитал исходники, там для s3 автоматический FSPI.
 

pvvx

Активный участник сообщества
Ещё на большинстве отладочных плат на SD стоят резисторы подтяжки к + питанию карты.
1747703028648.png
В данной плате - 47 кОм и никаких буферов или последовательных резисторов (но там в чипе есть установки скорости нарастания сигнала для выходов GPIO, т.е. ограничение тока).
А на быстрых чипах, с полным SDIO до 50 MHz часто стоят последовательные резисторы в 22 Ом.
 

pvvx

Активный участник сообщества
Во время инициализации устройства SDIO обычно поддерживают только режим одной шины с тактовой частотой до 400 кГц.
После инициализации хост обычно инициирует переключение на работу с низким напряжением и в то же время увеличивает тактовую частоту до максимальной, которую могут принять как микроконтроллер, так и устройство SDIO.

Вот воткнул SD карту в CH32V307 devboard, и немного скорректировал пример для SD в SDK. Включил DMA и мульти-чтение по 8 секторов (сектор 512 байт, чтение по 4КБ).
Получил такие время исполнения чтений по 1MB:
Код:
SystemClk:144 MHz
ChipID:30700528
Card Type:SDHC V2.0
Card ManufacturerID:18
Card RCA:1
Card Capacity:59638 MB
Card BlockSize:512
SD Card OK
Set DMA mode, SDIO_CK 48 MHz
Start reading 1MB blocks...
0 124536 us
1 123801 us
2 123756 us
3 123684 us
4 123551 us
5 123858 us
6 123480 us
7 123705 us
8 123703 us
9 123860 us
...
Что-то хило - всего 8 Мегабайт в секунду :(
 

pvvx

Активный участник сообщества
SD карта становиться теплой. Понижений напряжения на плате нет, но и нет полной CLK более 48MHz у данного MCU для пониженного напряжения...
 

pvvx

Активный участник сообщества
В итоге такая зависимость от чтения за раз кол-ва секторов:

Read 16MB, buffer 1 sector(s): Average 1402 kbytes per sec
Read 16MB, buffer 2 sector(s): Average 2679 kbytes per sec
Read 16MB, buffer 4 sector(s): Average 5024 kbytes per sec
Read 16MB, buffer 8 sector(s): Average 8141 kbytes per sec
Read 16MB, buffer 16 sector(s): Average 12128 kbytes per sec
Read 16MB, buffer 32 sector(s): Average 15785 kbytes per sec
 

enjoynering

Well-known member
спасибо конечно, но причем здесь CH32V307? вопрос был - ESP32-S3 работа с двумя SPI одновременно Arduino.
 
Сверху Снизу