Последовательный интерфейс SPI
SPI (Serial Peripheral Interface) – последовательный синхронный стандарт передачи данных в режиме полного дуплекса, разработанный компанией Motorola для обеспечения простого и недорогого сопряжения микроконтроллеров и периферии. SPI также иногда называют четырехпроводным (англ. four-wire) интерфейсом. SPI является синхронным протоколом, в котором любая передача синхронизирована с общим тактовым сигналом, генерируемым ведущим устройством (процессором). Принимающая периферия (ведомая) синхронизирует получение битовой последовательности с тактовым сигналом. К одному последовательному периферийному интерфейсу ведущего устройства-микросхемы может присоединяться несколько микросхем. Ведущее устройство выбирает ведомое для передачи, активируя сигнал «выбор кристалла» (chip select) на ведомой микросхеме. Периферия, не выбранная процессором, не принимает участие в передаче по SPI.
В SPI используются четыре цифровых сигнала:
- MOSI или SI – выход ведущего, вход ведомого (англ. Master Out Slave In). Служит для передачи данных от ведущего устройства ведомому;
- MISO или SO – вход ведущего, выход ведомого (англ. Master In Slave Out). Служит для передачи данных от ведомого устройства ведущему.
- SCK или SCLK – последовательный тактовый сигнал (англ. Serial CLocK). Служит для передачи тактового сигнала для ведомых устройств.
- CS или SS – выбор микросхемы, выбор ведомого (англ. Chip Select, Slave Select).Как правило, выбор микросхемы производится низким логическим уровнем.
В зависимости от комбинаций полярности и фазы синхроимпульсов возможны четыре режима работы SPI.
| Режим SPI | Временная диаграмма |
| Режим SPI0 Активные уровень импульсов — высокий. Сначала защёлкивание, затем сдвиг. |
![]() |
| Режим SPI1 Активные уровень импульсов — высокий. Сначала сдвиг, затем защёлкивание. |
![]() |
| Режим SPI2 Активные уровень импульсов — низкий. Сначала защёлкивание, затем сдвиг. |
![]() |
| Режим SPI3 Активные уровень импульсов — низкий. Сначала сдвиг, затем защёлкивание. |
![]() |
В таблице принято:
- MSB — старший бит;
- LSB — младший бит.
Мастеру приходится настраиваться на тот режим, который используется ведомым.
При обмене данными по интерфейсу SPI микроконтроллер может работать как ведущий (режим Master) либо как ведомый (режим Slave). При этом пользователь может задавать следующие параметры:
- режим работы в соответствии с таблицей;
- скорость передачи;
- формат передачи (от младшего бита к старшему или наоборот).
Соединение двух микроконтроллеров по структуре ведущий – ведомый по интерфейсу SPI осуществляется по следующей схеме.

Выводы SCK, CS для ведущего микроконтроллера являются выходами, а ведомого микроконтроллера – входами.
Передача данных осуществляется следующим образом. При записи в регистр данных SPI ведущего микроконтроллера запускается генератор тактового сигнала модуля SPI, и данные начинают побитно выдаваться на вывод MOSI и соответственно поступать на вывод MOSI ведомого микроконтроллера. После выдачи последнего бита текущего байта генератор тактового сигнала останавливается с одновременной установкой в «1» флага «Конец передачи». Если поддерживаются и разрешены прерывания от модуля SPI, то генерируется запрос на прерывание. После этого ведущий микроконтроллер может начать передачу следующего байта либо, подав на вход SS ведомого напряжение уровня логической «1», перевести его в состояние ожидания.
Одновременно с передачей данных от ведущего к ведомому происходит передача и в обратном направлении, при условии, что на входе SS ведомого присутствует напряжение низкого уровня. Таким образом, в каждом цикле сдвига происходит обмен данными между устройствами. В конце каждого цикла флаг прерывания устанавливается в «1» как в ведущем микроконтроллере, так и в ведомом. Принятые байты сохраняются в приемных буферах для дальнейшего использования.
При приеме данных принятый байт должен быть прочитан из регистра данных SPI до того, как в сдвиговый регистр поступит последний бит следующего байта. В противном случае первый байт будет потерян.
Вывод SS предназначен для выбора активного ведомого устройства и в режиме Slave всегда является входом. Каждый раз, когда на вывод SS подается напряжение уровня логической «1», происходит сброс модуля SPI. Если изменение состояния этого вывода произойдет во время передачи данных, и прием, и передача немедленно прекратятся, а передаваемый и принимаемый байты будут потеряны.
Если микроконтроллер находится в режиме Master, направление передачи данных через вывод SS определяется пользователем. Если вывод сконфигурирован как выход, он работает как линия вывода общего назначения и не влияет на работу модуля SPI. Как правило, в этом случае он используется для управления выводом SS микроконтроллера, работающего в режиме Slave.
Если вывод сконфигурирован как вход, то для обеспечения нормальной работы модуля SPI на него должно быть подано напряжение высокого уровня. Подача на этот вход напряжения низкого уровня от какой-либо внешней схемы будет воспринята модулем SPI как выбор микроконтроллера в качестве ведомого (при этом ему начинают передаваться данные).
Пример использования интерфейса SPI для микроконтроллеров STM32 хорошо описан в этой статье.
Назад
Raspberry Pi. Обмен данными по интерфейсу SPI.
![]()
Продвигаемся по нашему учебному курсу, посвященному работе с Raspberry Pi! Героем сегодняшней статьи будет интерфейс SPI. Разберем его включение, настройку и, конечно же, напишем реальный пример использования. Приступаем.
Как и в статье по работе с шиной I2C, для полноценности примера возьмем какое-нибудь устройство и подключим к Raspberry Pi по SPI. Из имеющегося у меня в наличии идеально подойдет датчик L3GD20. Схема подключения будет такой:

Raspberry будет играть роль ведущего устройства SPI (master), а гироскоп — подчиненного (slave). Здесь мы используем сигналы:
- SPI0_CE0_N — chip select
- SPI0_MOSI — master output slave input — для передачи данных от ведущего к подчиненному
- SPI0_MISO — master input slave output — для приема данных от slave
- SPI0_SCLK — тактовый сигнал — его также генерирует master
И, опять же, использование именно этого датчика не накладывает никаких ограничений — с любым другим устройством можно будет работать точно так же. L3GD20 выбран только для наглядности. Итак, переходим к программным аспектам.
Включение SPI на Raspberry Pi.
Для того, чтобы активировать интерфейс SPI платы Raspberry Pi можно воспользоваться утилитой raspi-config. Вводим команду:
После запуска утилиты идем по пути Interfacing options — SPI и включаем нужный нам интерфейс:


Другим способом активации SPI является непосредственное редактирование файла /boot/config.txt. В нем нужно раскомментировать строку:
В обоих случаях после изменения конфигурации необходимо перезапустить плату:
Не важно, каким именно способом пользоваться, результат будет одинаков. Для проверки вводим команду:
И в выводе команды в консоли видим такие строки:

Наличие в списке spidev0.0 и spidev0.1 сигнализирует нам о том, что интерфейс SPI успешно активирован. Первая цифра (0) в наименовании указывает, что используется SPI0, к которому и подключен датчик на нашей схеме.
А вторая цифра (0 или 1) определяет, какой вывод платы будет использован в качестве Chip Select’а. Здесь есть два варианта:
- SPI0_CE0_N
- SPI0_CE1_N
У нас использован SPI0_CE0_N, поэтому нас интересует spidev0.0. Два вывода Chip Select нужны для того, чтобы реализовать возможность подключения двух разных устройств к SPI0, каждому из которых будет соответствовать свой сигнал Chip Select (CS), а линии данных и тактирования (MOSI, MISO, SCLK) будут общими.
При таком подключении, если мы собираемся обмениваться данными с одним из устройств, то следует подать низкий уровень (0) на его вывод CS. А на CS второго устройства — высокий уровень (1). Таким образом и осуществляется переключение между устройствами, использующими одни и те же линии данных.
Работа с SPI на Python.
Здесь нам понадобится модуль python-spidev, который можно установить командой:
Если при запуске написанного кода будут возникать ошибки, то поможет принудительная установка версии 3.4 пакета:
Теперь уже можно переходить к написанию программы. Первый делом для использования SPI делаем import:
Далее нужно создать объект для работы с SPI и произвести подключение:
Аргументы функции open() как раз и позволяют выбрать использующийся модуль и сигнал Chip Select, который мы обсудили ранее. В нашем примере — SPI0 и SPI0_CE0_N. В целом, после вызова этих функций уже можно начинать работу с SPI, но давайте рассмотрим помимо прочего доступные варианты конфигурации:
- bits_per_word — количество битов в слове.
- cshigh — в активном режиме сигнал на выходе Chip Select может быть либо высокого, либо низкого уровня. Для первого случая ставим cshigh = True, для второго, соответственно — cshigh = False.
- loop — включение/отключение loopback режима.
- no_cs — записываем в параметр True, если не используем Chip Select.
- lsbfirst — выбираем, наиболее или наименее значимый бит будет первым в данных.
- max_speed_hz — максимальная частота интерфейса.
- mode — в этот параметр записываем два бита, например 0b01:
К примеру, если mode = 0b10, то исходный уровень сигнала синхронизации — высокий, по переднему фронту происходит выборка данных, по заднему — установка.
- threewire — режим, при котором вместо двух линий MOSI и MISO используется одна, объединяющая в себе их функции.
В коде установка параметров может происходить следующим образом:
Пришло время, наконец, рассмотреть и основные функции для приема и передачи данных:
- xfer(list of values[, speed_hz, delay_usec, bits_per_word])
Функция осуществления SPI транзакции. В квадратных скобках указаны необязательные аргументы, среди которых последовательно: частота, величина задержки между данными в микросекундах и количество битов в слове. Обязательный аргумент list of values — непосредственно передаваемые данные. Возвращает же функция данные, принятые от подчиненного устройства.
- xfer2(list of values[, speed_hz, delay_usec, bits_per_word])
Аналогичная функция, отличие от xfer() заключается в том, что сигнал Chip Select остается активным между транзакциями. В случае же с xfer() после каждой отправки CS переходит в неактивное состояние, а затем снова активируется.
- xfer3(list of values[, speed_hz, delay_usec, bits_per_word])
И еще одна функция из этой группы. Ее отличие заключается в том, что если размер передаваемых данных превышает максимально допустимый, то данные будут разбиты на порции и отправлены по частям. Максимальный размер передаваемых данных задается через /sys/module/spidev/parameters/bufsiz.
- readbytes(n)
Функция приема данных, аргумент — количество байт, которые необходимо прочитать.
- writebytes(list of values)
Передача данных, задаваемых аргументом функции.
- writebytes2(list of values)
И похожая на предыдущую функция, отличающаяся тем, что разбивает данные на части в случае превышения максимального размера. В общем, аналогично функции xfer3().
Итак, именно при помощи этих функций и организуется обмен данными по интерфейсу SPI.
А теперь вспомним про наш подключенный датчик L3GD20 и напишем небольшой пример для чтения значений его регистров. В частности, есть один регистр (адрес 0x0F), значение которого строго фиксировано и равно 0xD4. Его значение и прочитаем, а затем сравним с заведомо известной верной величиной 0xD4 (11010100):

Но нужно, в двух словах, особо не углубляясь, рассмотреть процесс обмена данными с L3GD20. В целом выглядит это так:

В рамках рассматриваемой нами сегодня задачи это значит следующее. Для того, чтобы запросить значение регистра с адресом 0x0F, нам нужно отправить подчиненному (датчику) команду 0x8F. В ответ на это гироскоп отправит значение регистра. Нюанс заключается в том, что, отправив команду, ведущий (Raspberry Pi) должен обеспечивать тактирование на линии в то время как идет отправка данных подчиненным. Для того, чтобы это осуществить, отправим 2 байта — 0x8F и 0x00. Второй байт не несет никакой смысловой нагрузки, он нужен только для того, чтобы master продолжал выдавать сигнал тактирования в то время, пока slave отправляет данные.
Создаем файл spi_test.py. Итоговый код будет выглядеть так:
И в результате получаем правильное значение:
![]()
Отправляем два байта, как и планировали, и в ответе от slave получаем также два байта, первый из которых не несет полезной информации. Он соответствует тому периоду времени, когда master отправлял запрос (0x8F), соответственно на шине было тактирование, а на MISO в этот момент был низкий уровень, который и был прочитан как 0x00.
Вот на успешном запуске программы и закончим сегодняшнюю статью, всем спасибо за внимание и до скорого 🤝
chip select
Chip Select — On nomme chip select une entrée de contrôle de nombreux circuits intégrés, tels que les puces mémoires, permettant d activer ou désactiver le circuit. Quand elle est active, le composant peut être adressé ; quand elle ne l est pas, le… … Wikipédia en Français
Chip select — [tʃɪp sɪ lekt, englisch], Informatik: CS … Universal-Lexikon
Chip select — On nomme chip select une entrée de contrôle de nombreux circuits intégrés, tels que les puces mémoires, permettant d activer ou désactiver le circuit. Quand elle est active, le composant peut être adressé ; quand elle ne l est pas, le… … Wikipédia en Français
Chip select — An example SPI with a master and three slave select lines. Note that all four chips share the SCLK, MISO, and MOSI lines but each slave has its own slave select. Chip select (CS) or slave select (SS) is the name of a control line in digital… … Wikipedia
Chip Select — Als Chipselect wird in der Digitaltechnik ein binäres Signal an einem integrierten Schaltkreis bezeichnet, mit dem man die Funktion eines solchen Schaltkreises ganz oder teilweise an bzw. abschalten kann. Der Chipselect wird meist als einzelner… … Deutsch Wikipedia
Chip Duncan — (born January 3, 1955) is an American filmmaker, author, photographer, and President of the Duncan Group, Inc, a documentary and feature film production company established in 1984. Contents 1 Biography 2 Artistic career 3 Broadcast TV credits … Wikipedia
Chip Daniels — is a gay pornography actor and film director. He is credited with directing 27 films and acting in over 30. Contents 1 Awards 2 References 3 Sources 4 External links … Wikipedia
Chip Brian — Born November 11, 1970 (1970 11 11) (age 40) Los Angeles, California, USA Residence New York, New York Nationality American Alma … Wikipedia
select — [adj] excellent, elite, preferable best, blue chip*, boss*, choice, chosen, cool*, cream*, culled, delicate, discriminating, eclectic, elect, elegant, exclusive, exquisite, favored, first class*, first rate*, handpicked, limited, number one*,… … New thesaurus
ChIP-on-chip — Workflow overview of a ChIP on chip experiment. Contents … Wikipedia



