SPI: подключение дисплеев, памяти и быстрых датчиков
SPI используют там, где I2C уже медленный: TFT-дисплеи, flash-память, SD-карты, АЦП, радиомодули и быстрые датчики. Разбираем линии MOSI, MISO, SCK, CS, частоту, несколько устройств на одной шине и ошибки подключения.
Почему SPI выбирают для быстрых модулей
SPI часто встречается в проектах, где нужно передавать данные быстрее, чем это удобно делать по I2C. Например, вывести картинку на TFT-дисплей, читать данные с flash-памяти, работать с SD-картой, опрашивать быстрый АЦП или передавать данные через радиомодуль.
Главное отличие SPI - отдельные линии для тактирования, передачи, приема и выбора устройства. Из-за этого проводов больше, чем в I2C, зато обмен получается быстрее и предсказуемее.
SPI хорошо подходит для задач, где важны скорость и стабильный поток данных:
- цветные TFT-дисплеи;
- SD-карты;
- внешняя flash-память;
- радиомодули;
- быстрые датчики;
- АЦП и ЦАП;
- драйверы светодиодных матриц;
- промышленные и измерительные модули.
Если I2C удобен для небольших датчиков и коротких команд, то SPI чаще выбирают там, где данных много.
Четыре основные линии
У SPI обычно есть четыре главные линии: SCK, MOSI, MISO и CS.
SCK - тактовый сигнал. Его формирует ведущий контроллер. По этим импульсам устройства понимают, когда принимать и отдавать биты.
MOSI - линия данных от микроконтроллера к модулю. Например, по ней ESP32 отправляет команды и пиксели на дисплей.
MISO - линия данных от модуля к микроконтроллеру. По ней датчик, память или SD-карта возвращает данные.
CS - выбор устройства. Иногда эту линию называют SS. Когда CS активен, выбранный модуль слушает обмен. Когда CS неактивен, модуль должен молчать и не мешать другим устройствам на шине.
На практике именно CS часто спасает SPI от хаоса: несколько устройств могут использовать общие SCK, MOSI и MISO, но у каждого должен быть свой отдельный CS.
MOSI и MISO часто путают
Названия MOSI и MISO сначала выглядят неудобно, но логика простая. Ведущий обычно микроконтроллер, ведомый - подключенный модуль.
MOSI означает Master Out Slave In. Это выход мастера и вход ведомого. Данные идут от микроконтроллера к устройству.
MISO означает Master In Slave Out. Это вход мастера и выход ведомого. Данные идут от устройства к микроконтроллеру.
Если дисплей только принимает данные и ничего не возвращает, линия MISO может не использоваться. Поэтому у некоторых TFT-модулей есть SCK, MOSI, CS, DC, RST, но нет полноценного MISO.
Если перепутать MOSI и MISO, устройство обычно просто не отвечает или не показывает картинку.
CS: отдельная линия для каждого устройства
SPI позволяет подключить несколько устройств к одной шине. Но для этого у каждого устройства должна быть своя линия CS.
Например, к ESP32 можно подключить TFT-дисплей, SD-карту и внешний АЦП. Линии SCK и MOSI могут быть общими. MISO тоже может быть общей, если устройства корректно освобождают ее, когда не выбраны. А вот CS у каждого должен быть отдельный.
Логика такая: перед обменом контроллер опускает CS нужного устройства, выполняет передачу, затем возвращает CS обратно. Остальные устройства в этот момент не должны участвовать в обмене.
Если два CS случайно активны одновременно, несколько модулей могут начать отвечать на одной линии MISO. В результате данные будут повреждены или шина начнет работать непредсказуемо.
TFT-дисплей по SPI
Цветные TFT-дисплеи часто подключаются по SPI. Это удобно: не нужно много параллельных линий, как у старых дисплейных интерфейсов, но скорость выше, чем у I2C.
У SPI-дисплея кроме стандартных линий часто есть дополнительные выводы. DC или A0 сообщает дисплею, что сейчас передается: команда или данные. RST сбрасывает контроллер дисплея. BL управляет подсветкой.
Для маленьких экранов SPI обычно достаточно. Но если дисплей большой, а изображение нужно обновлять часто, скорость шины становится важной. Чем выше разрешение и чем чаще обновление, тем больше данных нужно передавать.
Именно поэтому один и тот же дисплей может нормально показывать статичное меню, но тормозить при попытке рисовать сложную анимацию.
SD-карта и SPI
SD-карты могут работать в SPI-режиме. Это удобно для микроконтроллеров: можно сохранять логи, фотографии, настройки, измерения и файлы без сложного интерфейса.
Но SD-карта обычно требовательнее к питанию и качеству соединений, чем простой датчик. При записи она может потреблять заметный ток. Если питание слабое, файлы могут повреждаться, запись будет срываться, а модуль начнет пропадать.
Еще один момент - уровни сигнала. Многие SD-карты работают с логикой 3.3 В. Если проект на Arduino Uno с 5 В логикой, нужен модуль с согласованием уровней. Если проект на ESP32, уровни обычно ближе к нужным, но питание и разводку все равно нужно проверить.
SD-карта хорошо подходит для логов и снимков, но не любит внезапное отключение питания во время записи.
Частота SPI: быстрее не всегда лучше
SPI может работать на высокой скорости, но это не значит, что всегда нужно ставить максимальную частоту. На коротких дорожках платы высокая скорость обычно работает нормально. На длинных проводах, макетной плате или слабых соединениях начинаются искажения фронтов, наводки и случайные ошибки.
Если модуль не отвечает или работает нестабильно, полезно сначала снизить частоту SPI. Иногда дисплей, память или датчик начинают работать сразу, как только скорость уменьшается.
Частота зависит от нескольких вещей: возможностей микроконтроллера, модуля, длины проводов, качества земли, уровня сигнала и библиотеки.
В реальном проекте лучше выбрать не самую высокую скорость, а ту, на которой устройство работает стабильно.
SPI на макетной плате
На макетной плате SPI может вести себя хуже, чем ожидается. Причина не в самом интерфейсе, а в длинных перемычках, слабых контактах и паразитных емкостях.
Для медленного датчика это может быть незаметно. Для TFT-дисплея или SD-карты проблемы появляются быстрее: белый экран, случайные пиксели, ошибки чтения, зависание инициализации.
Если SPI-модуль не работает на макетке, стоит попробовать:
- укоротить провода;
- снизить частоту;
- соединить землю надежнее;
- убрать силовые провода подальше;
- поставить модуль ближе к контроллеру;
- проверить питание под нагрузкой.
Иногда модуль "оживает" просто после замены длинных Dupont-проводов на короткие.
ESP32 и аппаратные SPI-шины
У ESP32 есть аппаратные SPI-контроллеры. Это значит, что обмен может выполняться эффективнее, чем ручное переключение пинов в программе.
В Arduino-среде для ESP32 часто используют стандартные SPI-пины или задают свои. Но не каждый пин одинаково удобен. Часть пинов может быть занята flash-памятью, загрузочными режимами или особенностями платы.
Для простого проекта лучше начинать с рекомендованных пинов конкретной ESP32-платы. Если пины меняются вручную, нужно убедиться, что библиотека поддерживает такую настройку.
SPI особенно полезен на ESP32 для дисплеев, потому что можно получить нормальную скорость обновления интерфейса, если не завышать разрешение и правильно настроить библиотеку.
Пример инициализации SPI-дисплея
У разных дисплеев разные библиотеки и пины, поэтому универсального короткого кода для всех модулей нет. Но общий принцип обычно похож: указываются CS, DC, RST и используется SPI.
Пример ниже показывает идею для TFT-дисплея с библиотекой Adafruit_ST7735.
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
const int TFT_CS = 5;
const int TFT_DC = 2;
const int TFT_RST = 4;
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
void setup() {
tft.initR(INITR_BLACKTAB);
tft.fillScreen(ST77XX_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ST77XX_WHITE);
tft.setTextSize(2);
tft.print("SPI");
}
void loop() {
}
Если экран остается белым или черным, сначала проверяют питание, CS, DC, RST, тип контроллера дисплея и выбранную инициализацию.
Когда MISO можно не подключать
Не все SPI-проекты требуют обратной передачи данных. Например, если микроконтроллер только отправляет картинку на дисплей, линия MISO может быть не нужна. Дисплей получает команды и данные, но ничего не возвращает.
Это нормально, если библиотека и модуль не требуют чтения из дисплея. Но для SD-карты, flash-памяти, АЦП или датчика MISO обязателен, потому что микроконтроллер должен читать ответ.
Поэтому перед подключением полезно понять направление данных. Если устройство только принимает, достаточно SCK, MOSI, CS и дополнительных служебных линий. Если устройство должно отдавать данные, нужна MISO.
Типичные ошибки SPI
| Симптом | Возможная причина |
|---|---|
| Дисплей белый | Не тот CS, DC, RST, питание или тип контроллера |
| SD-карта не определяется | Питание, MISO/MOSI, CS, плохой контакт или уровень сигнала |
| Данные читаются с ошибками | Слишком высокая частота или длинные провода |
| Работает один модуль, но не два | Конфликт CS или устройство не освобождает MISO |
| ESP32 не загружается | Использован неподходящий загрузочный пин |
| Картинка мерцает | Проблемы питания или слишком частое обновление |
SPI или I2C: что выбрать
Если модуль доступен и в I2C, и в SPI-версии, выбор зависит от задачи. Для простого датчика температуры, часов реального времени или маленького OLED-дисплея I2C часто удобнее. Проводов меньше, адреса позволяют подключить несколько устройств, скорость обычно достаточная.
Для цветного дисплея, памяти, SD-карты, быстрого датчика или потока данных лучше подходит SPI. Проводов больше, зато обмен быстрее и проще контролировать по CS.
Коротко: I2C хорош для компактной шины с несколькими медленными устройствами. SPI хорош для скорости и больших объемов данных.
Практический вывод
SPI не сложный, если не путать его с I2C. Здесь нет адресов как главной идеи. Вместо этого есть отдельная линия выбора устройства - CS. Здесь больше проводов, но выше скорость. Здесь длинные провода и макетные соединения быстрее начинают мешать работе.
Для надежного SPI-подключения важны короткие линии, стабильное питание, правильные уровни сигнала, отдельный CS для каждого модуля и разумная частота.
Если устройство не работает, не стоит сразу переписывать программу. Часто проблема находится в простых вещах: MOSI и MISO перепутаны, CS не тот, дисплей требует другой DC/RST, SD-карте не хватает питания, а провода слишком длинные для выбранной скорости.

Комментарии (0)