
SPI (Serial Peripheral Interface) — высокоскоростной синхронный протокол передачи данных для микроконтроллеров, датчиков, SD-карт и дисплеев. Разбираем принцип работы, режимы, примеры кода для Arduino.

SPI (Serial Peripheral Interface) — это высокоскоростной синхронный протокол передачи данных, широко используемый в микроконтроллерах, датчиках, SD-картах и дисплеях. В отличие от UART, SPI работает с тактовым сигналом, что обеспечивает быстрый и надёжный обмен данными.
В этой статье мы разберём:
SPI — это синхронный последовательный интерфейс, разработанный для быстрого обмена данными между микросхемами. Он используется в:
Главный недостаток: Требует больше линий, чем I2C или UART. Обычно требуется 7-8 проводов для подключения SPI устройств, из них 2-3 питание.
SPI использует 4 основные линии:
| Линия | Назначение |
|---|---|
| SCK | Тактовый сигнал (синхронизация) |
| MOSI | Данные от мастера к ведомому (Master Out Slave In) |
| MISO | Данные от ведомого к мастеру (Master In Slave Out) |
| SS/CS | Выбор ведомого устройства (Slave Select/Chip Select) |

1. Мастер (например, Arduino) генерирует тактовый сигнал SCK.
2. Данные передаются по MOSI и принимаются по MISO одновременно (полный дуплекс).
3. SS (Slave Select) переводится в LOW, чтобы активировать нужное устройство.
SPI поддерживает 4 режима передачи, определяемые фазами тактового сигнала:
| Режим | CPOL (Polarity) | CPHA (Phase) | Описание |
|---|---|---|---|
| 0 | 0 | 0 | Такт начинается с LOW, данные читаются по фронту |
| 1 | 0 | 1 | Такт начинается с LOW, данные читаются по срезу |
| 2 | 1 | 0 | Такт начинается с HIGH, данные читаются по фронту |
| 3 | 1 | 1 | Такт начинается с HIGH, данные читаются по срезу |
Важно: Устройства должны использовать одинаковый режим SPI!
В Arduino Uno (ATmega328P) аппаратный SPI выведен на контакты:
Пример чтения/записи в EEPROM (25LC512):
```cpp
#include <SPI.h>
void setup() {
SPI.begin(); // Инициализация SPI
pinMode(10, OUTPUT); // SS (Slave Select)
digitalWrite(10, HIGH); // Деактивировать EEPROM
}
void writeEEPROM(uint16_t addr, uint8_t data) {
digitalWrite(10, LOW); // Активировать EEPROM
SPI.transfer(0x06); // Команда "Write Enable"
digitalWrite(10, HIGH);
digitalWrite(10, LOW);
SPI.transfer(0x02); // Команда записи
SPI.transfer(addr >> 8); // Старший байт адреса
SPI.transfer(addr & 0xFF); // Младший байт адреса
SPI.transfer(data); // Данные
digitalWrite(10, HIGH);
}
uint8_t readEEPROM(uint16_t addr) {
digitalWrite(10, LOW);
SPI.transfer(0x03); // Команда чтения
SPI.transfer(addr >> 8);
SPI.transfer(addr & 0xFF);
uint8_t data = SPI.transfer(0x00); // Чтение данных
digitalWrite(10, HIGH);
return data;
}
void loop() {
writeEEPROM(0x0001, 0xAB); // Запись байта 0xAB по адресу 0x0001
uint8_t value = readEEPROM(0x0001); // Чтение
delay(1000);
}
`
Если аппаратного SPI недостаточно (например, нужно несколько шин), можно реализовать SPI вручную:
```cpp
#define SCK_PIN 13
#define MOSI_PIN 11
#define MISO_PIN 12
#define SS_PIN 10
void setup() {
pinMode(SCK_PIN, OUTPUT);
pinMode(MOSI_PIN, OUTPUT);
pinMode(MISO_PIN, INPUT);
pinMode(SS_PIN, OUTPUT);
digitalWrite(SS_PIN, HIGH);
}
uint8_t softSPITransfer(uint8_t data) {
uint8_t received = 0;
for (int i = 0; i < 8; i++) {
digitalWrite(MOSI_PIN, (data & 0x80) ? HIGH : LOW);
digitalWrite(SCK_PIN, HIGH);
received <<= 1;
if (digitalRead(MISO_PIN)) received |= 1;
digitalWrite(SCK_PIN, LOW);
data <<= 1;
}
return received;
}
`
| Параметр | SPI | I2C | UART |
|---|---|---|---|
| Скорость | До 50 МГц | До 3.4 МГц | До 1 МГц |
| Линии | 4 (SCK, MOSI, MISO, SS) | 2 (SDA, SCL) | 2 (TX, RX) |
| Тип передачи | Полный дуплекс | Полудуплекс | Полудуплекс |
| Синхронизация | Тактовый сигнал (SCK) | Тактовый сигнал (SCL) | Асинхронный |
| Подключение устройств | До 10+ (с отдельными SS) | До 128 (по адресам) | 1:1 (без преобразователей) |
Когда выбирать SPI?
Проверьте:
Решения:
SPI_CLOCK_DIV2 на SPI_CLOCK_DIV8).Каждое ведомое устройство должно иметь отдельный SS-сигнал!
SPI — мощный интерфейс для высокоскоростной передачи данных между микросхемами. Он идеален для работы с памятью, датчиками и дисплеями в Arduino-проектах.
Главные выводы:
Теперь вы знаете, как работает SPI, и сможете применять его в своих устройствах!
P.S. Попробуйте подключить SPI-модуль (например, RFID RC522 или SD-карту) к Arduino — это отличный способ закрепить знания.
Подключите школу к пилоту. Генерируйте КМЖ за 2 минуты, ведите CodeStudio уроки, заказывайте оборудование — всё в одном месте.