Библиотека SPI
Быстрая четырёхпроводная шина для карт памяти, дисплеев, радиомодулей и RFID. Обычно работает внутри других библиотек.
SPI — три общих провода (MOSI, MISO, SCK) плюс по одному проводу выбора CS на каждое устройство. На UNO это выводы 11, 12 и 13; CS — любой. Обмен идёт мегабитами в секунду, поэтому на SPI сидят всё, что передаёт много данных: дисплеи, SD-карты, nRF24L01, RC522.
Напрямую SPI трогают редко — библиотеки модулей делают это сами. Знать нужно раскладку выводов, чтобы правильно подключить, и то, что вывод 13 при этом занят под тактовый сигнал вместе со встроенным светодиодом.
Установка и подключение
Ставить ничего не нужно: библиотека входит в среду Arduino и доступна сразу после установки. Достаточно строки подключения в начале скетча.
#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>
const int CS = 10;
void setup() {
Serial.begin(9600);
pinMode(CS, OUTPUT);
digitalWrite(CS, HIGH); // устройство не выбрано
SPI.begin();
}
void loop() {
// прочитать регистр 0x00 у типичного чипа: адрес с битом чтения, потом пустой байт
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
digitalWrite(CS, LOW);
SPI.transfer(0x00 | 0x80); // у многих чипов старший бит — признак чтения
byte value = SPI.transfer(0x00); // отправляем пустышку, получаем ответ
digitalWrite(CS, HIGH);
SPI.endTransaction();
Serial.println(value, HEX);
delay(1000);
}Схема «опустить CS — обменяться — поднять CS» одинакова для любого устройства; отличаются только адреса регистров и режим.
На чём попадаются
Два модуля на одной шине не работают вместе
У каждого свой CS, и в простое он должен быть HIGH. Библиотеки, которые не поднимают CS после обмена, мешают соседям.
На Mega ничего не работает
Там шина на 50, 51, 52, а не на 11, 12, 13. Библиотеки берут правильные выводы сами, но провода надо переставить.
Вывод 10 нужно держать выходом
На AVR вывод SS (10 на UNO), настроенный входом и притянутый к земле, переводит плату в режим ведомого, и шина замолкает.
Модуль на 3,3 В сгорел от UNO
MOSI и SCK с UNO выдают 5 В. nRF24L01 и SD-карты требуют делителей или преобразователя уровней.
Где используется на сайте
- RFID RC522: схема подключения и скетч
- Радиомодуль nRF24L01+: схема подключения и скетч
- TFT ILI9341: схема подключения и скетч
- Матрица MAX7219: схема подключения и скетч