spi nss что это

SPI STM32.

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

Miso(Master In / Slave Out data) — в зависимости от режима вывод может быть настроен как вход или выход, вход в режиме Master и выход в режиме Slave

Mosi(Master Out / Slave In data) – тут наоборот, выход в режиме Master и вход в режиме Slave

SCK – тактовый сигнал, генерируемый Master.

NSS – вывод предназначен для выбора подчинённого устройства в режиме Slave, при подаче на его вход логического ноля, также с помощью этого вывода можно переключать режимы SPI (Master/Slave), в мультимастерной шине.

Итак, вывод NSS работает не совсем так, как привычный CS у AVR, и в режиме Master для выбора ведомого необходимо использовать GPIO.

В режиме Slave сигнал(Сhip Select) можно получить с вывода NSS или программно, зависит это от значения бита SSM, если он сброшен, то считывается состояние вывода NSS, иначе определяющим является состояние бита SSI. Для приёма данных в таком случае(при программном управлении) необходимо установить SSM = 1, SSI = 0.

В режиме Master, вывод необходимо подтянуть к питанию или включить программную подтяжку (SSM =1, SSI = 1). В случае программной подтяжки вывод можно использовать как обычный GPIO.

Возможен ещё один вариант SSM = 0, SSOE = 0, вывод NSS настроен как вход с подтяжкой к питанию, при появлении на нём низкого уровня, SPI модуль подумает что появился новый Master и сам станет Slave, такой вариант используется в мультимастерной шине.

Так выглядит подключение одного Master к Slave.

Шина SPI представляет собой два последовательно соединённых между собой сдвиговых регистра и по каждому тактовому импульсу данные в регистрах сдвигаются. То есть по каждому тактовому импульсу один бит уходит из регистра, остальные биты сдвигаются к выходу, а на входе появляется свободное место, его и занимает вновь пришедший бит.

Ниже представлена блочная диаграмма модуля SPI.

На диаграмме видно, что модуль состоит из двух регистров у правления и регистра статуса, давайте рассмотрим какой бит в регистрах за что отвечает. Хотелось отметить, что изменять состояние большинства битов можно только, когда SPI выключен(SPE = 0).

Регистр управления SPI_CR1:

BIDIMODE(Bidirectional data mode enable) — если записать в этот бит единицу данные будут передаваться в двух направлениях по одной линии(однопроводной режим), если ноль —по двум линиям. При двунаправленной передаче master использует вывод MOSI, а slave вывод MISO.

BIDIOE(Output enable in bidirectional mode) — этот бит используется для настройки однопроводного режима, 1 — данные только передаются, 0 — данные только принимаются.

CRCEN(Hardware CRC calculation enable) — запись единицы в этот бит, разрешает аппаратный подсчёт CRC, 0 – запрещает.

CRCNEXT(CRC transfer next) – если этот бит установлен, это говорит о том следующей будет передаваться контрольная сумма.

DFF(Data frame format) – этот бит определяет формат фрейма, 0 — 8 бит, 1 — 16 бит.

RXONLY(Receive only) – этот бит используется в двухпроводном режиме, его установка в единицу запрещает передачу и модуль SPI работает только на приём, иначе на приём и передачу.

SSM(Software slave management) — программное управление NSS, когда этот бит установлен вместо уровня на входе NSS контролируется состояние бита SSI, если сброшен — контролируется состояние вывода NSS.

SSI(Internal slave select) — этот бит имеет силу только при установленном SSM, его значение заменяет состояние на выводе NSS.

LSBFIRST(Frame format) — определяет формат фрейма, 1 — младшим битом вперёд, 0 — старшим битом вперёд.

SPE(SPI enable) — единица в этом бите включает модуль SPI, 0 – выключает.

BR[2:0](Baud rate control) — данные биты определяют скорость передачи данных.

MSTR(Master selection) — определяет режим работы, 1 —Master, 0 — Slave.

CPOL(Clock polarity) — определяет полярность в режиме ожидания, 0 — низкий уровень в режиме ожидания, 1 — высокий уровень в режиме ожидания.

CPHA(Clock phase) – задаёт фазу тактового сигнала, 0 — выборка данных производится по переднему фронту сигнала синхронизации, 1 — выборка данных производится по заднему фронту сигнала синхронизации.

Регистр управления SPI_CR2 :

TXEIE(Tx buffer empty interrupt enable) — единица в этом бите разрешает прерывание, когда буфер передачи пуст.

RXNEIE(RX buffer not empty interrupt enable) — единица в этом бите разрешает прерывание когда буфер не пуст.

ERRIE(Error interrupt enable) — единица в этом бите разрешает прерывание при возникновении ошибки, о которой сигнализируют биты CRCERR, OVR, MODF.

SSOE(SS output enable) — единица в этом бите, разрешает использовать вывод NSS в качестве выхода и модуль SPI сам управляет выводом NSS, но управляет ним по следующему алгоритму: при включении модуля SPI(SPE = 1) на NSS появляется низкий уровень и сохраняется пока модуль не будет выключен(SPE = 0), что в большинстве случаев не подходит, поэтому для этих целей использую GPIO, а на NSS в режиме Master программно выставляю единицу(SSM = 1, SSI = 1).

TXDMAEN(Tx buffer DMA enable) — разрешает/запрещает формировать запрос к DMA при появлении флага TXE(по завершении передачи).

RXDMAEN(Rx buffer DMA enable) — разрешает/запрещает формировать запрос к DMA при появлении флага RXE(по завершении приёма).

Регистр статуса SPI_SR:

BSY(Busy flag) — флаг занятости, предназначен для отслеживания состояния сдвигового регистра, устанавливается аппаратно во время обмена данными, а точнее с момента когда данные из регистра SPI_DR поступают в сдвиговый регистр, сбрасывается при опустошении сдвигового регистра, то есть когда все данные ушли в линию MOSI.
Производители не советуют проверять его при приёме и передаче, вместо этого советуют пользоваться флагами TXE и RXNE.

OVR(Overrun flag) – устанавливается при переполнении буфера, когда новые данные перезаписали старые, которые ещё не были прочитаны.

MODF(Mode fault) — устанавливается если в режиме Master на вход NSS поступает сигнал низкого уровня, и он становится Slave. Сбросить его можно с помощью специальной последовательности.

CRCERR(CRC error flag) – флаг ошибки контрольной суммы.

TXE(Transmit buffer empty) – устанавливается когда буфер передачи(регистр SPI_DR) пуст, очищается при загрузке данных

RXNE(Receive buffer not empty) — устанавливается когда приёмный буфер содержит данные, очищается при считывании данных.

SPI_DR (Data register) – регистр данных, фактически он состоит из двух буферов: приёма и передачи, но мы работаем только с регистром DR, поэтому для отправки данных пишем в регистр DR, для приёма читаем его же.

SPI_CRCPR (CRC polynomial register) – содержит полином для расчёта CRC, после сброса его значение равно 0x0007.

Читайте также:  какие функции позволяет выполнять аис сго

SPI_RXCRCR (Rx CRC register) – содержит вычисленную CRC принятых данных.

SPI_TXCRCR (Tx CRC register) – содержит вычисленную CRC передаваемых данных.

Источник

Spi nss что это


Рис. %img:stm_c1. Типичный вариант подключения устройства по SPI.

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

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

Обобщённо, без привязки к конкретной реализации, данный интерфейс рассматривается в статье «SPI».

Здесь уделим внимание особенностям реализации SPI в микроконтроллерах STM, в том числе рассмотрим специфичные, редко используемые режимы работы. Для быстрого ознакомления с вопросами практического использования SPI, смотрите «Примеры использования SPI в STM32».

Введение

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

Естественно, что SPI может быть сконфигурирован для работы в качестве ведущего или ведомого устройства (в режиме ведущего устройства SPI является источником тактового сигнала SCK для ведомого устройства; соответственно, ведомое устройство получает тактовый сигнал от другого устройства, работающего в режиме ведущего). Интерфейс допускает конфигурации с несколькими ведущими устройствами. Кроме обычной полнодуплексной синхронной передачи по двум линиям, предусмотрена возможность передачи данных в одну сторону по одной линии; поддерживается полудуплексная связь по одной двунаправленной линии. Имеются средства для поддержки надёжной связи (CRC контроль целостности данных).

Рассмотрим подробнее эти и другие возможности SPI в микроконтроллерах STM32.

Предупреждение. Некоторые выводы устройств SPI1, SPI3 и выводы интерфейса JTAG могут иметь привязку к общим внешним выводам в некоторых моделях микроконтроллеров. Тогда для использования такого SPI можно:
— отключить JTAG, а для отладки использовать интерфейс SWD;
— отключить как JTAG, так и SWD интерфейс для автономных, не требующих отладки приложений.

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

Интерфейс SPI в микроконтроллерах STM32F100xx имеет следующие основные возможности.

Устройство SPI

На рисунке %img:spi_bd изображена блок-схема SPI в микроконтроллерах STM32F100xx, а с учётом высокой степени совместимости разных семейств микроконтроллеров STM между собой, она применима и ко многим другим устройствам.


Рис. %img:spi_bd

Обычно для подключения внешнего устройства к SPI используется 4 вывода.

Вывод NSS ведущего устройства может быть входом (обычно используется при наличии нескольких ведущих устройств на шине) или выходом (только если на шине только одно ведущее устройство). Режим выхода для ведущего устройства включается установкой бита SSOE (регистр SPI_CR2). В таком случае, на выходе NSS ведущего устройства устанавливается низкий уровень, когда начинается обмен данными и остаётся на низком уровне до отключения SPI. NSS как выход довольно бесполезен: если ведомое устройство одно, зачастую можно обойтись вообще без сигнала NSS; если ведомых устройств несколько, в любом случае необходимо наличие у ведущего устройства нескольких выводов NSS. А поскольку аппаратный вывод NSS только один, то всё равно потребуется формирование нужного количества сигналов NSS программными средствами с использованием стандартных портов ввода-вывода.

Пример варианта соединения между единственным ведущим и единственным ведомым устройством изображён на рис. %img:inter2. Здесь у обоих устройств вывод NSS сконфигурирован как вход. Ещё проще настроить NSS ведущего устройства как выход и оставить его неподключённым.


Рис. %img:inter2

Типичный вариант подключения, когда задействованы все линии интерфейса, изображён на рис. %img:inter3. Здесь NSS является выходом у ведущего устройства и входом у ведомого, выбор ведомого осуществляется низким уровнем сигнала NSS.


Рис. %img:inter3

Как видно из рисунков, для подключения по SPI, одноимённые выводы объединяемых устройств подключаются вместе (выводы MOSI устройств соединяются вместе, выводы MISO соединяются вместе, выводы SCK соединяются вместе). Использование NSS зависит от того, каким образом сконфигурированы устройства.

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

Преобразование данных из параллельной формы, в которой данные пересылаются по шине микроконтроллера, в последовательную форму для передачи через SPI, осуществляется с помощью регистра сдвига, Shift register на рис. %img:spi_bd. Данные, предназначенные для передачи через SPI, загружаются в этот регистр из буферного регистра Tx. Когда завершается передача-приём очередного фрейма по SPI и полученный фрейм оказывается в регистре сдвига, содержимое регистра сдвига помещается в буферный регистр Rx. Программный доступ к регистрам осуществляется посредством регистра SPI_DR: при записи в него, данные помещаются в Tx; при чтении из регистра, получаем данные из Rx.

Прежде чем выполнять запись в SPI_DR, следует убедиться в том, что установлен флаг TXE в регистре SPI_SR, который свидетельствует, что буфер Tx в данный момент пуст (помещённые в него ранее данные уже перемещены в регистр сдвига, либо никакие данные в него ещё не записывались). О том, что в регистре Rx содержатся новые данные, полученные по SPI, сигнализирует флаг SPI_RXNE.

Управление выбором ведомого устройства

Выбор ведомого устройства может осуществляться аппаратно или программно, в зависимости от значения бита SSM в регистре SPI_CR1.

Полярность и фаза тактового сигнала

Имеется четыре возможных варианта тактирования передаваемых данных, которые выбираются с помощью битов CPOL и CPHA в регистре SPI_CR1. Биты влияют на работу SPI как в ведущем, так и в ведомом режиме.

Бит CPOL контролирует полярность сигнала SCK, т.е. начальный (пассивный) уровень тактового сигнала, который он имеет до начала пересылки данных и в паузах между передачами. Этот уровень совпадает со значением бита: если бит сброшен, низкий уровень является начальным для тактового сигнала; если бит CPOL установлен, начальным является высокий уровень.

Бит CPHA контролирует фазу тактового сигнала. Если бит CPHA сброшен, то первый фронт сигнала на выводе SCK (нарастающий, если CPOL = 0; спадающий, если CPOL = 1) является первым стробирующим импульсом, по которому фиксируется первый передаваемый бит фрейма. Если бит CPHA установлен, то второй фронт на выводе SCK (спадающий, если CPOL = 0; нарастающий, если CPOL = 1) является первым стробирующим импульсом и фиксирует первый передаваемый бит данных.

Читайте также:  близнецы что за планета

Последующие биты фрейма также будут фиксироваться по нарастающим или спадающим фронтам тактового сигнала, в зависимости от комбинации битов CPOL и CPHA.

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


Рис. %img:transfer

Примечание. Изменять биты CPOL/CPHA допускается только при отключённом SPI (т.е. при сброшенном бите SPE). Поэтому, если необходимо изменить настройки тактового сигнала в процессе работы, сначала следует отключить SPI (о правильном отключении в разных режимах, без риска потери данных, смотрите: «Правильное отключение SPI»). Изменение настроек в процессе работы может потребоваться, например, если к одной SPI шине подключено несколько ведомых устройств, для которых необходимы разные варианты тактирования.

Хотя на рисунке показан случай, когда первым передаётся старший бит фрейма, установка бита LSBFIRST в регистре SPI_CR1 позволяет изменить порядок передачи битов (младший бит первым).

Имеется возможность выбора длины фрейма (8 или 16 бит) с помощью бита DFF в регистре SPI_CR1.

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

Источник

Программирование STM32. Часть 6: SPI

В этой статье мы научимся работать с модулем SPI в микроконтроллере STM32F103C8 в режиме Master с использованием прерываний и без них. Предыдущая статья здесь, все статьи цикла можно посмотреть тут: http://dimoon.ru/category/obuchalka/stm32f1.

SPI является самым популярным последовательным синхронным интерфейсом передачи данных между микроконтроллером и периферийными устройствами. В составе STM32F103C8 есть два модуля SPI. Этот интерфейс может работать в режиме Master (ведущий шины) или Slave (ведомый шины). Вообще говоря, интерфейс SPI является довольно навороченной штукой. Конкретно в STM32 SPI может подсчитывать контрольную сумму принятых и переданных кадров по заданному полиному, работать в Multimaster mode, аппаратно работать с выводом NSS, а так же обмениваться данными в полудуплексном режиме (MOSI и MISO идут по одному и тому же проводу). Поэтому для правильной настройки SPI нужно внимательно изучить все регистры этого модуля. Ну и еще один момент: SPI в STM32 может работать в режиме I2S (не путать с I2C. ). I2S — это SPI-подобный интерфейс передачи данных между цифровыми аудиоустройствами. Пусть это вас не смущает, по-умолчанию этот модуль работает в режиме SPI и регистры, которые нужны только для I2S режима мы рассматривать не будем.

Для связи двух или нескольких устройств необходимо 4 провода (+земля, куда же без нее):

Стоит отметить, что если мы только читаем данные из ведомого устройства, то нам нужны только провода SCK и MISO, а если только пишем в ведомое то SCK и MOSI.

Регистры SPI

Тут приведу описание регистров, которые относятся только к SPI. Все, что касается I2S выкинул.

SPI control register 1 (SPI_CR1)

Рис. 1. Регистр SPI_CR1

BIDIMODE: Разрешение двунаправленного режима работы вывода данных.

BIDIOE: Разрешение выхода в двунаправленном режиме

Этот бит, совместно с битом BIDIMODE, выбирает направление передачи в двунаправленном режиме. В режиме master для передачи данных используется вывод MOSI, в режиме slave используется вывод MISO.

CRCEN: Включение аппаратного подсчета CRC

CRCNEXT: Следующая передача данных будет завершаться CRC-кодом.

DFF: Формат кадра данных

RXONLY: Этот бит совместно с BIDIMODE выбирает направление передачи в 2-х проводном (MISO и MISO) режиме.

SSM: Программное управление ведомым устройством. Когда бит SSM установлен, сигнал NSS заменяется значением бита SSI.

SSI: Внутренний выбор ведомого. Этот бит работает только когда бит SSM установлен. Значение этого бита принудительно подается на NSS, а значение IO вывода NSS игнорируется.

LSBFIRST: Формат кадра

SPE: Включить SPI

BR[2:0]: Выбор скорости передачи

MSTR: Выбор режима работы SPI: Master/Slave

CPOL: Полярность тактового сигнала

CPHA: Фаза тактового сигнала

SPI control register 2 (SPI_CR2)

Рис. 2. Регистр SPI_CR2

TXEIE: Прерывание опустошения буфера передачи данных Tx

RXNEIE: Прерывание не пустого буфера приема Rx

ERRIE: Прерывание при возникновении ошибок передачи. Этот бит контролирует генерацию прерывания при возникновении одной из ошибок интерфейса SPI (CRCERR, OVR, MODF).

SSOE: Разрешить выход SS

TXDMAEN: Когда этот бит установлен, запрос DMA возникает при установке флага TXE

RXDMAEN: Когда этот бит установлен, запрос DMA возникает при установке флага RXNE

SPI status register (SPI_SR)

Рис. 3. Регистр SPI_SR

BSY: Флаг занятости. Этот флаг устанавливается и сбрасывается аппаратно

OVR: Флаг переполнения.

CRCERR: Флаг ошибки контрольной суммы CRC. Этот флаг устанавливается аппаратно и сбрасывается программно записью нуля.

TXE: Буфер передатчика пуст

RXNE: Буфер приемника не пуст

SPI data register (SPI_DR)

Рис. 4. Регистр SPI_DR

DR[15:0]: Регистр данных. Этот регистр разделен на два буфера: первый для записи (буфер передатчика), второй для чтения (буфер приемника). Операция записи в регистр SPI_DR записывает данные в буфер передатчика, а операция чтения из SPI_DR возвращает значение из буфера приемника.

SPI CRC polynomial register (SPI_CRCPR)

Рис. 5. Регистр SPI_CRCPR

CRCPOLY[15:0]: Регистр CRC полинома, по-умолчанию 0007h

SPI RX CRC register (SPI_RXCRCR)

Рис. 6. Регистр SPI_RXCRCR

RXCRC[15:0]: Значение CRC принятых данных. Когда вычисление CRC включено, RXCRC содержит вычисленное значение CRC принятых данных. Этот регистр сбрасывается в ноль, когда бит CRCEN в регистре SPI_CR1 устанавливается в единицу.

SPI TX CRC register (SPI_TXCRCR)

Рис. 7. Регистр SPI_TXCRCR

TXCRC[15:0]: Значение CRC переданных данных. Когда вычисление CRC включено, TXCRC содержит вычисленное значение CRC переданных данных. Этот регистр сбрасывается в ноль, когда бит CRCEN в регистре SPI_CR1 устанавливается в единицу.

Настройка SPI в режиме Master (ведущий) без прерываний

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

Функцию инициализации назовем SPI1_Init():

Теперь надо определить, к каким выводам микроконтроллера подключен SPI1. Открываем Reference manual, идем в раздел про GPIO, находим 9.3.10 SPI1 alternate function remapping. Там есть вот такая таблица:

Рис. 8 Таблица 56 в Reference manual

Пока не будем возиться с Remap-ом. Из рис. 7 становится понятно, что SPI1 подключен к порту GPIOA к следующим выводам:

А как эти выводы правильно настроить для работы с SPI? В 9.1.11 GPIO configurations for device peripherals есть вот такая таблица:

Рис. 9. Настройка выводов порта для работы с SPI1

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

Читайте также:  spectra rs что значит

Далее настраиваем GPIO. Про его регистры можно почитать вот в этой статье.

Вывод NSS не трогаем, так как не будем его использовать. Далее, настройка SPI:

Настроили вот так: 8 бит, MSB first, CPOL/CPHA 00. Стоит обратить особое внимание на SSM и SSI. Инициализация модуля SPI в режиме Master возможна только при сигнале SS равном единице. Почему это так объяснять не буду, скажу только, что это идет из режима Multimaster mode. Сигнал SS может быть получен либо с вывода NSS, либо бита SSI регистра CR1. Если SSM установлен в ноль (значение по-умолчанию), то при включении SPI он будет производить проверку состояния NSS, а NSS по-умолчанию настроен как Input floating. Таким образом, если на выводе NSS будет логическая единица, то инициализация завершится успешно, в противном случае ни чего не получится и в регистре SR установится бит MODF, который говорит об ошибке режима. Кроме того, даже после успешной инициализации низкий уровень на NSS отключит SPI и сбросит бит MSTR (из режима master переключится в slave). А если NSS будет просто болтаться в воздухе, то система будет вообще неработоспособной. Поэтому устанавливаем SSM и SSI в единицы.

Осталось теперь только включить SPI1:

Все, инициализация в режиме Master завершена! Вот полный код функции:

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

Рис. 10. Блок-схема модуля SPI

У SPI есть сдвиговой регистр (Shift register), буфер передатчика (Tx buffer) и буфер приемника (Rx buffer). В регистре SR есть три очень интересных флага: BSY, TXE и RXNE. Флаг TXE устанавливается в том случае, если буфер передатчика (Tx buffer) пуст и в него можно загрузить следующее значение, RXNE устанавливается в единицу, если в буфер приемника (Rx buffer) поступило новое значение и его можно прочитать. BSY устанавливается в том случае, если модуль SPI занят операцией обмена данными либо буфер передатчика не пуст.

Логика работы следующая: операцией записи в регистр DR производится заполнение буфера передатчика кадром данных (8 или 16 бит, зависит от настройки), при этом флаг BSY устанавливается, а TXE сбрасывается. После этого значение из буфера передатчика загружается в сдвиговой регистр и запускается процесс передачи данных по SPI, а флаг TXE устанавливается в единицу, что говорит об возможности загрузить новое значение в Tx buffer. Если в Tx buffer загрузить еще одно значение, то TXE сбросится в ноль до момента завершения текущей передачи кадра данных и очередной загрузке значения Tx buffer в сдвиговой регистр.

С каждым новым периодом сигнала синхронизации SCK сдвиговой регистр выплевывает очередной бит в MOSI и в свой хвост заносит новый бит данных с MISO (это справедливо для режима Master, для Slave наоборот). После того, как был принят последний бит, значение сдвигового регистра загружается с буфер приемника (Rx buffer) и устанавливается флаг RXNE. Если в Tx buffer не было загружено новое значение, то передача данных завершается и флаг BSY сбрасывается в ноль.

Отправка данных в SPI будет выглядеть вот так:

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

А вот и прием данных:

Для теста вот такой main():

ClockInit() — инициализация системы тактирования, см. эту статью. Далее инициализация SPI1 и бесконечный цикл с отправкой значения 0x34. В доказательство правильной работы программы приведу осциллограмму:

Рис. 11. Осциллограмма работы программы, нижний график (синий) сигнал SCK, верхний (желтый) сигнал на выводе MOSI

На рис. 11 видно, что данные идут непрерывным потоком без задержек. Отлично! 🙂

Настройка SPI в режиме Master (ведущий) с прерываниями

Теперь давайте сделаем все то же самое, но только на прерываниях. Задача следующая: у нас есть некий массив байт, который надо выплюнуть в SPI с использованием прерываний. Вдаваться в подробности работы прерываний в STM32 в не буду, для этого будет отдельная статья, ограничусь только необходимым минимумом.

У периферийного модуля может быть несколько событий, которые могут вызвать прерывание, для SPI это TXEIE, RXNEIE и ERRIE (см. рис. 2). Однако, обработчик прерывания в большинстве случаев всего один: SPI1_IRQHandler(). Таким образом, если у нас включено прерывание по нескольким событиям, то чтобы понять, что произошло, в SPI1_IRQHandler() нужно смотреть регистр статуса SR.

Для того, чтобы прерывание сработало, нужно выполнить 3 действия:

Функция инициализации почти ни чем не отличается от предыдущего примера, только добавлена строчка NVIC_EnableIRQ(SPI1_IRQn). Вот код инициализации:

Далее, нам понадобятся 3 глобальных переменных:

Затем идет функция запуска передачи данных по SPI. На вход она принимает указатель на массив uint8_t и количество байт для передачи:

Работает это так. В начальном состоянии SPI не ведет ни какую передачу данных и в регистре SR флаг TXE установлен в единицу. Это значит, что если разрешить прерывание TXEIE, то оно тут же сработает. После всех предварительных настроек мы разрешаем прерывание TXEIE, тем самым запускаем процесс отправки данных по SPI. Обработчик прерывания, в котором происходит вся основная работа, выглядит вот так:

Думаю, все ясно из комментариев. Набросаем небольшой main() для демонстрации:

А вот осциллограммы процесса передачи данных. Это для длинны буфера data[] 3 байта:

Рис. 12. Отправка буфера длинной 3 байта с использованием прерываний

Все работает правильно, сколько сказали — столько и отправили 😉 Байты идут друг за другом без задержек. Отлично 🙂

А вот так выглядит отправка 10-и байт:

Рис. 13. Отправка буфера длинной 10 байт с использованием прерываний

На этом пока все, статья и так получилась большой. Что будет в следующей части еще не решил, но надо бы сделать статьи про контроллер прерываний NVIC и контроллер прямого доступа к памяти DMA. Ну и SPI в режиме Slave не мешало бы рассмотреть. Всем спасибо за внимание, задавайте вопросы на мыло или мне во Вконтакте, ссылки в разделе «Контакты» вверху страницы.

Источник

Информ портал о технике и не только