Библиотека SPI для Arduino
Данная библиотека позволяет вам взаимодействовать с SPI устройствами с помощью платы Arduino, работающей в качестве ведущего устройства.
Краткое введение в последовательный периферийный интерфейс SPI (Serial Peripheral Interface)
Последовательный периферийный интерфейс SPI – это синхронный последовательный протокол передачи данных, используемый микроконтроллерами для быстрой связи на коротких расстояниях с одним или несколькими периферийными устройствами. Он также может использоваться для связи между двумя микроконтроллерами.
При SPI соединении всегда есть одно ведущее (мастер) устройство (обычно это микроконтроллер), которое управляет периферийными устройствами. Обычно ко всем устройствам подключены три общих линии:
- MISO (Master In Slave Out, вход ведущего, выход ведомого) – линия ведомого устройства для передачи данных ведущему устройству;
- MOSI (Master Out Slave In, выход ведущего, вход ведомого) – линия ведущего устройства для передачи данных периферийным устройствам;
- SCK (Serial Clock, тактовый сигнал) – тактовые импульсы, которые синхронизируют передачу данных и выдаются ведущим устройством;
и одна линия, отдельная для каждого устройства:
- SS (Slave Select, выбор ведомого) – вывод на каждом устройстве, с помощью которого мастер может включить или выключить использование конкретных ведомых устройств.
Когда на выводе выбора ведомого SS установлен низкий логический уровень, это ведомое устройство взаимодействует с мастером. Когда на выводе SS установлен высокий логический уровень, ведомое устройство игнорирует мастера. Это позволяет вам иметь несколько SPI устройств, использующих одни и те же линии MISO, MOSI и CLK.
Для написания кода для нового SPI устройства вам необходимо обратить внимание на несколько моментов:
- Какова максимальная скорость SPI, которую может использовать ваше устройство? Она управляется первым параметром в
SPISettings
. Если вы используете чип с тактовой частотой 15 МГц, используйте значение 15000000. Arduino будет автоматически использовать лучшую скорость, равную или меньшую, чем значение, которое вы использовали вSPISettings
. - В каком порядке передаются данные: сначала идет старший значащий бит (MSB, Most Significant Bit) или младший значащий бит (LSB, Least Significant Bit)? Он управляется вторым параметром в
SPISettings
: либоMSBFIRST
, либоLSBFIRST
. Большинство SPI чипов используют порядок с идущим первым MSB. - На линии данных во время ожидания должен быть установлен высокий или низкий логический уровень? Выборка данных происходит по нарастающему или по спадающему фронту тактовых импульсов? Эти режимы контролируются третьим параметром в
SPISettings
.
Стандарт SPI предоставляет свободу, и каждое устройство реализует с небольшими отличиями. Это означает, что при написании кода вы должны уделить особое внимание техническому описанию устройства.
Вообще говоря, существует четыре режима передачи. Эти режимы управляют тем, выбираются ли данные при нарастающем или при спадающем фронте сигнала тактовой синхронизации (так называемая фаза сигнала синхронизации), находится ли линия синхронизации в режиме ожидания при высоком или при низком логическом уровне (так называемая полярность сигнала синхронизации). Четыре режима объединяют полярность и фазу в соответствии с данной таблицей:
Режим | Полярность сигнала синхронизации (CPOL, Clock Polarity) | Фаза сигнала синхронизации (CPHA, Clock Phase) | Сдвиг данных | Выборка данных |
---|---|---|---|---|
SPI_MODE0 | 0 | 0 | спад | нарастание |
SPI_MODE1 | 0 | 1 | нарастание | спад |
SPI_MODE2 | 1 | 0 | нарастание | спад |
SPI_MODE3 | 1 | 1 | спад | нарастание |
После того, как вы определились с параметрами SPI, используйте SPI.beginTransaction()
, чтобы начать использовать порт SPI. Порт будет настроен на определенные вами параметры. Самый простой и эффективный способ использования SPISettings
заключается в его создании прямо в SPI.beginTransaction()
. Например:
SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0));
Если другие библиотеки используют SPI через прерывания, им будет закрыт доступ к SPI, пока вы не вызовите SPI.endTransaction()
. Параметры SPI применяются в начале транзакции, и SPI.endTransaction()
не меняет настроек SPI. Если вы (или какая-либо библиотека) не вызовите во второй раз beginTransaction
, настройки сохраняются. Если ваша программа используется совместно с другими библиотеками, использующими SPI, вы должны попытаться свести к минимуму время между вызовами SPI.beginTransaction()
и SPI.endTransaction()
.
При использовании большинства SPI устройств после SPI.beginTransaction()
вы устанавливаете низкий логический уровень на выводе выбора ведомого SS, вызываете сколько угодно раз SPI.transfer()
для передачи данных, затем устанавливаете уровень логической 1 на выводе SS и, наконец, вызываете SPI.endTransaction()
.
Для более подробной информации об интерфейсе SPI смотрите статью «Назад к основам: SPI (последовательный периферийный интерфейс)».
Подключение
Следующая таблица показывает, на какие выводы плат Arduino выведены выводы шины SPI:
Плата Arduino / Genuino | MOSI | MISO | SCK | SS (ведомый) | SS (мастер) | Уровень |
---|---|---|---|---|---|---|
Uno или Duemilanove | 11 или ICSP-4 | 12 или ICSP-1 | 13 или ICSP-3 | 10 | - | 5В |
Mega1280 или Mega2560 | 51 или ICSP-4 | 50 или ICSP-1 | 52 или ICSP-3 | 53 | - | 5В |
Leonardo | ICSP-4 | ICSP-1 | ICSP-3 | - | - | 5В |
Due | ICSP-4 | ICSP-1 | ICSP-3 | - | 4, 10, 52 | 3,3В |
Zero | ICSP-4 | ICSP-1 | ICSP-3 | - | - | 3,3В |
101 | 11 или ICSP-4 | 12 или ICSP-1 | 13 или ICSP-3 | 10 | 10 | 3,3В |
MKR1000 | 8 | 10 | 9 | - | - | 3,3В |
Обратите внимание, что MISO, MOSI и SCK доступны все вместе в одном постоянном месте на плате на разъеме ICSP; это полезно, например, при разработке платы, которая работает на всех платах Arduino.
Примечание о выводе выбора ведомого (SS) на платах на базе микроконтроллеров AVR
Все платы на базе AVR имеют вывод SS, который полезен, когда они действуют как ведомые устройства, управляемые внешним мастером. Поскольку данная библиотека поддерживает только мастер-режим, этот вывод всегда должен устанавливаться в режим выхода, иначе интерфейс SPI может быть автоматически переведен аппаратным модулем в режим ведомого, что приведет к тому, что библиотека перестанет работать.
Тем не менее, в режиме мастера для выбора устройств, в качестве вывода выбора ведомого (SS) можно использовать любой вывод на плате. Например, плата расширения Arduino Ethernet использует вывод 4 для управления SPI соединением со встроенной SD картой и вывод 10 для управления SPI соединением с контроллером Ethernet.
Описание методов библиотеки SPI
SPISettings
Описание
Объект
SPISettings
используется для настройки SPI порта вашего устройства. Все три параметра объединяются в один объектSPISettings
, который передается методуSPI.beginTransaction()
.Когда все ваши параметры являются константами,
SPISettings
следует использовать непосредственно вSPI.beginTransaction()
. Синтаксис смотрите ниже. При константах этот синтаксис приводит к меньшему и более быстрому коду.Если какие-либо из ваших параметров являются переменными, мы можете создать объект
SPISettings
для хранения трех параметров. Затем вы можете передать методуSPI.beginTransaction()
имя этого объекта. Создание именованного объектаSPISettings
может быть более эффективным, если ваши параметры не являются константами, особенно если максимальная скорость – это переменная, вычисленная или настроенная, а не число, которое вы водите непосредственно в коде скетча.Синтаксис
SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0));
Примечание: лучше всего подходит, если все 3 параметра – константы.
SPISettings mySettting(speedMaximum, dataOrder, dataMode);
Примечание: лучше всего подходит, если все 3 параметра – переменные.
Параметры
speedMaximum
: максимальная скорость связи. Для SPI чипа с тактовой частотой 20 МГц используйте 20000000.dataOrder
:MSBFIRST
илиLSBFIRST
.dataMode
:SPI_MODE0
,SPI_MODE1
,SPI_MODE2
илиSPI_MODE3
.
Возвращаемое значение
Нет.
begin()
Описание
Инициализирует шину SPI установкой SCK, MOSI и SS в режим выхода, установкой на SCK и MOSI низкого логического уровня, а на SS – высокого логического уровня.
Синтаксис
SPI.begin();
Параметры
Нет.
Возвращаемое значение
Нет.
end()
Описание
Отключает шину SPI (режимы работы выводов не меняются).
Синтаксис
SPI.end();
Параметры
Нет.
Возвращаемое значение
Нет.
beginTransaction()
Описание
Инициализирует шину SPI, используя переданный объект
SPISettings
.Синтаксис
SPI.beginTransaction(mySettings);
Параметры
mySettings
: выбранные настройки в соответствии сSPISettings
(смотрите выше).Возвращаемое значение
Нет.
endTransaction()
Описание
Останавливает использование шины SPI. Обычно вызывается после отмены выбора ведомого чипа, чтобы позволить использовать шину SPI другим библиотекам.
Синтаксис
SPI.endTransaction();
Параметры
Нет.
Возвращаемое значение
Нет.
setBitOrder()
Описание
Эта функция не должна использоваться в новых проектах. Для настройки параметров используйте
SPISettings
сSPI.beginTransaction()
.Устанавливает порядок передачи битов на шину SPI: либо
MSBFIRST
(сначала старший значащий бит), либоLSBFIRST
(сначала младший значащий бит).Синтаксис
SPI.setBitOrder(order);
Параметры
order
:LSBFIRST
илиMSBFIRST
.Возвращаемое значение
Нет.
setClockDivider()
Описание
Эта функция не должна использоваться в новых проектах. Для настройки параметров используйте
SPISettings
сSPI.beginTransaction()
.Устанавливает делитель частоты тактового сигнала SPI отностительно тактовой частоты системы. На платах на базе AVR доступны следующие значения делителя: 2, 4, 8, 16, 32, 64 или 128. Параметр по умолчанию – это
SPI_CLOCK_DIV4
, который устанавливает частоту тактового сигнала SPI, равной четверти от частоты опорного генератора микроконтроллера (4 МГц для плат 16 МГц).Arduino Due
На плате Due частота опорного генератора может быть поделена на значения от 1 до 255. Значение по умолчанию – 21, что устанавливает частоту тактового сигнала на 4 МГц, как и на других платах Arduino.
Синтаксис
SPI.setClockDivider(divider);
Параметры
divider
:SPI_CLOCK_DIV2
,SPI_CLOCK_DIV4
,SPI_CLOCK_DIV8
,SPI_CLOCK_DIV16
,SPI_CLOCK_DIV32
,SPI_CLOCK_DIV64
илиSPI_CLOCK_DIV128
(только на платах AVR);slaveSelectPin
: вывод ведомого устройства SS (только на Arduino Due);divider
: число от 1 до 255 (только на Arduino Due).
Возвращаемое значение
Нет.
setDataMode()
Описание
Эта функция не должна использоваться в новых проектах. Для настройки параметров используйте
SPISettings
сSPI.beginTransaction()
.Устанавливает режим данных SPI: полярность и фазу тактового сигнала. Для более подробной информации об интерфейсе SPI смотрите статью «Назад к основам: SPI (последовательный периферийный интерфейс)».
Синтаксис
SPI.setDataMode(mode);
Параметры
mode
:SPI_MODE0
,SPI_MODE1
,SPI_MODE2
илиSPI_MODE3
;slaveSelectPin
: вывод ведомого устройства SS (только на Arduino Due).
Возвращаемое значение
Нет.
transfer(), transfer16()
Описание
Передача SPI основана на одновременных отправке и приеме: принятые данные возвращаются в
receivedVal
(илиreceivedVal16
). В случае передачи буфера, полученные данные сохраняются в этом же месте (старые данные заменяются принятыми данными).Синтаксис
receivedVal = SPI.transfer(val);
receivedVal16 = SPI.transfer16(val16);
SPI.transfer(buffer, size);
Параметры
val
: байт, который необходимо передать по шине;val16
: переменная из двух байтов, которую необходимо передать по шине;buffer
: массив данных для передачи.
Возвращаемое значение
Принятые данные.
usingInterrupt()
Описание
Если ваша программа осуществляет передачи SPI внутри обработчика прерывания, вывовите данную функцию, чтобы зарегистрировать номер или имя прерывания в библиотеке SPI. Это позволит
SPI.beginTransaction()
предотвратить конфликты использования. Обратите внимание, что прерывание, указанное при вызовеusingInterrupt()
будет отключено при вызовеbeginTransaction()
и снова включено вendTransaction()
.Синтаксис
SPI.usingInterrupt(interruptNumber);
Параметры
interruptNumber
: соответствующий номер прерывания.Возвращаемое значение
Принятые данные.