Рейтинг@Mail.ru
Интерфейс SPI
Интерфейс SPI

Интерфейс SPI и Arduino

Изучаем интерфейс SPI и подключаем к Arduino сдвиговый регистр, к которому мы будем обращаться по этому протоколу для управления светодиодами.

Инструкция по работе Arduino с интерфейсом SPI

Вам понадобится

  • Arduino;
  • сдвиговый регистр 74HC595;
  • 8 светодиодов;
  • 8 резисторов по 220 Ом;
  • соединительные провода.

1Описание последовательного интерфейса SPI

SPI – Serial Peripheral Interface или «Последовательный периферийный интерфейс» – это синхронный протокол передачи данных для сопряжения ведущего устройства (Master) с периферийными устройствами (Slave). Ведущим устройством часто является микроконтроллер. Связь между устройствами осуществляется по четырём проводам, поэтому SPI иногда называют «четырёхпроводной интерфейс». Вот эти шины:

НазваниеНазначение шины SPI
MOSI (Master Out Slave In)линия передачи данных от ведущего к ведомым устройствам;
MISO (Master In Slave Out)линия передачи от ведомого к ведущему устройству;
SCLK (Serial Clock)тактовые импульсы синхронизации, генерируемые ведущим устройством;
SS (Slave Select)линия выбора ведомого устройства; когда на линии логический "0", ведомое устройство «понимает», что сейчас обращаются к нему.

Существует четыре режима передачи данных (SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3), обусловленные сочетанием полярности тактовых импульсов (работаем по уровню HIGH или LOW), Clock Polarity, CPOL, и фазой тактовых импульсов (синхронизация по переднему или заднему фронту тактового импульса), Clock Phase, CPHA.

РежимПолярность тактовых импульсов (CPOL)Фаза тактовых импульсов (CPHA)
SPI_MODE000
SPI_MODE101
SPI_MODE210
SPI_MODE311

Рисунок поясняет данную таблицу.

Четыре режима работы интерфейса SPI
Четыре режима работы интерфейса SPI

Интерфейс SPI предусматривает несколько вариантов подключения ведомых устройств: независимое и каскадное. При независимом подключении к шине SPI ведущее устройство обращается к каждому ведомому устройству индивидуально. При каскадном подключении ведомые устройства срабатывают поочерёдно, как бы каскадом.

Виды подключения устройств: независимое и каскадное
Виды подключения устройств для работы по интерфейсу SPI: независимое и каскадное

2Реализация интерфейса SPI на платах семейства Arduino

В Arduino шины интерфейса SPI находятся на определённых портах. У каждой платы своё соответствие выводов. Для удобства выводы продублированы и вынесены также на отдельный разъём ICSP (In Circuit Serial Programming, программирование устройства, включённого в цепь, по последовательному протоколу). Обратите внимание, что на разъёме ICSP отсутствует пин выбора ведомого – SS, т.к. подразумевается, что Arduino будет использоваться как ведущее устройство в сети. Но при необходимости вы можете назначить любой цифровой вывод Ардуино в качестве SS.

На рисунке приведено стандартное соответствие выводов шинам SPI для Arduino UNO и Nano.

Реализация интерфейса SPI на платах Arduino UNO и Arduino Nano
Реализация интерфейса SPI на платах Arduino UNO и Arduino Nano

3Библиотека для работы с интерфейсом SPI

Для Arduino написана специальная библиотека, которая реализует протокол SPI. Подключается она так: в начале программы добавляем #include SPI.h.

Чтобы начать работу по протоколу SPI, нужно задать настройки и затем инициализировать протокол с помощью процедуры SPI.beginTransaction(). Можно выполнить это одной инструкцией: SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0))

Это значит, что мы инициализируем протокол SPI на частоте 14 МГц, передача данных идёт, начиная с MSB (наиболее значимого бита), в режиме SPI_MODE0.

После инициализации выбираем ведомое устройство, переводя соответствующий пин SS в состояние LOW.

Затем передаём ведомому устройству данные командой SPI.transfer().

После передачи возвращаем SS в состояние HIGH.

Временная диаграмма работы интерфейса SPI
Временная диаграмма работы интерфейса SPI

Работа с протоколом завершается командой SPI.endTransaction().

Желательно минимизировать время выполнения передачи между инструкциями SPI.beginTransaction() и SPI.endTransaction(), чтобы не возникло накладок, если другое устройство попробует инициализировать передачу данных, используя другие настройки.

4Подключение сдвигового регистра к Arduino

Рассмотрим практическое применение интерфейса SPI. Будем зажигать светодиоды, управляя 8-битным сдвиговым регистром по шине SPI. Подключим к Arduino сдвиговый регистр 74HC595. К каждому из 8-ми выходов регистра через ограничительный резистор подключим по светодиоду номиналом 220 Ом. Схема приводится на рисунке.

Схема подключения сдвигового регистра 74HC595 к Arduino
Схема подключения сдвигового регистра 74HC595 к Arduino

5Скетч для управления сдвиговым регистром по интерфейсу SPI

Напишем такой скетч.

#include <SPI.h>

const int pinSelect = 8; // пин выбора регистра

void setup() {
  SPI.begin(); // инициализация интерфейса SPI
  pinMode(pinSelect, OUTPUT); // 
  digitalWrite(pinSelect, LOW); // выбор ведомого устройств (регистра)
  SPI.transfer(0); // очищаем содержимое регистра
  digitalWrite(pinSelect, HIGH); // конец передачи
  Serial.begin(9600);
}

void loop() {
  for (int i=0; i<8; i++) {    
    double L = pow(2, i); // вычисляем активный светодиод
    int leds = round(L); // округляем число до целого
    digitalWrite(pinSelect, LOW); // выбор регистра сдвига
    SPI.transfer(leds); // передаём значение в сдвиговый регистр
    digitalWrite(pinSelect, HIGH); // конец передачи
    Serial.println(leds, BIN); // вывод в двоичном представлении
    delay(125); // задержка 125 мс
  }
  Serial.println("--------");
}

Сначала подключим библиотеку SPI и инициализируем интерфейс SPI. Определим пин 8 как пин выбора ведомого устройства SS. Очистим сдвиговый регистр, послав в него значение "0". Инициализируем последовательный порт.

Чтобы зажечь определённый светодиод с помощью сдвигового регистра, нужно подать на его вход 8-разрядное число. Например, чтобы загорелся первый светодиод – подаём двоичное число 00000001, чтобы второй – 00000010, чтобы третий – 00000100, и т.д. Эти двоичные числа при переводе в десятичную систему счисления образуют такую последовательность: 1, 2, 4, 8, 16, 32, 64, 128 и являются степенями двойки от 0 до 7.

Соответственно, в цикле loop() по количеству светодиодов делаем пересчёт от 0 до 7. Функция pow(основание, степень) возводит 2 в степень счётчика цикла. Микроконтроллеры не очень точно работают с числами типа "double", поэтому для преобразования результата в целое число используем функцию округления round(). И передаём получившееся число в сдвиговый регистр. Для наглядности в монитор последовательного порта выводятся значения, которые получаются при этой операции: единичка «бежит» по разрядам – светодиоды загораются волной.

Числа, посылаемые в сдвиговый регистр 74HC595
Числа, посылаемые в сдвиговый регистр 74HC595

6«Бегущая волна» из светодиодов

Светодиоды загораются по очереди, и мы наблюдаем бегущую «волну» из огоньков. Управление светодиодами осуществляется с помощью сдвигового регистра, к которому мы подключились по интерфейсу SPI. В результате для управления 8-ю светодиодами задействованы всего 3 вывода Arduino. Если бы мы подключали светодиоды напрямую к цифровым портам Arduino, нам бы потребовалось для каждого светодиода использовать отдельный порт.

Мы изучили самый простой пример работы Arduino с шиной SPI. Более подробно рассмотрим работу нескольких сдвиговых регистров при независимом и каскадном подключениях в отдельной статье.

Последнее изменениеВторник, 05 Январь 2016 16:24
(6 голосов)
Прочитано 10054 раз

Поделиться

Оставить комментарий

Убедитесь, что вы вводите (*) необходимую информацию, где нужно
HTML-коды запрещены