Библиотека 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 В.
Где используется на сайте
- RFID RC522: схема подключения и скетч
- Радиомодуль nRF24L01+: схема подключения и скетч
- TFT ILI9341: схема подключения и скетч
- Матрица MAX7219: схема подключения и скетч