Библиотека SPI для Arduino

Добавлено 18 октября 2017 в 18:45

Данная библиотека позволяет вам взаимодействовать с 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 предоставляет свободу, и каждое устройство реализует с небольшими отличиями. Это означает, что при написании кода вы должны уделить особое внимание техническому описанию устройства.

Вообще говоря, существует четыре режима передачи. Эти режимы управляют тем, выбираются ли данные при нарастающем или при спадающем фронте сигнала тактовой синхронизации (так называемая фаза сигнала синхронизации), находится ли линия синхронизации в режиме ожидания при высоком или при низком логическом уровне (так называемая полярность сигнала синхронизации). Четыре режима объединяют полярность и фазу в соответствии с данной таблицей:

Режимы SPI
РежимПолярность сигнала синхронизации
(CPOL, Clock Polarity)
Фаза сигнала синхронизации
(CPHA, Clock Phase)
Сдвиг данныхВыборка данных
SPI_MODE000спаднарастание
SPI_MODE101нарастаниеспад
SPI_MODE210нарастаниеспад
SPI_MODE311спаднарастание

После того, как вы определились с параметрами 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:

Выводы шины SPI на платах Arduino
Плата Arduino / GenuinoMOSIMISOSCKSS (ведомый)SS (мастер)Уровень
Uno или Duemilanove11 или ICSP-412 или ICSP-113 или ICSP-310-
Mega1280 или Mega256051 или ICSP-450 или ICSP-152 или ICSP-353-
LeonardoICSP-4ICSP-1ICSP-3--
DueICSP-4ICSP-1ICSP-3-4, 10, 523,3В
ZeroICSP-4ICSP-1ICSP-3--3,3В
10111 или ICSP-412 или ICSP-113 или ICSP-310103,3В
MKR10008109--3,3В

Обратите внимание, что MISO, MOSI и SCK доступны все вместе в одном постоянном месте на плате на разъеме ICSP; это полезно, например, при разработке платы, которая работает на всех платах Arduino.

Назначение выводов разъема ICSP на платах Arduino
Назначение выводов разъема 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: соответствующий номер прерывания.

Возвращаемое значение

Принятые данные.

Примеры

Теги

ArduinoSPI (последовательный периферийный интерфейс)Программирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.