Соединение нескольких устройств через SPI
SPI: Master&Slaves. Источник картинки
Довольно часто при создании различных самоделок на основе микроконтроллера Arduino разработчики как бы «приделывают к телу руки и ноги», то есть присоединяют некую периферию, которая управляется с центрального микроконтроллера. Однако иногда возникают такие ситуации, когда необходимо соединить «два мозга друг с другом», то есть соединить два микроконтроллерa. Об этом мы и поговорим в этой статье.
Для коммуникации существует несколько вариантов, и один из них называется SPI.
SPI (англ. Serial Peripheral Interface, SPI bus — последовательный периферийный интерфейс, шина SPI) — последовательный синхронный стандарт передачи данных в режиме полного дуплекса, предназначенный для обеспечения простого и недорогого высокоскоростного сопряжения микроконтроллеров и периферии. SPI также иногда называют четырёхпроводным (англ. four-wire) интерфейсом.
Автор: Cburnett, Источник картинки
В отличие от стандартного последовательного порта (англ. standard serial port), SPI — это синхронный интерфейс, в котором любая передача синхронизирована с общим тактовым сигналом, генерируемым ведущим устройством (процессором). Принимающая (ведомая) периферия синхронизирует получение битовой последовательности с тактовым сигналом. К одному последовательному периферийному интерфейсу ведущего устройства-микросхемы может присоединяться несколько микросхем. Ведущее устройство выбирает ведомое для передачи, активируя сигнал «выбор кристалла» (англ. chip select) на ведомой микросхеме.
Периферия, которая не была выбрана процессором, не будет принимать участия в передаче по SPI.
Интерфейс
В SPI используются четыре цифровых сигнала:
- MOSI — выход ведущего, вход ведомого (англ. Master Out Slave In). Служит для передачи данных от ведущего устройства ведомому.
- MISO — вход ведущего, выход ведомого (англ. Master In Slave Out). Служит для передачи данных от ведомого устройства ведущему.
- SCLK или SCK — последовательный тактовый сигнал (англ. Serial Clock). Служит для передачи тактового сигнала для ведомых устройств.
- CS или SS — выбор микросхемы, выбор ведомого (англ. Chip Select, Slave Select).
Имена портов интерфейса SPI могут различаться в зависимости от производителя аппаратных средств, при этом возможны такие варианты:
- MISO: SOMI, SDO (на устройстве), DO, DON, SO, MRSR.
- MOSI: SIMO, SDI (на устройстве), DI, DIN, SI, MTST.
- SCLK: SCK, CLK, SPC (SPI serial port clock).
- SS: nCS, CS, CSB, CSN, NSS, nSS, STE, SYNC.
Синхронизация в SPI
Частота следования битовых интервалов в линиях передачи данных определяется синхросигналом SCK, который генерирует ведущее устройство, ведомые устройства используют синхросигнал для определения моментов изменения битов на линии данных, при этом ведомые устройства никак не могут влиять на частоту следования битовых интервалов.
Как в ведущем устройстве, так и в ведомом устройстве есть счётчик импульсов синхронизации (битов). Счётчик в ведомом устройстве позволяет последнему определить момент окончания передачи пакета. Счётчик сбрасывается при выключении подсистемы SPI, такая возможность всегда имеется в ведущем устройстве. В ведомом устройстве счётчик обычно сбрасывается деактивацией интерфейсного сигнала SS.
Так как действия ведущего и ведомого устройства тактируются одним и тем же сигналом, то к стабильности этого сигнала не предъявляется никаких специальных требований, за исключением ограничения на длительность полупериодов, которая определяется максимальной рабочей частотой более медленного устройства. Это позволяет использовать SPI в системах с низкостабильной тактовой частотой, а также облегчает программную эмуляцию ведущего устройства.
Приём и передача данных в SPI
Передача осуществляется пакетами. Длина пакета, как правило, составляет 1 байт (8 бит), при этом известны реализации SPI с иной длиной пакета, например, 4 бита. Ведущее устройство инициирует цикл связи установкой низкого уровня на выводе выбора подчинённого устройства (SS) того устройства, с которым необходимо установить соединение. При низком уровне сигнала SS:
- схемотехника ведомого устройства находится в активном состоянии,
- вывод MISO переводится в режим «выход»,
- тактовый сигнал SCLK от ведущего устройства воспринимается ведомым и вызывает считывание на входе MOSI значений, передаваемых от ведущего битов и сдвиг регистра ведомого устройства.
Автор: Cburnett, Источник картинки
Подлежащие передаче данные ведущее и ведомое устройства помещают в сдвиговые регистры. После этого ведущее устройство генерирует импульсы синхронизации на линии SCLK, что и приводит к взаимному обмену данными. Передача данных идёт бит за битом от ведущего по линии MOSI и от ведомого по линии MISO.
Передача осуществляется, начиная со старших битов, но некоторые производители допускают изменение порядка передачи битов программными методами. После передачи каждого пакета данных ведущее устройство, в целях синхронизации ведомого устройства, может перевести линию SS в высокое состояние.
Режимы работы интерфейса SPI
Возможны четыре режима синхронизации. Режим определяется комбинацией бит CPHA и CPOL:
- CPOL = 0 — исходное состояние сигнала синхронизации — низкий уровень.
- CPOL = 1 — исходное состояние сигнала синхронизации — высокий уровень.
- CPHA = 0 — выборка данных производится по переднему фронту (переключению) сигнала синхронизации. То есть по переключению из основного в противоположное ему.
- CPHA = 1 — выборка данных производится по заднему фронту (переключению) сигнала синхронизации.То есть по переключению обратно к основному из противоположного.
Для обозначения режимов работы интерфейса SPI принято следующее соглашение:
- режим 0 (CPOL = 0, CPHA = 0),
- режим 1 (CPOL = 0, CPHA = 1),
- режим 2 (CPOL = 1, CPHA = 0),
- режим 3 (CPOL = 1, CPHA = 1).
Топология систем связи на базе SPI
В простейшем случае к ведущему устройству подключено единственное ведомое устройство и необходим двусторонний обмен данными. В таком случае используется трёхпроводная схема подключения. Интерфейс SPI позволяет подключать к одному ведущему устройству несколько ведомых устройств, причём подключение может быть осуществлено несколькими способами.
Первый способ дает возможность реализовать радиальную структуру связи (топология типа «звезда»), его принято считать основным вариантом подключения нескольких ведомых устройств:
Автор: Cburnett, Источник картинки
В этом случае для обмена более чем с одним ведомым устройством, ведущее устройство должно формировать соответствующее количество сигналов выбора ведомого устройства (SS). При обмене данными с ведомым устройством, соответствующий ему сигнал SS переводится в активное (низкое) состояние, при этом все остальные сигналы SS находятся в неактивном (высоком) состоянии. Выводы данных MISO ведомых устройств соединены параллельно, при этом они находятся в неактивном состоянии, а перед началом обмена один из выходов (выбранного ведомого устройства) переходит в активный режим.
Второй способ позволяет выполнять структуру связи типа «кольцо»:
Автор: Cburnett, Источник картинки
В данном случае для активации одновременно нескольких ведомых устройств используется один сигнал SS, а выводы данных всех устройств соединены последовательно и образуют замкнутую цепь. При передаче пакета от ведущего устройства этот пакет получает первое ведомое устройство, которое, в свою очередь, транслирует свой пакет следующему ведомому устройству и так далее. Для того чтобы пакет от ведущего устройства достиг определённого ведомого устройства, ведущее устройство должно отправить ещё несколько пакетов.
Преимущества и недостатки интерфейса SPI
Преимущества
Недостатки
- Необходимо больше выводов, чем для интерфейса I²C.
- Ведомое устройство не может управлять потоком данных.
- Нет подтверждения приёма данных со стороны ведомого устройства (ведущее устройство может передавать данные «в никуда»).
- Нет определённого стандартом протокола обнаружения ошибок.
- Отсутствие официального стандарта, что делает невозможным сертификацию устройств.
- По дальности передачи данных интерфейс SPI уступает таким стандартам, как UART и CAN.
- Наличие множества вариантов реализации интерфейса.
- Нет поддержки горячего подключения устройств.
А теперь если мы попробуем обратиться к микроконтроллеру Arduino и откроем одну из стандартных библиотек, идущих в комплекте для библиотеки SPI, под названием Digital Pot Control (управление цифровым потенциометром), то мы сможем с помощью неё организовать общение с подчинённым устройством в рамках этого интерфейса.
Скетч ниже предназначен для управления AD5206, многоканальным цифровым потенциометром. Устройство является достаточно интересным и служит для изменения сопротивления в цепи электронным способом, а не вручную. Если кому интересно, можете почитать подробные спецификации этого потенциометра здесь.
Одним из его применений может быть изменение яркости светодиодов за счёт плавной регулировки сопротивления.
Говоря о технических особенностях этого устройства, можно сказать, что этот цифровой потенциометр имеет возможность установки 256 позиций и является шестиканальным (то есть поддерживает 6 подключаемых устройств, например, светодиодов). Его возможности позволяют заменить механические потенциометры, номиналами 10, 50 или 100 кОм.
Каждый из 6 переменных резисторов потенциометра выведен на корпус микросхемы в виде 3 контактов, и логика подключения к ним ничем не отличается от подключения обычных переменных резисторов.
Назначение пинов на корпусе микросхемы можно посмотреть на рисунке ниже:
Источник картинки
Принципиальную схему соединений светодиодов с микросхемой и пинами Arduino Uno можно увидеть на рисунке ниже:
Источник картинки
Источник картинки
Код довольно простой, он реализует сказанное выше и работает следующим образом: плавно изменяется сопротивление на каждом из 6 каналов, пробегая по каждой из 256 позиций, заставляя светодиоды сначала плавно ярко «разгореться», а потом — также плавно погаснуть. Все требующиеся пояснения содержатся в комментариях к коду.
Как мы уже упоминали в самом начале, интерфейс SPI позволяет не только управлять каким-то ещё одним устройством, но и осуществлять полноценную связь в рамках модели ведущий/ведомый между двумя и более ардуинами.
Код, приведённый ниже, работает следующим образом: ардуины связаны друг с другом через SPI. Каждая из них имеет подключённую кнопку-замыкатель. Если происходит нажатие кнопки на ведущем устройстве — включается белый диод на подчинённой ардуине. И, соответственно, если нажимается кнопка на ведомом устройстве, то загорается красный светодиод на ведущей ардуине. Сам пример взят здесь, можете почитать более подробно, если интересно. Все требующиеся пояснения содержатся в комментариях к коду.
Результат работы кода:
Из интересных моментов в этом примере, на мой взгляд, можно выделить, что используется делитель частоты синхронизации SPI. В данном случае используется делитель на 8, то есть связь между ардуинами осуществляется на скорости в 2 МГц (однако значение по умолчанию обычно равно SPI_CLOCK_DIV4, одна четверть от частоты контроллера).
Всего возможны 7 вариантов делителей частоты:
- SPI_CLOCK_DIV2
- SPI_CLOCK_DIV4
- SPI_CLOCK_DIV8
- SPI_CLOCK_DIV16
- SPI_CLOCK_DIV32
- SPI_CLOCK_DIV64
- SPI_CLOCK_DIV128
Однако один из самых красивых примеров, который, на мой взгляд, хорошо иллюстрирует взаимодействие между собой множества ардуин, показан всё-таки ниже.
Электронная начинка:
Источник картинки
Результат сборки:
В этой самоделке используется взаимодействие мастера и множества слейвов, которые работают синхронно и образуют вращающимися стрелками текущее время. Кому интересно более подробно почитать о проекте, может это сделать здесь.
Правда следует оговориться, что здесь для взаимодействия использован более продвинутый способ, где применяется интерфейс I2C, который тратит в 2 раза меньшее количество линий (2 против 4 у SPI). Хотя теоретически эта самоделка вполне могла быть выполнена и с использованием протокола SPI, однако тогда бы количество соединений критически выросло (видимо, именно поэтому автором и был выбран другой, более лаконичный на количество выводов способ).
С кодом этой реализации можно ознакомиться здесь.
Подытоживая, хочу сказать, что возможности протокола SPI не ограничиваются только перечисленными выше примерами. Однако если попытаться обобщить, то основными его назначениями, на мой взгляд, являются возможность расширить количество доступных контактов в рамках самоделок, а также разгрузить используемые микроконтроллеры, «сбрасывая» выполняющуюся задачу на подчинённых.
НЛО прилетело и оставило здесь промокод для читателей нашего блога:
— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS .
Communication between two Arduino
In this tutorial, we are going to learn:
Hardware Required
You can alse use PHPoC WiFi/Ethernet Shield instead of Ethernet Shield. PHPoC WiFi/Ethernet Shield supports both WiFi and Ethernet.
Communication between two Arduino — Overview
Let’s consider a specific case: Arduino #1 communicates with Arduino #2. There are many methods to enable communication between two Arduino. We can choose one of them depending on the communication range. The below table shows some methods and their communication range.
Methods | Range |
---|---|
I2C | very short |
SPI | very short |
UART (TTL) | very short |
UART (RS-232/485/422) | short |
Bluetooth | short |
LoRa | long |
Ethernet/WiFi | unlimited (*) |
Among the above methods, this tutorial uses Ethernet/WiFi to enable communication between two Arduino because it allows two Arduino to communicate over the unlimited distance.
Communication between two Arduino via Ethernet/WiFi
Two Arduino can communicate with each other via Ethernet/WiFi if:
No matter two Arduino connects with each other within a local LAN network or via the Internet, there are two types of communication:
In the case of communicating directly, in most cases, one Arduino plays the role of TCP client, the other plays the role of TCP server.
In the case of communicating through a centralized server, in most cases, both Arduino play the role of TCP client.
Depending on the application, We need to choose an application protocol for communicating between two Arduino. Below are some of the application protocols we can use: