Skip to main content

SPI

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

Основные характеристики:

  • работа в режиме «ведомого» и «ведущего»
  • работа в дуплексном и симплексном режимах
  • формат кадра 8 или 16 бит
  • максимальная скорость передачи соответствует системной частоте
  • отдельные буферы на прием и передачу глубиной 8 слов
  • фильтр по линии синхросигнала

Структурная схема

Структурная схема SPI интерфейса

SPI состоит из следующих блоков:

  • REGISTERS – блок для хранения управляющих данных и статусов;
  • FIFO_TX – буфер передатчика;
  • FIFO_RX – буфер приемника;
  • CONTROL – управляющий автомат модуля SPI;
  • SPI_INOUT – блок управления линиями интерфейса;
  • DATA_SYNCH – синхронизатор данных, производящий синхронизацию данных с системной частоты на частоту SCK и в обратном направлении;
  • SYNCHRONIZER – синхронизатор линии SCK, работающий по требованию пользователя;
  • FILTER – фильтр линии SCK, избавляющий от помех;
  • MULTIPLEXOR – мультиплексор, выбирающий частоту тактирования блока SPI_INOUT в зависимости от входных настроек.

Алгоритмы работы

В режиме «ведущий» модуль автоматически генерирует синхросигнал для ведомого устройства по линии SCK.

Процедура работы с ведущим

  • задействовать один из свободных выводов GPIO как CS, настроев его на выход и переведя в «1»;
  • в регистре SPI_MSK разрешить необходимые прерывания;
  • в регистре SPI_CFG2 установить биты BR для определения скорости обмена;
  • в регистре SPI_CFG0:
    • определить формат данных с помощью бита DWW;
    • настроить формат кадра при помощи бита BO;
    • установить биты POL и PHA для определения соответствия между данными и синхросигналом (настройка должна быть одинакова для ведущего и для ведомого);
    • установить бит MOD для перехода в режим «ведущий».
  • для режимов, связанных с передачей данных необходимо записать отправляемую информацию в регистры SPI_TX1 и SPI_TX0 (необходимо записать столько слов данных, сколько необходимо отправить за данную передачу; имеется возможность отправить более 8 слов в режимах с PHA в «1», дописывая слова по опустошению буфера передатчика);
  • перевести CS в «0», используя ранее настроенный GPIO, таким образом разрешив работу ведомому устройству;
  • в регистре SPI_CTRL разрешить работу модуля битом EN;
  • на основании данных регистра SPI_ST установить момент завершения передачи, перевести CS в «1» и выключить модуль битом EN в регистре SPI_CTRL;
  • принимаемые данные можно вычитать из регистров SPI_RX1 и SPI_RX0;
  • при необходимости продолжить работу с процедуры записи отправляемой информации или следующей за ней процедуры.

В данном формате MOSI работает как выход данных, а MISO как вход данных. Так как CS задается через вывод GPIO, пользователю необходимо самостоятельно выдерживать задержки между фронтами SCK и CS в начале и конце передачи данных. Минимальная задержка перед первым фронтом SCK определяется временем записи бита EN в регистр SPI_CTRL.

В режиме «ведомый» синхросигнал поступает от ведущего устройства. Значение бит BR не влияет на работу модуля. Рекомендуется включить модуль до того, как начнет передаваться синхросигнал, иначе будут приняты сдвинутые данные. Буфер передатчика должен содержать данные до первого изменения синхросигнала, иначе отправляемые данные могут быть искажены при перезаписи в сдвиговый регистр.

Процедура работы с ведомым

  • в регистре SPI_MSK разрешить необходимые прерывания;
  • в регистре SPI_CFG0:
    • определить формат данных с помощью бита DWW;
    • настроить формат кадра при помощи бита BO;
    • установить биты POL и PHA для определения соответствия между данными и синхросигналом (настройка должна быть одинакова для ведущего и для ведомого);
    • установить бит MOD для перехода в режим «ведомый».
  • в регистре SPI_CTRL разрешить работу модуля битом EN;
  • для режимов, связанных с передачей данных необходимо записать отправляемую информацию в регистры SPI_TX1 и SPI_TX0;
  • на основании данных регистра SPI_ST установить момент завершения передачи;
  • принимаемые данные можно вычитать из регистров SPI_RX1 и SPI_RX0;
  • при необходимости продолжить передачу данных с процедуры записи отправляемой информации или следующей за ней процедуры.

В данном формате MOSI работает как вход данных, MISO как выход данных.

Дуплексный и симплексный режимы

SPI может работать в двух конфигурациях:

  • две однонаправленные линии данных;
  • одна двунаправленная линия данных (режим «только прием» или «только передача»).

Две однонаправленные линии данных (стандартный режим). Активируется, когда бит TR_MOD регистра SPI_CFG0 равен «0». Бит RXO регистра SPI_CFG1 задает режим передачи данных. Если RXO неактивен, то модуль работает как на прием, так и на передачу. Если RXO активен, то модуль работает только на прием. Ведущий постоянно генерирует синхросигнал для ведомого. Линия передачи остается незадействованной. У ведущего это линия MOSI, у ведомого – MISO.

Одна двунаправленная линия данных. Режим активируется, когда бит TR_MOD регистра SPI_CFG0 равен «1». В данном режиме модуль SPI работает только на прием, либо только на передачу, 
что определяется битом EN_TX. У ведущего для приема и передачи используется линия MOSI, у ведомого MISO. MISO у ведущего или MOSI у ведомого не используется. В режиме «только прием» ведущий постоянно генерирует синхросигнал для ведомого. В режиме «только передача» необходимо игнорировать состояние принимающего буфера.

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

В соответствии с требованиями протокола SPI, в зависимости от настройки модуля, данные передаются на линию либо по фронту, либо по спаду синхросигнала. Передача начинается 
при наличии данных в буфере передатчика. Данные поступают в сдвиговый регистр и далее биты слова передаются последовательно старшим или младшим вперед в зависимости от настройки BO. Установка бита TXB_E, сообщает о том, что буфер передатчика опустел, но данные еще могут находится в сдвиговом регистре, следовательно, будет продолжаться их передача. Об окончании передачи последнего слова данных сообщает бит NULL_BUF. С этого момента генерация синхросигнала будет остановлена, до новой записи в буфер передатчика.

Буфер рассчитан на 8 слов. При переполнении буфера передатчика в регистре SPI_ST устанавливается бит TXB_OV. Записываемое слово будет утеряно. Пользователь имеет возможность очистить буфер передатчика путем записи в бит TXBS_RST единицы.

По битам TXB_E, NULL_BUF, TXB_OV может быть настроено прерывание в регистре SPI_MSK.

Прием данных

В соответствии с требованиями протокола SPI, в зависимости от настройки модуля, данные фиксируются по фронту, либо по спаду синхросигнала. Биты последовательно заполняют сдвиговый регистр. Затем из сдвигового регистра принятые данные поступают в буфер приемника. Когда в буфер передано хотя бы одно слово данных, в регистре SPI_ST выставляется бит RX_NE.

Буфер рассчитан на 8 слов данных. Пользователь может последовательно вычитать принятые данные или очистить буфер путем записи бита RXBS_RST в регистр SPI_CTRL во избежание переполнения. В случае, когда буфер заполнен, приход нового слова данных вызовет установку бита RXB_OV регистра SPI_ST. Само слово записано не будет.

В режиме «только передача» данные в буфере приемника не фиксируются.

По битам RX_NE, RXB_OV может быть настроено прерывание в регистре SPI_MSK.

Работа с входом выбора микросхемы

Модуль SPI имеет в своем составе вход выбора микросхемы – I_CS.

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

Пользователь может перейти в программный режим управлением входа I_CS с помощью бита SS_CTRL регистра SPI_CFG0. Далее пользователю достаточно имитировать необходимый логический уровень с помощью бита SSS регистра SPI_CTRL. В остальном принцип работы модуля полностью соответствует работе в аппаратном режиме.

Особенности работы в режиме «ведомый». Синхронизация и фильтрация

Модуль SPI может вести прием и передачу данных на системной частоте и близкой к ней. Однако это накладывает ограничение на работу с буфером передатчика в режиме «ведомый». Данные в буфер должны быть гарантированно записаны до выдачи последнего бита данных из сдвигового регистра передатчика в режимах с PHA «0» или до первого изменения SCK перед началом передачи нового слова в режимах с PHA «1», либо же после полного окончания передачи (актуально если отправляется несколько слов в одной посылке, часть которых дописывается в процессе отправки данных). В противном случае, слово, которое было записано в нарушении этих требований, может быть искажено. Данное ограничение можно избежать, если разрешить работу синхронизатора. В таком случае в сдвиговый регистр будут записаны новые данные или нули.

Модуль SPI оснащен синхронизатором синхросигнала. Для включения синхронизатора необходимо записать «1» в бит SYN регистра SPI_CFG1. Синхронизатор вносит задержку в два такта системной частоты. Значит для корректного приема и передачи данных синхрочастота должна быть уменьшена 
и соотносится с системной как FCLK/7.

Модуль SPI оснащен фильтром синхрочастоты. Для включения фильтра необходимо записать «1» в бит FIL регистра SPI_CFG1. Не рекомендуется включать фильтр независимо от синхронизатора. Фильтр может сгладить один сбой на промежутке времени, соответствующем трем тактам системной частоты. При этом частота синхросигнала также должна быть понижена.

С учетом включенного синхронизатора и фильтра частота синхросигнала должна быть меньше системной частоты минимум в 13 раз.

Также при работе на системной частоте или близкой к ней необходимо учитывать, что синхронизация CS занимает 1-2 такта частоты микроконтроллера. Поэтому после перехода CS 
в «0» необходимо сделать паузу 3-4 такта частоты микроконтроллера перед началом подачи SCK. В случае PHA равной «0» первый бит данных поступит на MISO по синхронизированному CS c буфера передатчика. Захват данных с буфера в сдвиговый регистр происходит на первом такте SCK по фронту или срезу в зависимости от POL (аналогично в режимах с PHA равной «1»). После приема последнего бита сообщения данные поступят в буфер приемника через 2-3 такта частоты микроконтроллера. Останется ли CS в «0» или перейдет в «1» не имеет значения. MISO перейдет в Z-состояния через 1-2 такта после перехода CS в «0». Ниже на рисунке представлен лучший вариант передачи в режиме «00», так как не потребовалось дополнительных тактов на синхронизацию.

Передача данных в режиме «ведомый» на частоте микроконтроллера

Как видно на рисунке новые данные поступают в сдвиговый регистр по последнему срезу (или фронту в зависимости от POL) SCK в режимах с PHA «0». Если буфер пуст, то это будут нули. В режимах с PHA «1» новые данные поступают в сдвиговый регистр по первому фронту (или срезу) первого бита нового слова. Из этого следует, что в режимах с PHA «1» пользователь может делать паузы между передачами слов данных в рамках одной передачи SPI, во время которых ведомый микроконтроллер может обработать только что полученные данные и записать результат в буфер передатчика.

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

Регистры SPI

АббревиатураДоступОписание
SPI0
2600hSPI0_CTRLRWРегистр управления
2604hSPI0_CFG0RWРегистр конфигурации 0
2605hSPI0_CFG1RWРегистр конфигурации 1
2606hSPI0_CFG2RWРегистр конфигурации 2
2607hSPI0_CFG3RWРегистр конфигурации 3
2608hSPI0_MSKRWРегистр маски
260ChSPI0_STRРегистр статуса
2610hSPI0_TX0WРегистр для записи данных в буфер передатчика 0
2611hSPI0_TX1WРегистр для записи данных в буфер передатчика 1
2610hSPI0_RX0RРегистр для чтения принятых данных 0
2611hSPI0_RX1RРегистр для чтения принятых данных 1
SPI1
2700hSPI1_CTRLRWРегистр управления
2704hSPI1_CFG0RWРегистр конфигурации 0
2705hSPI1_CFG1RWРегистр конфигурации 1
2706hSPI1_CFG2RWРегистр конфигурации 2
2707hSPI1_CFG3RWРегистр конфигурации 3
2708hSPI01_MSKRWРегистр маски
270ChSPI1_STRРегистр статуса
2710hSPI1_TX0WРегистр для записи данных в буфер передатчика 0
2711hSPI1_TX1WРегистр для записи данных в буфер передатчика 1
2710hSPI1_RX0RРегистр для чтения принятых данных 0
2711hSPI1_RX1RРегистр для чтения принятых данных 1

SPIx_CTRL

Бит76543210
НазначениеРезервSSSTXBS_RSTRXBS_RSTEN
Начальное значение0

SSS (Slave Select Signal) – состояние этого бита воздействует на устройство только 
при установленном бите SS_CTRL (при программном управлении I_CS):

  • 1 – имитировать высокий логический уровень;
  • 0 – имитировать низкий логический уровень.

Значение этого бита принудительно заменяет состояние входа I_CS, которое при этом игнорируется.

TXBS_RST (Transmitter Buffer Set Reset) – сброс состояния буфера передатчика:

  • 1 – сброс состояния буфера;
  • 0 – сброс неактивен.

Сброс записанной «1» происходит аппаратно через один такт.

RXBS_RST (Receiver Buffer Set Reset) – сброс состояния буфера приемника:

  • 1 – сброс состояния буфера;
  • 0 – сброс неактивен.

Сброс записанной «1» происходит аппаратно через один такт.

EN – включение модуля SPI:

  • 1 – модуль включен;
  • 0 – модуль выключен.

SPIx_CFG0

Бит76543210
НазначениеEN_TXTR_MODSS_CTRLDWWBOPOLPHAMOD
Начальное значение0

EN_TX– в режиме двунаправленного обмена данными по одной линии, разрешает или запрещает передачу данных:

  • 1 – выход активен (только передача данных);
  • 0 – выход неактивен (только прием данных).

TR_MOD– разрешает или запрещает использование двунаправленного режима обмена данными 
по одной линии:

  • 1 – режим 1-ой двунаправленной линии данных;
  • 0 – режим 2-х однонаправленных линий данных.

SS_CTRL (Slave Signal Control) – программное управление выбором устройства:

  • 1 – программный контроль включен;
  • 0 – программный контроль выключен.

Когда этот бит установлен, вместо уровня на входе I_CS учитывается состояние бита SSS.

DWW (Data Word Width) – формат данных:

  • 1 – 16 бит;
  • 0 – 8 бит.

BO (Bit Order) – порядок передачи данных:

  • 1 – первым передается младший значащий разряд – LSB;
  • 0 – первым передается старший значащий разряд – MSB.

POL – полярность тактового сигнала:

  • 1 – высокий уровень в режиме ожидания на выводе SCK;
  • 0 – низкий уровень в режиме ожидания на выводе SCK.

PHA – фаза тактового сигнала:

  • 1 – строб данных происходит по второму перепаду тактового сигнала;
  • 0 – строб данных происходит по первому перепаду тактового сигнала.

MOD – выбор режима:

  • 1 – режим «ведущий»;
  • 0 – режим «ведомый».

SPIx_CFG1

Бит76543210
НазначениеFILSYNRXO
Начальное значение0

FIL – разрешение работы фильтра I_SCK:

  • 1 – I_SCK передается через фильтр;
  • 0 – I_SCK передается без фильтрации.

Фильтр необходимо включать вместе с синхронизатором. Скорость сигнала I_SCK при включенном синхронизаторе и фильтре должна быть не более FCLK/13.

SYN – разрешение работы синхронизаторов I_SCK:

  • 1 – I_SCK передается через два триггера;
  • 0 – I_SCK передается напрямую.

Скорость сигнала I_SCK при включенном синхронизаторе должна быть не более FCLK/7:

RXO (Receive Only) – только прием:

  • 1 – выход отключен (только прием данных);
  • 0 – полнодуплексный режим (передача и прием данных).

В комбинации с битом TR_MOD задает направление передачи данных.

SPIx_CFG2

Бит76543210
НазначениеBR
Начальное значение0

BR (Bit Rate) – выбор скорости обмена:

  • 255 – FCLK/510
  • 3 – FCLK/6
  • 2 – FCLK/4
  • 1 – FCLK/2
  • 0 – FCLK

SPIx_CFG3

Бит76543210
НазначениеРезервSOCS
Начальное значение0

SOCS (Set Output Chip Select) – выбор ведомого устройства:

  • 1 – ведомое устройство выбрано (сигнал O_CS переходит в «0»);
  • 0 – ведомое устройство не выбрано (сигнал O_CS в «1»).

SPIx_MSK

Прерывания формируется, только если модуль включен.

Бит76543210
НазначениеРезервNULL_BUFRX_NEMOD_FAILTXB_ERXB_OV
Начальное значение0

Для каждого из битов справедливо:

  • 1 – данное прерывание формируется;
  • 0 – данное прерывание не формируется.

SPIx_ST

Бит76543210
НазначениеРезервNULL_BUFBUSYTXB_OVRX_NEMOD_FAILTXB_ERXB_OV
Тип статусаEVENTFLAGEVENTFLAGEVENTFLAGEVENT
Начальное значение010

NULL_BUF – зафиксирован пустой буфер передатчика на момент окончания выдачи слова.

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

TXB_OV (Transmitter Buffer Overwrite) – переполнение буфера передатчика. Сообщает о том, что пользователь пытается записать слово данных в уже заполненный буфер передатчика. Записываемое слово будет утеряно. Прерывание по данному биту отсутствует.

RX_NE (Receiver Not Empty) – в буфере приемника содержится хотя бы одно слово данных. Если пользователь сбросит буфер или вычитает все слова, то бит перейдет в неактивное состояние.

MOD_FAIL – вход I_CS был переведен в низкий логический уровень в режиме «ведущий». Данная ситуация возможна при включенном модуле только, если выбрана соответственная альтернативная функция GPIO или выбран программный контроль линии I_CS битом SS_CTRL регистра SPI_CFG0 и бит SSS регистра SPI_CTRL в «0».

TXB_E (Transmitter Buffer Empty) – буфер передатчика пуст. Статус переходит в неактивный уровень, когда в буфер будет записано хотя бы одно слово данных. Стоит учитывать, что записанное слово переместится в сдвиговый регистр, как только тот опустеет и буфер опять окажется пустым.

RXB_OV (Receiver Buffer Overwrite) – буфер приемника переполнен, а значит он уже потерял одно из принимаемых слов данных. Для того, чтобы такой ситуации не происходило необходимо вычитывать принимаемые данные из буфера через регистр SPI_RX.

SPIx_TX0

При записи в данный регистр в буфер передатчика записываются старшая и младшая часть данных.

Бит76543210
НазначениеDATA_TX
Начальное значение0

DATA_TX – данные на передачу, младшая часть.

SPIx_TX1

Бит76543210
НазначениеDATA_TX
Начальное значение0

DATA_TX – данные на передачу, старшая часть.

SPIx_RX0

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

Бит76543210
НазначениеDATA_RX
Начальное значение0

DATA_RX – принятые данные, младшая часть.

SPIx_RX1

Бит76543210
НазначениеDATA_RX
Начальное значение0

DATA_RX – принятые данные, старшая часть.