[Home] | [Donate!] [Контакты] |
[<< SPI в микроконтроллерах STM32. Основы] | [SPI в STM32. Управление передачей данных >>] |
Наиболее типичный способ использования SPI предполагает наличие одного ведущего и одного или нескольких ведомых устройств; одноимённые выводы всех устройств соединяются вместе (кроме NSS, использование которого зависит от конфигурации). Рассмотрим процедуру настройки SPI в микроконтроллерах STM32 для работы в ведомом и ведущем режимах. Кроме того, кратко коснёмся вопросов полудуплексной и симплексной связи.
Здесь в большей степени рассматривается теоретическая сторона вопросов. Об использовании SPI с точки зрения практики, с примерами кода, смотрите: "Примеры использования SPI в STM32".
Рис. %img:spi_c1. Типичный вариант подключения устройства по SPI
Оглавление
При работе в ведомом режиме, устройство получает тактовый сигнал через вход SCK от ведущего устройства. Поэтому значение битового поля BR[2:0] в регистре SPI_CR1 не оказывает влияния на скорость передачи, скорость задаётся ведущим устройством. Остальные биты регистров SPI_CR1, SPI_CR2 должны быть заданы в соответствии с требованиями к конфигурированию SPI.
Примечания.
1. Рекомендуется включать ведомое устройство SPI до того, как ведущее устройство начнёт формировать тактовый сигнал. В противном случае может произойти нежелательная передача данных.
2. Регистр данных ведомого устройства должен быть готов (в него должны быть записаны данные) до первого фронта тактового сигнала или до завершения текущей передачи. Возможно, протокол обмена между устройствами не всегда требует какой-либо передачи от данного устройства, тогда могут быть переданы любые фиктивные данные.
3. Обязательно следует задать полярность тактового сигнала до того, как ведущее и ведомое устройство будут включены.
Процедура конфигурирования SPI для работы в ведомом режиме.
В ведомом режиме вывод MOSI является входом, а вывод MISO - выходом. Выход находится в высокоимпедансом состоянии до тех пор, пока данное ведомое устройство не будет выбрано - в зависимости от настроек: аппаратно, низким уровнем сигнала NSS или программно, сбросом бита SSI в регистре SPI_CR1.
Для передачи данных от ведомого устройства, следует загрузить данные в буфер Tx путём записи в программно доступный регистр данных SPI_DR. Если сдвигающий регистр свободен, данные из буфера будут помещены в него (если не свободен - после завершения текущей передачи). После выгрузки данных из Tx в сдвигающий регистр, устанавливается флаг TXE в регистре SPI_SR, а также генерируется прерывание, если установлен бит TXEIE в регистре SPI_CR2. Установка флага TXE сигнализирует о том, что буфер Tx освободился и готов для записи в него новых данных.
Данные передаются из сдвигающего регистра побитно, одновременно с приёмом данных от ведущего устройства. Всё это происходит по тактовому сигналу, получаемому от ведущего устройства.
Когда пересылка фрейма завершается, сдвигающий регистр содержит принятый от ведущего устройства фрейм данных. Данные из сдвигающего регистра пересылаются в буфер Rx, при этом устанавливается флаг RXNE, сигнализирующий о наличии данных в буфере, а если установлен бит RXNEIE в регистре SPI_CR2, то генерируется прерывание. Программный доступ к буферу Rx осуществляется путём чтения регистра данных SPI_DR. При чтении из SPI_DR происходит сброс флага RXNE.
В ведущем режиме, устройство SPI генерирует тактовый сигнал на выходе SCK, поэтому кроме всего прочего, необходима настройка скорости передачи.
Процедура конфигурирования SPI для работы в ведущем режиме.
В ведущем режиме вывод MOSI является выходом, а вывод MISO - входом.
Передача данных ведущим устройством начинается, когда данные для передачи записываются в буфер Tx (путём записи в программно доступный регистр SPI_DR). Из буфера происходит параллельная загрузка данных в сдвигающий регистр, с помощью которого в дальнейшем происходит побитовый вывод/ввод данных синхронно с тактовым сигналом. После пересылки содержимого буфера Tx в сдвигающий регистр, устанавливается флаг TXE, сигнализирующий о том, что буфер пуст и в него могут быть записаны новые данные. Таким образом, новые данные в буфер можно записать ещё до завершения текущей передачи. Если установлен бит TXEIE в регистре SPI_CR2, то при установке флага TXE генерируется прерывание.
После завершения пересылки фрейма, сдвигающий регистр содержит данные, полученные от ведомого устройства. Эти данные пересылаются в буфер Rx и устанавливается флаг RXNE, а также генерируется прерывание, если установлен бит RXNEIE в регистре SPI_CR2. Чтение содержимого буфера Rx осуществляется путём чтения программно доступного регистра данных SPI_DR. При чтении из регистра данных происходит сброс флага RXNE.
Для организации непрерывного потока передаваемых данных, следует помещать новые данные в буфер Tx сразу после начала передачи предыдущей порции данных (до завершения передачи текущего фрейма). Однако, следует убедиться в том, что TXE флаг установлен, прежде чем выполнять запись в Tx.
Примечание.
Когда осуществляется взаимодействие с ведомым SPI устройством, которому требуется снятие сигнала выбора устройства между пересылками, потребуется осуществить программную эмуляцию выхода NSS ведущего устройства с использованием какого-либо вывода GPIO (с программным управлением уровнем на этом выводе). Это связано с тем, что SPI в микроконтроллерах STM не поддерживают снятие сигнала NSS между пересылками на аппаратном уровне.
Кроме полнодуплексной связи, требующей двух однонаправленных линий для передачи данных, возможна передача данных по одной линии. Общее количество линий уменьшается на одну, но передача осуществляется только в одном направлении (симплексная связь) или в двух направления, но поочерёдно (полудуплексная связь). При полудуплексной связи, линия для передачи данных используется как двунаправленная: в разные промежутки времени данные передаются в разных направлениях (от ведущего устройства к ведомому или обратно).
BIDIMODE = 1: одна линия для тактового сигнала и одна двунаправленная линия для передачи данных.
Рис. %img:hd. Подключение для работы в полудуплексном режиме
Этот режим включается установкой бита BIDIMODE в регистре SPI_CR1. В этом режиме используется вывод SCK (для тактового сигнала) и вывод MOSI у ведущего устройства, вывод MISO у ведомого устройства (для передачи данных). Направлением передачи (вход/выход) управляем программно с помощью бита BIDIOE в регистре SPI_CR1. Когда этот бит установлен в 1, вывод для подключения к линии данных является выходом, иначе - входом.
BIDIMODE = 0: одна линия для тактового сигнала и одна однонаправленная линия данных.
В этом режиме SPI используется только для передачи или только для приёма данных.
Рис. %img:master_tx. Ведущее устройство SPI работает в режиме "только передача"
Рис. %img:slave_tx. Ведомое устройство SPI работает в режиме "только передача"
Рис. %img:master_rx. Ведущее устройство SPI работает в режиме "только приём"
Рис. %img:slave_rx. Ведомое устройство SPI работает в режиме "только приём"
Функционирование SPI в режиме "только приём" при работе в качестве ведомого устройства мало чем отличается от работы в полнодуплексном режиме. Пока оно выбрано и получает тактовый сигнал от ведущего устройства, оно должно принимать поступающие данные. Поведение ведущего устройства в режиме "только приём" весьма специфично: сразу после включения и до отключения, оно начинает безостановочную генерацию тактового сигнала, требуя от подключённого к нему ведомого устройства непрерывного потока данных.
Итак, в режиме "только приём", после конфигурирования и включения SPI, передача данных начинается:
Чтобы остановить получение данных ведомым устройством в режиме "только приём", следует отключить SPI (сбросить бит SPE). Сделать это можно в любой момент, при этом текущая пересылка будет успешно завершена, прежде чем SPI в действительности отключится (узнать о моменте действительного отключения SPI можно по сброшенному флагу BSY).
Чтобы остановить получение данных ведущим устройством в режиме "только приём", следует дождаться получения предпоследнего фрейма и во время получения последнего фрейма (выждав не менее одного периода тактового сигнала SPI от момента получения предпоследнего фрейма), отключить SPI. Перед тем, как произойдёт действительное отключение SPI, последний фрейм будет успешно принят.
Подробнее о правильном отключении SPI при работе в разных режимах, а также о многих других важных вопросах смотрите
"SPI в STM32. Управление передачей данных".