Что такое SPI-интерфейс. Как работать с SPI - Теория Программная реализация spi на си

SPI (англ. Serial Peripheral Interface, SPI bus - последовательный периферийный интерфейс, шина SPI) - последовательный синхронный стандарт передачи данных в режиме полного дуплекса , предназначенный для обеспечения простого и недорогого высокоскоростного сопряжения микроконтроллеров и периферии. SPI также иногда называют четырёхпроводным (англ. four-wire ) интерфейсом.

В отличие от стандартного последовательного порта (англ. 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 могут различаться в зависимости от производителя аппаратных средств, при этом возможны следующие варианты:

  • MOSI : SIMO, SDI (на устройстве), DO, DON, SI, MRSR;
  • MISO : SOMI, SDO (на устройстве), DI, DIN, SO, MTST;
  • SCLK : SCK, CLK, SPC (SPI serial port clock);
  • SS : nCS, CS , CSB , CSN , nSS, STE , SYNC .

Синхронизация в SPI

Частота следования битовых интервалов в линиях передачи данных определяется синхросигналом SCK, который генерирует ведущее устройство, ведомые устройства используют синхросигнал для определения моментов изменения битов на линии данных, при этом ведомые устройства никак не могут влиять на частоту следования битовых интервалов. Как в ведущем устройстве, так и в ведомом устройстве имеется счетчик импульсов синхронизации (битов). Счетчик в ведомом устройстве позволяет последнему определить момент окончания передачи пакета. Счетчик сбрасывается при выключении подсистемы SPI, такая возможность всегда имеется в ведущем устройстве. В ведомом устройстве счетчик обычно сбрасывается деактивацией интерфейсного сигнала SS .

Так как действия ведущего и ведомого устройства тактируются одним и тем же сигналом, то к стабильности этого сигнала не предъявляется никаких требований, за исключением ограничения на длительность полупериодов, которая определяется максимальной рабочей частотой более медленного устройства. Это позволяет использовать SPI в системах с низкостабильной тактовой частотой, а также облегчает программную эмуляцию ведущего устройства.

Прием и передача данных в SPI

Передача осуществляется пакетами. Длина пакета, как правило, составляет 1 байт (8 бит), при этом известны реализации SPI с иной длиной пакета, например, 4 бита. Ведущее устройство инициирует цикл связи установкой низкого уровня на выводе выбора подчиненного устройства (SS ) того устройства, с которым необходимо установить соединение. При низком уровне сигнала SS :

  • схемотехника ведомого устройства находится в активном состоянии;
  • вывод MISO переводится в режим «выход»;
  • тактовый сигнал SCLK от ведущего устройства воспринимается ведомым и вызывает считывание на входе MOSI значений передаваемых от ведущего битов и сдвиг регистра ведомого устройства.

Подлежащие передаче данные ведущее и ведомое устройства помещают в сдвиговые регистры. После этого ведущее устройство начинает генерировать импульсы синхронизации на линии SCLK, что приводит к взаимному обмену данными. Передача данных осуществляется бит за битом от ведущего по линии MOSI и от ведомого по линии MISO. Передача осуществляется, как правило, начиная со старших битов, но некоторые производители допускают изменение порядка передачи битов программными методами. После передачи каждого пакета данных ведущее устройство, в целях синхронизации ведомого устройства, может перевести линию SS в высокое состояние.

Режимы работы интерфейса SPI

Возможны четыре комбинации фазы (CPHA) и полярности (CPOL) сигнала SCLK по отношению к сигналам данных. Режимы работы определяются комбинацией бит 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 позволяет подключать к одному ведущему устройству несколько ведомых устройств, причем подключение может быть осуществлено несколькими способами.

Первый способ позволяет реализовать радиальную структуру связи (топология типа «звезда»), его принято считать основным способом подключения нескольких ведомых устройств. В данном случае для обмена более чем с одним ведомым устройством ведущее устройство должно формировать соответствующее количество сигналов выбора ведомого устройства (SS ). При обмене данными с ведомым устройством, соответствующий ему сигнал SS переводится в активное (низкое) состояние, при этом все остальные сигналы SS находятся в неактивном (высоком) состоянии. Выводы данных MISO ведомых устройств соединены параллельно, при этом они находятся в неактивном состоянии, а перед началом обмена один из выходов (выбранного ведомого устройства) переходит в активный режим.

Второй способ позволяет реализовать структуру связи типа «кольцо». В данном случае для активации одновременно нескольких ведомых устройств используется один сигнал SS , а выводы данных всех устройств соединены последовательно и образуют замкнутую цепь. При передаче пакета от ведущего устройства этот пакет получает первое ведомое устройство, которое, в свою очередь, транслирует свой пакет следующему ведомому устройству и так далее. Для того, чтобы пакет от ведущего устройства достиг определенного ведомого устройства, ведущее устройство должно отправить еще несколько пакетов.

Преимущества и недостатки интерфейса SPI

Преимущества

  • Полнодуплексная передача данных по умолчанию.
  • Более высокая пропускная способность по сравнению с I²C или SMBus .
  • Возможность произвольного выбора длины пакета, длина пакета не ограничена восемью битами.
  • Простота аппаратной реализации:
    • более низкие требования к энергопотреблению по сравнению с I²C и SMBus ;
    • возможно использование в системах с низкостабильной тактовой частотой;
    • ведомым устройствам не нужен уникальный адрес, в отличие от таких интерфейсов, как I²C , GPIB или SCSI .
  • Используется только четыре вывода, что гораздо меньше, чем для параллельных интерфейсов.
  • Однонаправленный характер сигналов позволяет при необходимости легко организовать гальваническую развязку между ведущим и ведомыми устройствами.
  • Максимальная тактовая частота ограничена только быстродействием устройств, участвующих в обмене данными.

Недостатки

  • Необходимо больше выводов, чем для интерфейса I²C .
  • Ведомое устройство не может управлять потоком данных.
  • Нет подтверждения приема данных со стороны ведомого устройства (ведущее устройство может передавать данные «в никуда»).
  • Нет определенного стандартом протокола обнаружения ошибок.
  • Отсутствие официального стандарта, что делает невозможным сертификацию устройств.
  • По дальности передачи данных интерфейс SPI уступает таким стандартам, как UART и CAN .
  • Наличие множества вариантов реализации интерфейса.
  • Отсутствие поддержки горячего подключения устройств.

Пример программной реализации

Ниже представлен пример программной реализации SPI мастера на языке Си . Линия CS (chip select, выбор микросхемы) должна быть активирована (в большинстве случаев - притянута к низкому уровню), перед тем, как начнётся обмен данными, и деактивирована после окончания обмена. Большинство устройств требуют несколько сеансов передачи с активной линией CS . Эта функция может быть вызвана несколько раз, пока линия активна.

Поначалу в данной статье предполагалось описать особенности реализации синхронного последовательного интерфейса SPI в семействе однокристальных микроконтроллеров ADuC70xx фирмы Analog Devices. Автор намеревался не только рассмотреть особенности реализации SPI, но и обсудить, когда эти особенности оказываются полезными, как и для чего их следует использовать. В ходе написания статьи оказалось, что доля текста, посвященного вопросам «когда, как и для чего», превысила 50%.Тогда было принято решение изменить характер изложения в направлении, обозначенном в заглавии. Вследствие выросшего объема материал будет разбит на три отдельные статьи. 1. Принципы интерфейса SPI и организация ведомых устройств. 2. Подсистемы интерфейса SPI в микроконтроллерах: варианты организации и использование. 3. Подсистема интерфейса SPI в микроконтроллерах семейства ADuC70xx.

Все статьи цикла:

  • Синхронный последовательный интерфейс SPI в микроконтроллерах «от А до Я» и его реализация на примере ADuC70xx фирмы Analog Devices. Часть 1
  • Синхронный последовательный интерфейс SPI в микроконтроллерах ≪от А до Я≫ и его реализация в ADuC70xx фирмы Analog Devices. Часть 2
  • Синхронный последовательный интерфейс SPI в микроконтроллерах от «А до Я» и его реализация в ADuC70xx фирмы Analog Devices. Часть 3

В ходе написания статьи оказалось, что доля текста, посвященного вопросам «когда, как и для чего», превысила 50%. Тогда было принято решение изменить характер изложения в направлении, обозначенном в заглавии.

Вследствие выросшего объема материал будет разбит на три отдельные статьи:

  1. Принципы интерфейса SPI и организация ведомых устройств.
  2. Подсистемы SPI в микроконтроллерах: варианты организации и использование.
  3. Подсистема SPI в МК семейства ADuC70xx.

История SPI

Изобретатель интерфейса SPI — фирма Motorola . Однако изобретение было сделано не на «пустом месте». Предшественником послужил интерфейс MicroWire фирмы National Semiconductor . Автор статьи познакомился с интерфейсом SPI, работая с популярным семейством M68HC11 — практически первым, в котором SPI появился в конце 1980-х годов. Основное предназначение этого интерфейса — подключение к МК различных периферийных устройств. Очень быстро SPI стал весьма популярен по следующим причинам:

  1. минимальные требования к аппаратной части подключаемого к МК устройства (сдвиговый регистр);
  2. SPI-ведущего в минимальной конфигурации легко эмулировать программно, если в МК отсутствует аппаратная реализация SPI.

В последние два десятилетия многочисленные фирмы производят огромное количество различных периферийных узлов, подключаемых к МК через SPI (см., например, ). Это датчики физических величин (температуры, давления, ускорения и т. п.), устройства аналого-цифрового преобразования (АЦП, ЦАП, цифровые потенциометры), устройства преобразования интерфейсов (CAN-контроллеры, Ethernet-контроллеры), модули энергонезависимой памяти (Flash-карты MMC и SD, микросхемы EEPROM) и многие другие. В (2005 год) утверждается, что «примерно 85% МК оснащены интерфейсом SPI».

Исторически, однако, сложилось так, что какой-либо официальный общепризнанный стандарт на интерфейс SPI отсутствует. Поэтому свойства подсистемы SPI в микросхемах разных производителей могут различаться как набором возможностей, так и их реализацией, что нередко вызывает затруднения при использовании. Разработчики преодолевают эти затруднения по большей части методом проб и ошибок либо обмениваясь опытом. В свою очередь производители МК нередко, в предположении, что SPI — это общеизвестный стандарт, описывают свойства подсистемы излишне кратко. Этим, в частности, грешит техническое описание МК семейства ADuC70xx фирмы Analog Devices .

Весьма нелегко найти источники, в которых бы систематически были описаны все (или хотя бы большинство) из возможных особенностей интерфейса SPI. Обычно встречаемая на форумах разработчиков рекомендация — взять техническое описание МК, в котором SPI имеется. Но там, естественно, описывается лишь подмножество опций, реализованных в конкретном МК.

Автору известно лишь несколько публикаций, в которых сделана попытка описать свойства SPI без привязки к конкретному типу МК [ , , , ], и все они страдают неполнотой. Некоторые фирмы опубликовали свое «видение» того, что представляет собой SPI, например [ , – ], однако упомянутые документы в значительной степени «привязаны» к реализациям МК, выпускаемых этими фирмами.

Минимальная архитектура интерфейса и конфигурации

Минимальная архитектура изображена на рис. 1. Интерфейс SPI содержит четыре линии:

  • MOSI (Master Out Slave In) — выход данных ведущего (она же вход данных ведомого);
  • MISO (Master In Slave Out) — вход данных ведущего (она же выход данных ведомого);
  • SCK (Serial ClocK) — тактирование (синхронизация);
  • SS (Slave Select) — выбор ведомого.

Рис. 1. Структура связей и линии интерфейса SPI

Синхронизация передачи

Частота следования битовых интервалов в линиях данных SPI определяется синхросигналом SCK, который генерирует один из абонентов — ведущий (Master). Прочие абоненты — ведомые (Slave), которых может быть как один, так и несколько, используют синхросигнал для определения моментов изменения битов на линии данных. Ведомые устройства никак не могут влиять на частоту следования битовых интервалов (в отличие, например, от интерфейса I 2 C).

Ведущий в подавляющем большинстве случаев — это приемопередатчик SPI в составе МК (если аппаратный SPI отсутствует, его можно эмулировать программно). Однако автору известны реализации SPI-ведущего устройства в составе микросхем PLD фирмы Xilinx , а также в ИМС преобразователя параллельного интерфейса в интерфейс USB . В обоих этих случаях ведущий ориентирован на подключение определенного типа микросхем: EEPROM с SPI-совместимым интерфейсом.

Ведомое устройство — это обычно периферийная микросхема. Однако SPI можно использовать и для связи двух (или больше) МК, эта возможность будет обсуждаться позже.

Передача битов осуществляется пакетами. Длина пакета чаще всего составляет 1 байт (8 битов), хотя встречаются реализации SPI с иной длиной пакета [ , , ]. Как в ведущем устройстве, так и в ведомом имеется (обычно программно недоступный) счетчик импульсов синхронизации (битов). Счетчик в ведомом устройстве позволяет последнему определить момент окончания передачи пакета. Счетчик битов сбрасывается в ноль при выключении (деактивации) подсистемы SPI, такая возможность всегда имеется в ведущем устройстве. В ведомом устройстве счетчик битов обычно сбрасывается деактивацией интерфейсного сигнала SS. Передача пакета, то есть запуск генератора синхроимпульсов в ведущем, обычно осуществляется автоматически при записи передаваемого байта в регистр сдвига ведущего.

Задание частоты следования битов F SCK осуществляется стандартным для последовательных интерфейсов способом: F SCK =F G /DIV, где F G — постоянная частота задающего генератора SPI, значение которой приведено в техническом описании на микросхему, DIVА-217.(О- делитель, который может быть задан программно. В ряде МК делитель DIV может быть выбран только из набора предопределенных значений. Например, в МК семейства M68HC11 это одно из четырех значений: 2, 4, 16, 32 . При номинальном значении F G , равном 2 МГц, частота сдвига в этих МК может составлять 1000, 500, 125 или 62,5 кГц. В других МК значение DIV разрешается выбирать произвольно в пределах ограниченной разрядности. В семействе микроконтроллеров ADuC70xx эта разрядность составляет один байт, величина делителя может задаваться в пределах от 5 до 255, что позволяет выбрать одно из 251 значения частоты сдвигов в пределах от 3482 до 81,2 кГц.

Поскольку действия на ведущем и ведомом устройствах тактируются одним и тем же сигналом SCK, к стабильности частоты этого сигнала не предъявляется никаких требований (за исключением ограничения сверху на длительности полупериодов, определяемого максимальной рабочей частотой более медленного абонента). Это позволяет использовать SPI в системах с низкостабильной частотой тактирования (тактовый генератор без кварцевой стабилизации, с времязадающей RCцепью), а также существенно облегчает программную эмуляцию ведущего устройства. Более того, при программной эмуляции вполне допустимо приостанавливать передачу «в середине» байта, если это допускает ведомое устройство.

Передача данных

SPI предполагает передачу бит за битом: от ведущего по линии MOSI и от ведомого (в обратную сторону) по линии MISO. Таким образом, возможен полнодуплексный режим, когда данные передаются в обоих направлениях одновременно и синхронно. Порядок следования битов в исходной версии SPI фирмы Motorola можно определить как «начиная со старшего», однако в дальнейшем некоторые производители микроконтроллеров позволяли его задавать программно. Возможны реализации, в которых для передачи данных используется единственная двунаправленная линия; подобная конфигурация описана, в частности, в документе фирмы Freescale, полупроводниковой «дочки» фирмы Motorola .

Выбор ведомого — сигнал SS

Четвертый сигнал интерфейса — SS (Slave Select, выбор ведомого) — имеет основным назначением включение или выключение ведомого устройства сигналом от ведущего (от МК).

При активном (низком) уровне сигнала SS:

  • Схемотехника ведомого устройства находится в активном состоянии.
  • Вывод MISO — в режиме «выход».
  • Тактовый сигнал SCK от ведущего воспринимается ведомым, вызывает считывание на входе MOSI значений передаваемых от ведущего битов и сдвиг регистра ведомого.

При пассивном (высоком) уровне сигнала SS тактовый сигнал SCK и сигнал MOSI не оказывают никакого воздействия на ведомое устройство.

В простейших вариантах использования SPI сигнал SS может не употребляться. В других, более сложных периферийных устройствах сигнал SS не только используется, но выполняет еще и дополнительные функции, и этот вопрос будет обсуждаться далее.

Временная диаграмма сигналов

Возможно несколько вариантов диаграммы. Один из них изображен на рис. 2, а другие будут рассмотрены далее. Опишем диаграмму подробно.


Рис. 2. Диаграмма SPI, режим 0

До начала передачи пакета, левее момента времени А сигнал SS на выходе ведущего в высоком состоянии — рис. 2д), ведомый неактивен, его выход MISO в отключенном состоянии, а входы ведомого MOSI и SCK не воспринимают сигналов, формируемых ведущим. Тактовый сигнал на выходе ведущего в этот период имеет низкий уровень.

Для активации ведомого ведущий переводит в активное (низкое) состояние сигнал SS выбора ведомого (момент времени A). Ведомый включается, его вход тактирования способен воспринимать тактовый сигнал, а вывод MISO переходит в режим выхода. Тактовые импульсы пока еще не начались, выходные сигналы на линях данных MOSI и MISO теперь отражают значения бита, который будет первым передан другому абоненту (интервал времени от A до 1).

Через некоторое время ведущий начинает формирование пакета сдвиговых импульсов — рис. 2а), сигнал SCK. Перепады тактового сигнала вызывают сдвиг содержимого сдвиговых регистров ведущего и ведомого, а также захват новых значений битов после сдвига. Моменты сдвига и захвата должны быть разнесены во времени, поэтому эти действия выполняются в интерфейсе SPI по разным перепадам тактовых импульсов. Диаграмма изображена в предположении, что захват производится по нарастанию тактового сигнала (по нечетным перепадам на рисунке), соответствующие моменты времени отмечены также на рис. 2б), а сдвиг в регистрах — по спаду (четные перепады). Таким образом, порядок событий при действии каждого тактового импульса можно описать как «захват, затем сдвиг» (Latch, then Shift).

После окончания обмена пакетами (правее перепада 16-тактовой последовательности) выходной сигнал на каждой из линий данных MOSI и MISO отражает значение бита, который был передан первым. Передача пакета завершается снятием сигнала SS на выходе ведущего (момент B), что деактивирует ведомого абонента. Через некоторое время возможно начало передачи следующего пакета (момент С).

Сигнал SS может формироваться на выходе ведущего разными способами. В некоторых МК он формируется аппаратно: после того как будет программно выполнена запись передаваемого байта в регистр данных передатчика, выходной сигнал SS автоматически переключается в низкий уровень, а по окончании пакета — возвращается в исходное неактивное значение (высокий). Если в ведущем устройстве отсутствует аппаратно реализованное формирование сигнала SS, его формируют программно, используя для этого выход параллельного порта общего назначения. Однако при работе с некоторыми периферийными устройствами приходится формировать сигнал SS программно даже при наличии аппаратного формирователя. Примеры будут приведены позже.

На этом рассмотрение базовых свойств интерфейса SPI заканчиваем, а более подробное их обсуждение продолжим на примерах использования.

Простейший пример использования SPI

Рассмотрим простой пример использования интерфейса SPI для увеличения количества линий дискретного вывода (параллельных портов) в МК, например, для управления группой светодиодов либо семисегментным ЖК-индикатором. Для этого в качестве ведомого можно взять обычный регистр сдвига, например 74HC164. Такой восьмиразрядный регистр имеет последовательный вход данных, вход тактирования (сдвига) и восемь параллельных выходов. Отдельный последовательный выход данных в этом регистре отсутствует, но для этого можно использовать выход старшего разряда D7. Схема подключения показана на рис. 3. В ней использованы только две из четырех линий интерфейса SPI.


Рис. 3. Подключение к МК сдвигового регистра через SPI

Схемотехника микросхемы 74HC164 такова, что как восприятие нового значения входного сигнала MOSI, так и сдвиг (в результате которого изменяются состояния параллельных выходов D7, …, D0) происходит по нарастанию тактового сигнала SCK. Таким образом, использовав два вывода (MOSI и SCK) можно получить дополнительно восемь цифровых выходов в системе.

Почти во всех микроконтроллерах с интерфейсом SPI линии этого интерфейса мультиплексированы с выводами параллельных портов общего назначения. Данный факт позволяет использовать незадействованные выводы микроконтроллера MISO и SS для других целей. Но этот же факт требует от программиста не забыть переконфигурировать соответствующие выводы параллельных портов для их использования в SPI.

Последовательное включение ведомых

При необходимости увеличения количества выходов можно соединить n регистров 74HC164 последовательно в цепочку, которая образует 8× n -разрядный сдвиговый регистр и предоставит 8× n выходов. На рис. 4 показано, как это выглядит для n = 2.


Рис. 4. Последовательное подключение к МК простых сдвиговых регистров как ведомых

Для загрузки этого составного сдвигового регистра новым содержимым придется передать через SPI последовательно n байтов. Недостаток такого решения состоит в том, что во время передачи цепочки битов через многоразрядный сдвиговый регистр состояния его выходов будут переключаться, однако для управления набором светодиодов или многоразрядным семисегментным индикатором это вполне допустимо.

Аналогично можно подключить к МК через интерфейс SPI одну или несколько ИМС регистров сдвига типа 74HC299, имеющих двунаправленные параллельные выводы, что даст дополнительное количество двунаправленных линий ввода/вывода.

Периферийные микросхемы с интерфейсом SPI могут быть устроены сложнее, нежели рассмотренные сдвиговые регистры, и требовать определенной последовательности сигналов SCK и MOSI на своих входах. Это относится:

  • к полярности тактовых импульсов (или иначе, к уровню сигнала, которого требует на входе SCK периферийная микросхема в промежутках между передачами пакетов),
  • а также к порядку событий «захват и сдвиг».

По этой причине в спецификациях интерфейса SPI различают четыре режима работы , диаграммы для этих режимов изображены на рис. 5.


Рис. 5. Четыре режима работы интерфейса SPI

Буквы S и L над графиками обозначают соответственно Shift (сдвиг) и Latch (захват). Рассмотренная ранее диаграмма соответствует Mode 0. Считается, что наиболее употребительны Mode 0 и Mode 3.

Для выбора в ведущем устройстве (в МК) одного из режимов, различающихся полярностью тактовых импульсов и их «фазой» (порядком действий), в одном из периферийных регистров подсистемы SPI обычно есть два управляющих бита: CPOL (полярность) и CPHA (фаза) — приведенные обозначения битов и обозначения режимов являются широко употребительными. Периферийные устройства (ведомые) чаще всего поддерживают единственный режим, и перед началом обмена ведущий (МК) должен быть настроен на этот режим.

Обратим внимание читателя на то, что в рассмотренном выше примере работы с обычным регистром сдвига одинаково пригоден любой из этих четырех режимов.

Возможные топологии систем связи на базе интерфейса SPI

Простейший случай: к ведущему подключен единственный ведомый, и необходим двусторонний обмен. В этом случае структура межсоединений может использовать трехпроводную схему (рис. 6).


Рис. 6. Двунаправленный обмен с одним ведомым без использования сигнала SS

На вход выбора SS на ведомом может быть постоянно подан активный (низкий) уровень, в то время как выход SS ведущего не используется вовсе и может быть задействован как вывод параллельного порта.

Интерфейс SPI позволяет подключить к одному ведущему несколько ведомых устройств, причем это может быть сделано различными способами. Первый из них позволяет реализовать радиальную структуру связи («звезда»), его принято считать основным вариантом использования интерфейса SPI. Соответствующая конфигурация соединений показана на рис. 7 (заимствован из ).

Рис. 7. Радиальная структура связи
с несколькими ведомыми через SPI

Как видно на рисунке, для обмена более чем с одним ведомым ведущий должен формировать соответствующее количество сигналов выбора ведомого SS. Это как раз тот случай, когда сигналы SS приходится формировать программно, поскольку аппаратно в ведущем формируется не более одного сигнала SS. Если требуется обеспечивать обмен всегда только между ведущим и лишь одним из ведомых, программа на ведущем должна в промежутках между передачами данных держать все сигналы SS в неактивном (высоком) состоянии, а для обмена с одним из ведомых переводить в активный (низкий) уровень соответствующий сигнал SS (отсюда и название «выбор ведомого» — Slave Select). Выводы данных ведомых MISO соединены параллельно, но не «мешают» друг другу, поскольку находятся в отключенном состоянии, а перед началом обмена лишь один из этих выходов (на выбранном ведомом) переходит в активный режим. Обеспечение такого положения дел требует от программиста внимательности.

Однако может возникнуть желание в некоторых приложениях использовать «широковещательную» передачу, при которой данные, передаваемые ведущим, воспринимаются и используются одновременно несколькими (может быть, всеми) ведомыми. Подобный режим возможен без опасности возникновения электрического конфликта на линии MISO в случае, если не требуется передавать данные из ведомых в ведущее устройство, тогда обратные линии данных из ведомых просто отсутствуют.

Если в качестве ведомых в рассматриваемой структуре используются тоже МК, в которых имеется возможность программно управлять режимом выходов MISO, то можно организовать широковещ ательную передачу и при наличии обратного канала (линии MISO). Для этого программы, работающие на микроконтроллерах — ведомых, должны постоянно держать выводы MISO в отключенном состоянии, при этом возможен режим широковещательной передачи от ведущего. Если же требуется получение данных от одного из ведомых, ведущий может сообщить ему об этом в широковещательном режиме, послав пакет с командным кодом-идентификатором, распознав который, один из ведомых должен перевести свой вывод MISO в активное состояние, после чего возможен двусторонний обмен данными между ведущим и выбранным ведомым. По окончании двустороннего обмена ведущий должен вернуть выбранного ведомого в исходное состояние. Иными словами, для получения такой возможности разработчику придется сконструировать некий протокол обмена, надстроенный над диаграммами SPI, в котором некоторые значения байтов (или их последовательностей) играют роль команд для ведомых МК. Этот вопрос будет рассмотрен более подробно в следующей статье цикла при обсуждении организации симметричной магистрали с несколькими ведущими на базе SPI.

Второй способ, позволяющий соединить одного ведущего абонента с несколькими ведомыми, — это структура «кольцо» (иногда эту структуру называют «цепочкой» или каскадным включением, в английской терминологии используется название Daisy-Chain) . Эта структура изображена на рис. 8 (заимствован из ).

Рис. 8. Кольцевая топология связи через SPI

В ней для активации одновременно нескольких ведомых используется единственный сигнал SS, а выводы данных всех абонентов соединены последовательно и образуют замкнутую цепь (кольцо). При передаче пакета от ведущего этот пакет получает первый ведомый, который, в свою очередь, транслирует свой пакет следующему ведомому, и т. д., наконец, последний в цепи ведомый передает свой пакет ведущему. Для того чтобы пакет от ведущего достиг определенного ведомого, ведущий должен выдать еще несколько пакетов. Вариант этой структуры (с незамкнутым кольцом) уже обсуждался (рис. 4).

Некоторые периферийные микросхемы с интерфейсом SPI проектируются специально для использования в цепочечных конфигурациях. Пример таких микросхем — цифро-аналоговые преобразователи AD5444 и AD5446 фирмы Analog Devices . Их структура изображена на рис. 9.


Рис. 9. Структура ЦАП AD5444/AD5446, приспособленная для SPI-цепочки

Интерфейс этих приборов, совместимый с SPI, содержит 16-разрядный сдвиговый регистр с последовательным входом данных SDIN (MOSI), последовательным выходом данных SDO (MISO), входом тактирования сдвига SCLK (SCK) и входом управления SYNC. Три первых вывода по своим функциям полностью аналогичны выводам SPI (они указаны в скобках). Наличие выхода сдвигового регистра SDO позволяет подключить к МК (ведущему) несколько микросхем ЦАП по цепочечной структуре. Захват значения на входе регистра ведомого AD5444/6 происходит по спаду сигнала SCLK, изменение сигнала на этом входе (сдвиг выходного регистра ведущего) должен происходить по нарастанию SCLK. Такая последова тельность действий соответствует Mode 1 (рис. 5). Длина передаваемого в микросхему ЦАП пакета составляет 16 битов, из них два старших выполняют управляющие функции, а последующие 14 битов (в AD5446) или 12 битов (в AD5444) представляют значение отсчета, преобразуемое в напряжение. У программиста есть возможность переключить режим работы SPI в ведомом AD544x, задав значение старших двух битов пакета равным 11, в результате чего ведомый AD544x переключится в Mode 2, захват входного сигнала будет происходить по нарастанию сигнала SCLK.

А вот вход SYNC (SS) выполняет одновременно несколько функций. Во-первых, он низким уровнем активирует в микросхеме ЦАП функцию восприятия сигналов входной линии данных SDIN (MOSI) и линии тактирования SCLK (SCK). Кроме того, по окончании передачи пакета в микросхемы ЦАП переход в высокий уровень сигнала SYNC инициирует передачу полученного 16-битового пакета во входной буфер схемотехники ЦАП (что приведет к появлению нового значения напряжения на аналоговом выходе ЦАП синхронно во всех ведомых), а кроме того, отключает питание от интерфейсных цепей для уменьшения мощности, потребляемой микросхемой ЦАП.

Таким образом, штатный режим работы с цепочкой микросхем ЦАП предполагает установку активного уровня сигнала SYNC (SS), по которому включается питание интерфейсной схемотехники в ЦАП, затем последовательную передачу нужного количества 16-разрядных посылок с учетом порядка включенных в цепочку ведомых (при этом изменения выходных напряжений ЦАП не происходит) и, наконец, выключение активного сигнала SYNC, по которому изменятся одновременно выходные напряжения всех ЦАП в цепочке. Сигнал SYNC должен сохраняться активным (низким) без переключений до окончания передачи всех посылок.

Еще ряд примеров использования SPI

И в случае радиальной схемы с широковещанием, и в последнем примере с цепочечным подключением ЦАП дополнительные возможности были получены в результате наличия и использования высокоуровневого протокола, предполагающего передачу многобайтовых посылок. В примере с широковещанием разработка такого протокола должна выполняться прикладным программистом, в то время как при использовании ИМС AD5444/AD5446 этот протокол специфицирован в их техническом описании.

Широко распространенный отладочный интерфейс JTAG также представляет собой пример реализации высокоуровневого протокола поверх SPI. JTAG предполагает соединение нескольких контролируемых устройств (ведомых) в кольцо и наличие в этом кольце единственного ведущего (JTAG-хоста) [ , , ]. Длины посылок, используемые в JTAG, могут быть достаточно большими, однако их размер кратен 8 битам.

Рассмотрим еще один пример, в котором передача данных осуществляется только в обратном направлении — от ведомого к ведущему, а сигнал SS выполняет дополнительную функцию — запуск операции в периферийном устройстве.


Рис. 11. Диаграмма работы АЦП MAX1240/1241 с интерфейсом SPI и с запуском от сигнала SS

Исходно при неактивном (высоком) уровне сигнала CS выход данных DOUT находится в отключенном (высокоимпедансном) состоянии.

По спаду сигнала CS из ведущего МК в ведомом MAX1240/1241 происходит:

  1. захват входного аналогового сигнала на встроенном устройстве выборки/хранения УВХ;
  2. запуск процесса аналого-цифрового преобразования с одновременным переходом сигнала DOUT в низкий уровень.

По окончании (через 7,5 мкс) процесса АЦ преобразования УВХ переходит из состояния «хранение» (HOLD) в состояние «выборка» (TRACK), а сигнал DOUT — в высокий уровень: последнее сигнализирует микроконтроллеру о готовом результате.

После этого ведущий МК может начать (немедленно или через некоторое время) считывание результата АЦ преобразования путем подачи последовательности тактовых импульсов на линию SCLK. Для его получения ведущий должен инициировать передачу двух байтов из ведомого. В них будет передано 16 битов, из которых первые 12 представляют результат, а последние четыре (нуля) должны быть просто отброшены. На диаграмме показано, что для повторения измерения ведущий должен снять активный уровень сигнала SS на предопределенное время (не менее 0,24 мкс), после чего процесс вновь можно запустить переключением сигнала SS в активный (низкий) уровень.

В этом примере сигнал CS (SS) выполняет в ведомом MAX1240/1 несколько функций:

  1. активирует внутреннюю схемотехнику SPI и выводит из отключенного состояния выход сигнала DOUT (MISO);
  2. запускает процесс аналого-цифрового преобразования в АЦП. Следует обратить внимание на то, что в течение времени, пока происходит АЦ-преобразование, сигнал SS должен иметь активное значение (низкий уровень), но сдвиговые такты должны отсутствовать. Это возможно лишь при программном управлении сигналом SS в ведущем устройстве.

Отдельно нужно сказать о сигнале SHDN в микросхемах MAX1240/MAX1241. Он предназначен для перевода периферийной микросхемы в режим энергосбережения. Для этой цели можно было бы использовать SS, однако внутренней схемотехнике преобразователей напряжения (для АЦП) требуется некоторое время для выхода на режим (около 4 мкс). Разработчики микросхемы могли бы реализовать внутреннюю задержку, но они предпочли использовать дополнительный управляющий сигнал. Это оправдано тем, что при необходимости непрерывного преобразования SHDN нужно включить лишь единожды, а запуск АЦП производить многократно. Для управления сигналом SHDN можно использовать выход порта общего назначения.

Что должна делать программа в ведущем (в МК)?

Вот какой может быть последовательность действий, выполняемая микроконтроллером в последнем примере, если его подсистема SPI имеет стандартную длину пакета 8 битов:

  1. Установить высокий уровень сигнала SHDN (программно).
  2. Подождать не менее 4 мкс (выход на режим преобразователей напряжения для АЦП).
  3. Установить низкий уровень сигнала SS (программно).
  4. Убедиться, что сигнал DOUT принял значение лог. 0 (программно или по прерыванию).
  5. Проверять состояние сигнала DOUT (признак окончания АЦ-преобразования) до тех пор, пока этот сигнал не переключится в лог. 1 (программно или по прерыванию).
  6. Инициировать передачу байта из периферийной микросхемы. Частота следования тактовых импульсов не должна превышать 2,1 МГц.
  7. Дождаться окончания приема первого байта (программно или по прерыванию).
  8. Прочитать и сохранить принятый первый байт.
  9. Инициировать передачу второго байта.
  10. Дождаться окончания приема второго байта (программно или по прерыванию).
  11. Прочитать и сохранить второй байт.
  12. Установить высокий уровень сигнала SS для того, чтобы в будущем можно было без задержек запустить следующее измерение.
  13. При необходимости немедленно выполнить еще одно измерение, установить низкий уровень сигнала SS (время нахождения сигнала SS в высоком уровне между двумя циклами измерения должно быть не меньше 0,24 мкс).
  14. Из полученных двух байтов взять первые 12 битов и записать их в переменную, предназначенную для результата.

Как видим, последовательность достаточно длинная, и нагрузка на МК оказывается значительной, если хочется выполнять измерения с частотой, близкой к максимальной.

И под конец еще более сложный пример ведомого устройства. Фирма Atmel производит микросхемы Flash-памяти с интерфейсом SPI . Рассмотрим особенности подключения микросхемы AT45DB161B с организацией 2M×8 бит. На рис. 12 изображена структурная схема устройства с указанием всех внешних выходов.


Рис. 12. Структура и выводы ИМС Flash-памяти AT45DB161B с интерфейсом SPI

Сигналы SI (MOSI), SO (MISO), SCK (SCK), CS (SS) образуют интерфейс, совместимый с SPI. Обмен с внутренним массивом Flash осуществляется через два буфера размером (512+16) байт. Внутреннее состояние «микросхема занята выполнением операции» либо «операция закончена, микросхема свободна» отражается состоянием сигнала RDY/BUSY. При выполнении длительных операций состояние этого сигнала можно анализировать программно, либо использовать механизм аппаратных прерываний.

Особенностью микросхемы Flash-памяти является то, что при обмене используются многобайтовые пакеты переменной длины. Первый байт каждого пакета является командой, а последующие байты содержат параметры или записываемые данные. Переход сигнала CS в активный (низкий) уровень отмечает начало пакета, а возврат сигнала CS в высокий уровень — конец пакета. Часть пакетов, предназначенных для чтения данных из Flashпамяти, имеют переменную длину. Структура заголовка команд чтения/записи изображена на рис. 13.


Рис. 13. Структура заголовка пакета, содержащего команду и адресную информацию

Как видно на рис. 13, первый байт содержит команду (код операции), а следующие три байта — два параметра: адрес страницы в Flash-массиве и адрес байта в странице, с которого требуется осуществить запись либо чтение. Параметры не выровнены по границам байтов, следовательно, заголовок должен быть сформирован программистом заранее, до начала передачи пакета.

SPI - Serial Peripheral Interface или «Последовательный периферийный интерфейс» - это синхронный протокол передачи данных для сопряжения ведущего устройства (Master) с периферийными устройствами (Slave) . Ведущим устройством часто является микроконтроллер. Связь между устройствами осуществляется по четырём проводам, поэтому SPI иногда называют «четырёхпроводной интерфейс». Вот эти шины:

Существует четыре режима передачи данных (SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3 ), обусловленные сочетанием полярности тактовых импульсов (работаем по уровню HIGH или LOW), Clock Polarity, CPOL , и фазой тактовых импульсов (синхронизация по переднему или заднему фронту тактового импульса), Clock Phase, CPHA . В последнем столбце таблицы приведены поясняющие иллюстрации. На них Sample обозначены моменты, когда данные на линии должны быть готовы и считываются устройствами. Буквой Z отмечено, что состояние данных на линии неизвестно или не важно.

Интерфейс SPI предусматривает несколько вариантов подключения ведомых устройств: независимое и каскадное . При независимом подключении к шине SPI ведущее устройство обращается к каждому ведомому устройству индивидуально. При каскадном подключении ведомые устройства срабатывают поочерёдно, как бы каскадом.


Виды подключения устройств для работы по интерфейсу SPI: независимое и каскадное

2 Реализация интерфейса SPI на платах семейства Arduino

В Arduino шины интерфейса SPI находятся на определённых портах. У каждой платы своё соответствие выводов. Для удобства выводы продублированы и вынесены также на отдельный разъём ICSP (In Circuit Serial Programming, программирование устройства, включённого в цепь, по последовательному протоколу). Обратите внимание, что на разъёме ICSP отсутствует пин выбора ведомого - SS, т.к. подразумевается, что Arduino будет использоваться как ведущее устройство в сети. Но при необходимости вы можете назначить любой цифровой вывод Ардуино в качестве SS.

На рисунке приведено стандартное соответствие выводов шинам SPI для Arduino UNO и Nano.


3 Стандартная библиотека для работы по интерфейсу SPI

Для Arduino написана специальная библиотека , которая реализует протокол SPI . Она устанавливается вместе со средой разработки Arduino IDE . Подключается она так: в начале программы добавляем #include SPI.h .

Чтобы начать работу по протоколу SPI , нужно задать настройки и затем инициализировать протокол с помощью процедуры SPI.beginTransaction() . Можно выполнить это одной инструкцией: SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0))

Это значит, что мы инициализируем протокол SPI на частоте 14 МГц, передача данных идёт, начиная с MSB (наиболее значимого бита), в режиме SPI_MODE0 .

После инициализации выбираем ведомое устройство, переводя соответствующий пин SS в состояние LOW . Затем передаём ведомому устройству данные командой SPI.transfer() . После передачи возвращаем SS в состояние HIGH .


Работа с протоколом завершается командой SPI.endTransaction() .

Желательно минимизировать время выполнения передачи между инструкциями SPI.beginTransaction() и SPI.endTransaction(), чтобы не возникло накладок, если другое устройство попробует инициализировать передачу данных, используя другие настройки.

Если вы планируете в своём скетче использовать стандартные пины Arduino, можно не описывать их в начале программы, т.к. они уже определены в самой библиотеке и имеют следующие имена:

#define PIN_SPI_SS (10) #define PIN_SPI_MOSI (11) #define PIN_SPI_MISO (12) #define PIN_SPI_SCK (13)

Данные пины определены в файле pins_arduino.h , который находится по пути %programfiles%\arduino-(версия)\hardware\arduino\avr\variants\ (если вы устанавливали программу в стандартное расположение). То есть, например, чтобы опустить пин выбора ведомого в состояние "0", можно написать:

DigitalWrite(PIN_SPI_SS, LOW);

4 Подключение сдвигового регистра к Arduino

Рассмотрим практическое применение интерфейса SPI . Будем зажигать светодиоды, управляя 8-битным сдвиговым регистром по шине SPI . Подключим к Arduino сдвиговый регистр 74HC595 . К каждому из 8-ми выходов регистра через ограничительный резистор подключим по светодиоду номиналом 220 Ом. Схема приводится на рисунке.


5 Скетч для управления сдвиговым регистром по интерфейсу SPI

Напишем скетч, реализующий «бегущую волну», последовательно зажигая светодиоды, подключённые к выходам сдвигового регистра.

#include const int pinSelect = 8; // пин выбора регистра void setup() { SPI.begin(); // инициализация интерфейса SPI pinMode(pinSelect, OUTPUT); // digitalWrite(pinSelect, LOW); // выбор ведомого устройств (регистра) SPI.transfer(0); // очищаем содержимое регистра digitalWrite(pinSelect, HIGH); // конец передачи Serial.begin(9600); } void loop() { for (int i=0; i }

Сначала подключим библиотеку SPI и инициализируем интерфейс SPI . Определим пин 8 как пин выбора ведомого устройства SS . Очистим сдвиговый регистр, послав в него значение "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, нам бы потребовалось для каждого светодиода использовать отдельный порт.

Мы изучили самый простой пример работы Arduino с шиной SPI . Более подробно рассмотрим работу нескольких сдвиговых регистров при независимом и каскадном подключениях в отдельной статье.

SPI (Serial Peripheral Bus ) - последовательный периферийный протокол обмена. Этот прокол был разработан компанией Motorola , но в настоящее время используется многими производителями. Он предназначен для связи микроконтроллеров между собой, а также со всевозможной периферией: датчиками, AЦП, микросхемами памяти, часами. Но все же наиболее частое применение SPI – это запись программы в память микроконтроллера. В микроконтроллерах AVR c помощью SPI можно прошить микроконтроллер не выпаивая из платы, такой способ прошивки называется ISP(In System Programming) . Хотя названия SPI и ISP очень созвучны, это не одно и то же, в AVR SPI используется как физический уровень ISP , то есть используются линии SPI для передачи данных, но сам протокол(программный уровень) отличается.

Для передачи данных в SPI используется три линии:

MISO(Master Input Slave Output) – по этой линии Master(ведущий) принимает данные от Slave(ведомого).

MOSI(Master Output Slave Input) – по этой линии Master отправляет данные Slave.

SCK(Serial Clock) – служит для передачи тактового сигнала ведомому устройству.

Также используется линия SS(Slave Select) , которая определяет устройство с которым Master будет обмениваться данными.

По причине того, что многие производители в своих устройствах используют SPI, названия выводов могут несколько отличаться. Ниже приведена таблица с альтернативными названиями.


SPI бывает двух видов аппаратный и программный. При реализации программного SPI , мы вручную должны устанавливать сигнал на ножках соответствующих MISO, MOSI, SS при этом дёргать за SCK . При аппаратной реализации SPI мы передаём данные в специальный регистр, а микроконтроллер сам проделывает вышеописанные манипуляции, по предварительным настройкам.

Физическая реализацию SPI , представляет собой два соединённых вместе сдвиговых регистра.


В зависимости от того по какому логическому уровню сигнала SCK , происходит синхронизация Master и Slave и по какому фронту происходит захват и сдвиг данных, возможны 4 режима SPI .

  • CPOL = 0 - сигнал синхронизации начинается с низкого уровня;
  • CPOL = 1 - сигнал синхронизации начинается с высокого уровня;
  • CPHA = 0 - выборка данных производится по переднему фронту сигнала синхронизации;
  • CPHA = 1 - выборка данных производится по заднему фронту сигнала синхронизации.
На осциллограммах ниже видно как выглядит посылка 0х17 в разных режимах.
CPOL = 0 CPHA = 0


CPOL = 1 CPHA = 0


CPOL = 0 CPHA = 1


CPOL = 1 CPHA = 1

SPI - синхронный интерфейс, то есть для того чтобы получить какие-нибудь данные от Slave , Master должен что-нибудь отправить. Вроде всё понятно, но что если Master отправляет один байт, а Slave должен вернуть ему два? В таком случае Master должен отправить ему что-нибудь 2 раза, например 0х00.
//отправляем команду, в ответ должно прийти два байта Spi_Master_Transmit(chx); //отправляем что-нибудь для того чтобы принять первый байт Spi_Master_Transmit(0X00); touch_x = SPDR; touch_x <<= 8; //отправляем что-нибудь для того чтобы принять второй байт Spi_Master_Transmit(0X00); touch_x |= SPDR; touch_x >>= 3;
На этом всё, выше пример кода взятый из рабочего проекта.

Если вы уже знаете что такое SPI интерфейс и с чем его едят, то вряд-ли вы почерпнете что-то новое из этой статьи. В ней я попробую рассказать основные понятия относящиеся к этому интерфейсу, а в следующей расскажу как использовать модуль SPI встроенный в микроконтроллеры STM32. Как и любой другой интерфейс, SPI используется для передачи данных от одного устройства к другому. Устройства на шине SPI не равноправны, как правило, присутствует одно главное устройство (Master) и множество подчинённых устройств (Slave). Обычно, в роли мастера выступает микроконтроллер, а подчинёнными устройствами является различная периферия вроде термодатчиков, акселерометров, часов реального времени итд. Мастер не просто так называется мастером, без его ведома ни один слейв не будет предпринимать ни какого обмена данными. Сама шина SPI физически представляет собой 4 провода:

  • MOSI – По этому проводу данные идут от Master к Slave устройству
  • MISO — По этому проводу данные идут от Slave к Master устройству
  • SCK — Через этот провод, Master передает тактовый сигнал к Slave устройствам
  • CS – Chip select (или SS – Slave select) – Через этот провод мастер дает понять слейву, что сейчас он шлёт данные именно ему.

Из описания всех четырёх линий можно сделать выводы:

  • SPI – это последовательный интерфейс. Биты данных передаются один за другим
  • SPI — это синхронный интерфейс. Это означает, что передача данных (в любую сторону) происходит только в то время когда мастер генерирует импульсы синхронизации и передает их через провод SCK другим устройствам на шине.
  • К одной шине может подключаться несколько устройств, количество которых теоритически не ограничено.
  • SPI предоставляет возможность обмениваться данными в полнодуплексном режиме. Пока мастер генерирует тактовые импульсы, он может посылать данные на слейв устройство и одновременно принимать их от него же.

Теперь рассмотрим, как устройства подключаются к шине. Стрелочки показывают кто и куда передает сигнал:

Как видно на рисунке, все линии интерфейса кроме CS, просто объединяются между собой. Для каждого слейв устройства, мастер имеет отдельный выход CS. Для того чтоб обменяться данными со вторым слейв устройством, мастер установит на ножке CS2 низкий логический уровень, а на двух других (CS1 и CS3) – высокий. Таким образом Slave_1 и Slave_3 не будут подавать вообще ни каких признаков жизни, и тем самым не создадут помех общению мастера и Slave_2. Еще раз подчеркну, что активное состояние ноги CS — это логический ноль. У такой схемы есть один недостаток – на 10 слейв устройств, мастер должен иметь 10 отдельных ног для подключения к CS. Существует другой вариант подключения который называется daisy-chain. При таком включении все устройства соединяются в цепочку и имеют один общий CS. Подробно этот способ включения рассматриваться не будет, в виду того, что используется он достаточно редко. Как уже упоминалось выше, к одной шине могут быть подключены самые разные slave устройства, некоторые из них достаточно быстрые и могут обмениваться данными с мастером на большой скорости, а некоторые наоборот очень медленные. Это значит, что мастер не должен слишком быстро генерировать тактовые импульсы, в противном случае медленные слейв устройства его не поймут из-за искажения данных. Однако скорость, это еще не все параметры SPI интерфейса, существует также 4 режима SPI. Я обращал внимание, что в даташитах на какое-либо устройство со SPI интерфейсом обычно так и пишут – «это устройство использует режим 2». Насколько это стандартизовано сказать не могу, но видел несколько раз. Если в двух словах описать суть этих режимов, то каждый из них определяет в какой момент (в зависимости от состояния линии SCK) нужно считывать/передавать данные. Следующая таблица показывает, что это за режимы и чем они отличаются друг от друга. Во всех 4-х режимах, мастер посылает один и тот же байт (0x93). Желтая линия это SCK, а синяя – MOSI.

Режим CPOL CPHA Осциллограмма Описание режима
0 0 0 Выборка по переднему нарастающему фронту
1 0 1 Выборка по заднему спадающему фронту
2 1 0 Выборка по переднему спадающему фронту
3 1 1 Выборка по заднему нарастающему фронту

Как видно из таблицы, номер режима состоит из двух бит – CPOL и CPHA . Бит CPOL определяет, в каком состоянии будет находиться нога SCL в то время когда ничего не передается. Если CPOL =0 то в режиме простоя на ноге низкий логический уровень. Это означает, что передний фронтом будет считаться переход из 0 в 1 (а задним фронтом соответственно наоборот из 1 в 0). Если CPOL =1 то в режиме простоя на ноге высокий логический уровень. Это означает, что передний фронтом будет считаться переход из 1 в 0 (а задним фронтом соответственно наоборот из 0 в 1). Бит CPHA определяет по какому фронту нужно производить выборку 0 – по переднему фронту, 1 – по заднему фронту. Собственно это всё и показывает таблица сверху. Кстати, примечательно, что точно так же эти два бита называются в регистре настройки SPI у микроконтроллеров STM32 и AVR. Следующий немаловажный параметр – порядок следования бит. Обычно, первым передается старший бит, но иногда бывает наоборот, если этого не учесть, то слейв и мастер не найдут общий язык. Количество бит может изменяться, обычно это 8 бит, иногда бывает больше. С теоритическими основами покончено. В следующей статье попробуем завести SPI на платке