Вам понадобится
- - Arduino;
- - сдвиговый регистр 74HC595;
- - 8 светодиодов;
- - 8 резисторов по 220 Ом.
Инструкция
1
SPI - Serial Peripheral Interface или "Последовательный периферийный интерфейс" - это синхронный протокол передачи данных для сопряжения ведущего устройства (Master) с периферийными устройствами (Slave). Ведущим устройством часто является микроконтроллер. Связь между устройствами осуществляется по четырём проводам, поэтому 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.
На рисунке показаны два варианта подключения устройств по протоколу 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.
На рисунке показаны два варианта подключения устройств по протоколу SPI: независимое и каскадное. При независимом подключении к шине SPI ведущее устройство обращается к каждому ведомому устройству индивидуально. При каскадном - ведомые устройства срабатывают поочерёдно, каскадом.
2
В Arduino шины интерфейса SPI находятся на определённых портах. У каждой платы своё соответствие выводов. Для удобства выводы продублированы и вынесены также на отдельный разъём ICSP (In Circuit Serial Programming, программирование устройства, включённого в цепь, по последовательному протоколу). Обратите внимание, что на разъёме ICSP отсутствует пин выбора ведомого - SS, т.к. подразумевается, что Arduino будет использоваться как ведущее устройство в сети. Но при необходимости вы можете назначить любой цифровой вывод Ардуино в качестве SS.
На рисунке приведено стандартное соответствие выводов шинам SPI для Arduino UNO и Nano.
На рисунке приведено стандартное соответствие выводов шинам SPI для Arduino UNO и Nano.
3
Для Arduino написана специальная библиотека, которая реализует протокол SPI. Подключается она так: в начале программы добавляем #include SPI.h
Чтобы начать работу по протоколу SPI, нужно задать настройки и затем инициализировать протокол с помощью процедуры SPI.beginTransaction(). Можно выполнить это одной инструкцией: SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0)).
Это значит, что мы инициализируем протокол SPI на частоте 14 МГц, передача данных идёт, начиная с MSB (наиболее значимого бита), в режиме "0".
После инициализации выбираем ведомое устройство, переводя соответствующий пин SS в состояние LOW.
Затем передаём ведомому устройству данные командой SPI.transfer().
После передачи возвращаем SS в состояние HIGH.
Работа с протоколом завершается командой SPI.endTransaction(). Желательно минимизировать время выполнения передачи между инструкциями SPI.beginTransaction() и SPI.endTransaction(), чтобы не возникло накладок, если другое устройство попробует инициализировать передачу данных, используя другие настройки.
Чтобы начать работу по протоколу SPI, нужно задать настройки и затем инициализировать протокол с помощью процедуры SPI.beginTransaction(). Можно выполнить это одной инструкцией: SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0)).
Это значит, что мы инициализируем протокол SPI на частоте 14 МГц, передача данных идёт, начиная с MSB (наиболее значимого бита), в режиме "0".
После инициализации выбираем ведомое устройство, переводя соответствующий пин SS в состояние LOW.
Затем передаём ведомому устройству данные командой SPI.transfer().
После передачи возвращаем SS в состояние HIGH.
Работа с протоколом завершается командой SPI.endTransaction(). Желательно минимизировать время выполнения передачи между инструкциями SPI.beginTransaction() и SPI.endTransaction(), чтобы не возникло накладок, если другое устройство попробует инициализировать передачу данных, используя другие настройки.
4
Рассмотрим практическое применение интерфейса SPI. Будем зажигать светодиоды, управляя 8-битным сдвиговым регистром по шине SPI. Подключим к Arduino сдвиговый регистр 74HC595. К каждому из 8-ми выходов подключим по светодиоду (через ограничительный резистор). Схема приводится на рисунке.
5
Напишем такой скетч.
Сначала подключим библиотеку SPI и инициализируем интерфейс SPI. Определим пин 8 как пин выбора ведомого устройства. Очистим сдвиговый регистр, послав в него значение "0". Инициализируем последовательный порт.
Чтобы зажечь определённый светодиод с помощью сдвигового регистра, нужно подать на его вход 8-разрядное число. Например, чтобы загорелся первый светодиод - подаём двоичное число 00000001, чтобы второй - 00000010, чтобы третий - 00000100, и т.д. Эти двоичные числа в переводе в десятичную систему счисления образуют такую последовательность: 1, 2, 4, 8, 16, 32, 64, 128 и являются степенями двойки от 0 до 7.
Соответственно, в цикле loop() по количеству светодиодов делаем пересчёт от 0 до 7. Функция pow(основание, степень) возводит 2 в степень счётчика цикла. Микроконтроллеры не очень точно работают с числами типа "double", поэтому для преобразования результата в целое число используем функцию округления round(). И передаём получившееся число в сдвиговый регистр. Для наглядности в мониторе последовательного порта выводятся значения, которые получаются при этой операции: единичка бежит по разрядам - светодиоды загораются волной.
Сначала подключим библиотеку SPI и инициализируем интерфейс SPI. Определим пин 8 как пин выбора ведомого устройства. Очистим сдвиговый регистр, послав в него значение "0". Инициализируем последовательный порт.
Чтобы зажечь определённый светодиод с помощью сдвигового регистра, нужно подать на его вход 8-разрядное число. Например, чтобы загорелся первый светодиод - подаём двоичное число 00000001, чтобы второй - 00000010, чтобы третий - 00000100, и т.д. Эти двоичные числа в переводе в десятичную систему счисления образуют такую последовательность: 1, 2, 4, 8, 16, 32, 64, 128 и являются степенями двойки от 0 до 7.
Соответственно, в цикле loop() по количеству светодиодов делаем пересчёт от 0 до 7. Функция pow(основание, степень) возводит 2 в степень счётчика цикла. Микроконтроллеры не очень точно работают с числами типа "double", поэтому для преобразования результата в целое число используем функцию округления round(). И передаём получившееся число в сдвиговый регистр. Для наглядности в мониторе последовательного порта выводятся значения, которые получаются при этой операции: единичка бежит по разрядам - светодиоды загораются волной.
6
Светодиоды загораются по очереди, и мы наблюдаем бегущую "волну" из огоньков. Управление светодиодами осуществляется с помощью сдвигового регистра, к которому мы подключились по интерфейсу SPI. В результате для управления 8-ю светодиодами задействованы всего 3 вывода Arduino.
Мы изучили самый простой пример работы Arduino с шиной SPI. Более подробно рассмотрим подключение сдвиговых регистров в отдельной статье.
Мы изучили самый простой пример работы Arduino с шиной SPI. Более подробно рассмотрим подключение сдвиговых регистров в отдельной статье.
Видео по теме
Источники:
- Описание библиотеки SPI на официальном сайте Arduino