Если в примере кода под ESP32 встречаются константы VSPI или HSPI, речь идёт о двух аппаратных интерфейсах SPI микроконтроллера, которые различаются внутренним контроллером и выводами по умолчанию. Подключить дисплей, SD-карту или радиомодуль можно к любому из них, но перепутанные пины — самая частая причина, почему устройство «не видит» периферию при вроде бы правильной схеме.

В этой статье разберём, что скрывается за аббревиатурами, на какие GPIO выведены эти шины в типовых модулях, как задать интерфейс в коде и как проверить, что обмен данными действительно идёт. Материал ориентирован на тех, кто собирает проекты на ESP32 в среде Arduino IDE или аналогичных фреймворках.

Что такое SPI и зачем нужны VSPI и HSPI

SPI (Serial Peripheral Interface) — синхронный последовательный интерфейс для связи микроконтроллера с периферией: дисплеями, картами памяти, датчиками, АЦП, радиомодулями. Обмен идёт по четырём линиям: тактовый сигнал SCK, данные к ведомому MOSI, данные от ведомого MISO и выбор устройства CS (он же SS), который у каждой микросхемы на шине свой.

В классическом ESP32 есть несколько SPI-контроллеров. Часть из них задействована под внутреннюю flash-память и пользователю недоступна, а два свободных получили условные имена HSPI и VSPI. Буквы исторически связаны с внутренними блоками чипа (Host и «Versatile»), но для практики важно другое: это два независимых аппаратных контроллера, каждый со своими выводами по умолчанию.

Наличие двух шин удобно, когда нужно одновременно обслуживать, например, дисплей и SD-карту с разными настройками скорости и режима. Разведя их по разным контроллерам, вы избегаете конфликтов и постоянного переключения параметров шины.

💡

VSPI и HSPI — это два независимых аппаратных SPI-контроллера ESP32. Разница между ними — в выводах по умолчанию и внутренней реализации, а не в «качестве» интерфейса.

Распиновка VSPI и HSPI в типовых модулях

Для классического ESP32 (модули семейства WROOM, платы DevKit) выводы по умолчанию принято указывать так, как показано в таблице ниже. Это распространённая раскладка, но перед пайкой обязательно сверьтесь со схемой конкретной платы: некоторые производители переназначают выводы или занимают часть GPIO под встроенную периферию.

СигналVSPI (по умолчанию)HSPI (по умолчанию)Назначение
SCKGPIO 18GPIO 14Тактовый сигнал
MISOGPIO 19GPIO 12Данные от устройства
MOSIGPIO 23GPIO 13Данные к устройству
CS/SSGPIO 5GPIO 15Выбор устройства

Линию CS можно вывести практически на любой свободный GPIO — главное, чтобы у каждого устройства на шине был свой сигнал выбора. А вот SCK, MOSI и MISO у всех ведомых на одной шине общие.

⚠️ Внимание: часть GPIO у ESP32 имеет особые состояния при загрузке (strapping-пины). Например, GPIO 12 влияет на выбор напряжения flash-памяти, и подтяжка его к «1» при старте может помешать загрузке. Перед использованием таких выводов под периферию проверьте их поведение в документации на ваш модуль.

Как выбрать и настроить интерфейс в коде

В Arduino-фреймворке для ESP32 выбор шины выполняется при создании объекта SPIClass. Можно использовать готовые объекты или создать свой с явным указанием контроллера и пинов:

#include <SPI.h>

// Явное создание объекта на контроллере HSPI

SPIClass hspi(HSPI);

void setup() {

// Инициализация с указанием пинов: SCK, MISO, MOSI, CS

hspi.begin(14, 12, 13, 15);

// Далее работа через hspi.beginTransaction(...) и т.д.

}

Многие библиотеки (для дисплеев, SD-карт, радиомодулей) позволяют передать ссылку на объект SPI в конструктор или метод begin. Если библиотека по умолчанию использует SPI, а ваше устройство подключено к HSPI, передача правильного объекта — единственное, что нужно изменить.

☑️ Проверка подключения SPI-устройства

Выполнено: 0 / 6

Отдельно обратите внимание на частоту шины. Начинайте с умеренных значений и повышайте её только после того, как обмен стабильно заработал: слишком высокая частота на длинных проводах — типичный источник «мусора» в данных.

📊 Для чего вы используете SPI на ESP32?
TFT/OLED-дисплей
SD-карта и накопители
Радиомодуль (nRF24, LoRa)
Датчики и АЦП

Чем VSPI и HSPI отличаются на практике

Функционально оба контроллера реализуют один и тот же протокол SPI, поддерживают режимы 0–3 и широкий диапазон частот. Практические отличия сводятся к следующему:

  • 🔌 Выводы по умолчанию — у VSPI и HSPI они разные, поэтому схема подключения зависит от выбранной шины.
  • 📚 Поддержка в библиотеках — многие библиотеки по умолчанию работают через VSPI (объект SPI), а HSPI приходится указывать явно.
  • ⚙️ Занятость пинов — на конкретной плате часть выводов одной из шин может быть использована под встроенную периферию, и тогда выбор диктуется схемой платы.
  • 🧩 Одновременная работа — два контроллера позволяют вести обмен с двумя группами устройств независимо, с разными настройками.

Частый вопрос: «какая шина быстрее?». Достоверного преимущества одного контроллера над другим в обычных задачах нет — скорость определяется заданной частотой и качеством монтажа, а не именем шины. Выбирайте по свободным пинам и совместимости с библиотекой.

Почему в ESP32 вообще несколько SPI-контроллеров

В чипе ESP32 аппаратных SPI-блоков больше двух, но часть из них обслуживает подключение внешней flash-памяти и псевдостатического ОЗУ. Эти контроллеры заняты системой, и использовать их для пользовательской периферии нельзя. Свободными остаются два блока, которые в среде Arduino получили имена HSPI и VSPI. В других чипах семейства (ESP32-S2, S3, C3) количество и нумерация доступных SPI-контроллеров отличаются, поэтому код с жёстко заданными пинами не всегда переносим между платформами без правок.

Типичные ошибки при работе с VSPI и HSPI

Большинство проблем с SPI на ESP32 связаны не с самим протоколом, а с подключением и инициализацией. Вот что стоит проверить в первую очередь:

  • 🔀 Перепутаны MOSI и MISO — классическая ошибка: сигналы должны идти «крест-накрест» относительно ведомого устройства, и легко запутаться в обозначениях на плате дисплея.
  • 📍 Устройство на одной шине, код — на другой — дисплей подключён к пинам HSPI, а библиотека по умолчанию работает с VSPI.
  • Несогласованные уровни — ESP32 работает с логикой 3,3 В; устройства с 5-вольтовыми сигналами требуют согласования уровней.
  • 📏 Слишком длинные провода — на высоких частотах длинные неэкранированные линии дают сбои; сократите проводники или снизьте частоту.
  • 🚫 Конфликт CS — два устройства с одним сигналом выбора отвечают одновременно и «засоряют» линию MISO.
⚠️ Внимание: не подключайте 5-вольтовые сигналы напрямую к входам ESP32 — выводы не толерантны к 5 В, и это может вывести порт или весь чип из строя. Используйте согласователи уровней или делители напряжения там, где это допустимо по схеме.
💡

Если устройство «молчит», временно снизьте частоту SPI до минимальной и проверьте обмен логическим анализатором или хотя бы контрольным светодиодом на линии CS. Работа на низкой частоте отсекает проблемы монтажа и оставляет только логику подключения.

Диагностика: как убедиться, что шина работает

Простейшая проверка — программная. Отправьте устройству команду чтения идентификатора (у большинства микросхем — дисплеев, радиомодулей, флешек — есть регистр ID) и сравните ответ с ожидаемым из документации. Нулевой или «все единицы» ответ почти всегда означает проблему с подключением, а не с чипом.

Дальше помогает аппаратная диагностика. Логический анализатор на линиях SCK, MOSI и CS за пару минут показывает, идут ли вообще тактовые импульсы и на той ли шине. Если тактов нет — проблема в инициализации кода; если такты есть, а ответа нет — проверяйте CS, питание и распиновку ведомого.

Не забудьте про общий провод: отсутствие соединения GND между микроконтроллером и периферией — банальная, но регулярно встречающаяся причина «нерабочей» шины, особенно при питании устройств от разных источников.

💡

Диагностику SPI начинайте с простого: правильная шина в коде → правильные пины → общий GND → согласованные уровни → снижение частоты. Логический анализатор позволяет проверить каждый шаг фактически, а не «на глаз».

Особенности других чипов семейства ESP32

Имена VSPI и HSPI относятся прежде всего к классическому ESP32. У более новых чипов — ESP32-S2, ESP32-S3, ESP32-C3 — набор SPI-контроллеров и их обозначения в фреймворке отличаются: там обычно используются имена вида FSPI/HSPI или числовые идентификаторы, а распиновка по умолчанию — иная.

Поэтому при переносе проекта между платами не копируйте код инициализации SPI вслепую. Откройте документацию на конкретный чип и плату, уточните доступные контроллеры и назначьте пины явно через begin(SCK, MISO, MOSI, CS) — так код останется переносимым и предсказуемым.

Если вы работаете в ESP-IDF, а не в Arduino, выбор контроллера задаётся иначе — через структуру конфигурации шины с указанием хоста (SPI2_HOST, SPI3_HOST и т. п.). Принцип тот же: один хост — одна шина со своими пинами и настройками.

Часто задаваемые вопросы

Что означают буквы V и H в названиях VSPI и HSPI?

Это исторические обозначения внутренних блоков чипа ESP32: H — от Host, V — от «Versatile». Для практического применения расшифровка не важна: это просто имена двух независимых аппаратных SPI-контроллеров с разными выводами по умолчанию.

Можно ли поменять пины VSPI или HSPI на другие GPIO?

Да, в Arduino-фреймворке пины задаются при вызове begin(SCK, MISO, MOSI, CS), и сигналы можно переназначить на многие свободные GPIO. Однако не все выводы одинаково подходят: часть из них имеет особые функции при загрузке или ограничена на вход. Сверяйтесь с документацией на ваш модуль перед переназначением.

Можно ли подключить несколько устройств к одной шине SPI?

Можно: линии SCK, MOSI и MISO у всех устройств общие, а выбор конкретного устройства выполняется отдельным сигналом CS для каждого. Убедитесь, что устройства не конфликтуют по режимам SPI и что неактивные ведомые корректно освобождают линию MISO.

Почему дисплей работает на VSPI, но не работает на HSPI при той же схеме?

Наиболее вероятные причины: библиотека по умолчанию обращается к объекту VSPI и ей не передали объект HSPI, либо пины подключения не соответствуют выбранной шине. Также проверьте, не заняты ли выводы HSPI на вашей плате встроенной периферией и не влияет ли выбранный GPIO на процесс загрузки.

Чем SPI отличается от I2C и когда что выбрать?

SPI быстрее и проще по протоколу, но требует больше проводов и отдельной линии выбора для каждого устройства. I2C использует всего две линии и адресацию, но медленнее и чувствительнее к длине шины. Для дисплеев и карт памяти обычно выбирают SPI, для датчиков с малым объёмом данных — I2C.