ELECTRONICS

Библиотека SPI

Скачивать не нужно. SPI входит в пакет платы: для UNO, Nano и Mega это пакет Arduino AVR Boards, он ставится вместе со средой. В менеджере библиотек её нет — и искать там не надо.

Быстрая четырёхпроводная шина для карт памяти, дисплеев, радиомодулей и RFID. Обычно работает внутри других библиотек.

SPI — три общих провода (MOSI, MISO, SCK) плюс по одному проводу выбора CS на каждое устройство. На UNO это выводы 11, 12 и 13; CS — любой. Обмен идёт мегабитами в секунду, поэтому на SPI сидят всё, что передаёт много данных: дисплеи, SD-карты, nRF24L01, RC522.

Напрямую SPI трогают редко — библиотеки модулей делают это сами. Знать нужно раскладку выводов, чтобы правильно подключить, и то, что вывод 13 при этом занят под тактовый сигнал вместе со встроенным светодиодом.

Как скачать и установить

Ничего ставить не нужно: достаточно строки подключения в начале скетча. Если среда пишет SPI.h: No such file or directory, проверьте, какая плата выбрана в меню «Инструменты»: у некоторых пакетов плат этой библиотеки нет или она называется иначе.

Строка подключения:

#include <SPI.h>

Создание объекта — обычно до setup():

SPI.begin();                                          // в setup(): выводы 11, 12, 13 переходят под шину
pinMode(CS_PIN, OUTPUT); digitalWrite(CS_PIN, HIGH);   // CS своего устройства — вручную

Методы

Только то, что нужно в обычном скетче. Сигнатуры сверены по заголовкам: ядро AVR 1.8.8.

begin()
Включить шину. Настраивает MOSI, SCK и вывод SS как выходы.
beginTransaction(SPISettings(hz, order, mode))
Начать обмен с настройками: частота, порядок бит (MSBFIRST), режим 0–3. Так разные устройства на одной шине не мешают друг другу.
transfer(uint8_t data)
Отправить байт и одновременно получить байт в ответ.
transfer16(uint16_t data)
То же с двумя байтами.
transfer(void* buf, size_t count)
Обменять буфер целиком; ответ ложится на место отправленного.
endTransaction()
Закончить обмен, отпустить шину.
end()
Выключить шину, вернуть выводы.
usingInterrupt(uint8_t n)
Сообщить, что обмен идёт и из прерывания — библиотека будет их блокировать на время транзакции.

Пример

#include <SPI.h>

// RFID-считыватель RC522: SDA (выбор чипа) — 10, RST — 9,
// SCK — 13, MOSI — 11, MISO — 12, питание 3,3 В
const int CS  = 10;
const int RST = 9;

const byte VERSION_REG = 0x37;   // регистр версии чипа MFRC522

// прочитать регистр: CS вниз, адрес с битом чтения, пустой байт в ответ, CS вверх
byte readRegister(byte reg) {
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  digitalWrite(CS, LOW);
  SPI.transfer(0x80 | (reg << 1));     // у MFRC522 адрес сдвинут на бит, старший бит — чтение
  byte value = SPI.transfer(0x00);    // отправляем пустышку, получаем ответ
  digitalWrite(CS, HIGH);
  SPI.endTransaction();
  return value;
}

void setup() {
  Serial.begin(9600);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);             // в простое модуль не выбран
  pinMode(RST, OUTPUT);
  digitalWrite(RST, HIGH);            // вывести чип из сброса
  delay(50);
  SPI.begin();
}

void loop() {
  byte v = readRegister(VERSION_REG);
  Serial.print("VersionReg = 0x");
  Serial.print(v, HEX);
  // 0x91 и 0x92 — оригинальные чипы, 0x88 и 0xB2 — клоны; 0x00 или 0xFF — нет связи
  Serial.println(v == 0x00 || v == 0xFF ? "  — модуль не отвечает" : "  — модуль на связи");
  delay(1000);
}
Запустить в симулятореСхема с этим скетчем — запустить в браузере

Схема «опустить CS — обменяться — поднять CS» одинакова для любого SPI-устройства; от чипа к чипу меняются только формат адреса и режим. У MFRC522 адрес регистра сдвинут на один бит влево, а старший бит означает чтение — отсюда 0x80 | (reg << 1). Подключение — как на странице RC522; для работы с картами есть библиотека MFRC522.

Монитор порта:

VersionReg = 0x92  — модуль на связи
VersionReg = 0x92  — модуль на связи

На чём попадаются

Два модуля на одной шине не работают вместе

У каждого свой CS, и в простое он должен быть HIGH. Библиотеки, которые не поднимают CS после обмена, мешают соседям.

На Mega ничего не работает

Там шина на 50, 51, 52, а не на 11, 12, 13. Библиотеки берут правильные выводы сами, но провода надо переставить.

Вывод 10 нужно держать выходом

На AVR вывод SS (10 на UNO), настроенный входом и притянутый к земле, переводит плату в режим ведомого, и шина замолкает.

Модуль на 3,3 В сгорел от UNO

MOSI и SCK с UNO выдают 5 В. SD-карте без переходника и модулям без преобразователя уровней нужны делители. nRF24L01+ — исключение: его входы терпят 5 В, но питание — только 3,3 В.

Где используется на сайте

Что дальше