
Эта статья по применению описывает настройку и использование модуля SPI в AVR ® XMEGA. Примеры кода на языке C содержат оба варианта использования драйвера, как с использованием прерываний, так и с помощью опроса флагов. Драйвер поддерживает и режим ведущего, и режим ведомого. Теоретические сведения в статье практически отсутствуют. Узнать о функционировании интерфейса SPI Вы можете из статьи "AVR151: Инициализация и использование интерфейса SPI".
Последовательные шины все больше и больше вытесняют параллельные. Разводка таких шин проще, а с увеличением производительности последовательных интерфейсов преимущество в скорости при параллельной передачи данных отходит на второй план. Типичными периферийными устройствами, использующими последовательный интерфейс, являются преобразователи (АЦП и ЦАП), устройства памяти (RAM и EEPROM), часы реального времени, датчики и другие контроллеры LCD, CAN USB и тому подобное.

Рисунок 1-1. Простейшая реализация SPI
Последовательный периферийный интерфейс (SPI) в основном используется для синхронной последовательной передачи данных между ведущим и ведомым. Ведущий инициирует и контролирует передачу, в то время как ведомый может только отвечать.
SPI является полнодуплексным интерфейсом, и при низких затратах позволяет организовать высокоскоростную связь между ведущим и ведомым. SPI не имеет стандартизованного протокола более высокого уровня, что означает почти полное отсутствие дополнительных накладных расходов. Недостатком является то, что в SPI нет подтверждений и управления потоком, а ведущий даже не знает о присутствии ведомого.
В стандартной конфигурации SPI использует две управляющие линии и две линии передачи данных. Для передачи данных в оба направления предназначены линии данных MOSI (выход ведущего, вход ведомого) и MISO (вход ведущего, выход ведомого). К управляющим линиям относятся SCK (тактовый сигнал шины SPI) и SS (выбор ведомого). Если используется линия SS, ведущий выбирает ведомое устройство установив на этой линии низкий логический уровень. При подаче тактового сигнала данные передаются в обоих направлениях одновременно. Значение каждого байта определяется протоколом более высокого уровня.

Рисунок 2-1. Взаимосвязь между ведущим и ведомым
Если в системе присутствует несколько ведомых и каждый из них должен адресоваться независимо, ведущий должен генерировать сигнал SS для каждого ведомого. Эта ситуация показана на рисунке 2-2.

Рисунок 2-2. Система с несколькими ведомыми
Для SPI отсутствует официальная спецификация обмена информацией, что делает проблему гибкости устройств очень важной. Для взаимодействия устройств необходимо одинаково настроить фронт сдвига (CPOL) и фронт захвата (CPHA) данных.
Таблица 2-1. Режимы SPI
| Режим SPI | Конфигурация | Передний фронт | Задний фронт | |||
|---|---|---|---|---|---|---|
| CPOL | CPHA | |||||
| 0 | 0 | 0 | Восходящий | Захват | Нисходящий | Сдвиг |
| 1 | 0 | 1 | Восходящий | Сдвиг | Нисходящий | Захват |
| 2 | 1 | 0 | Нисходящий | Захват | Восходящий | Сдвиг |
| 3 | 1 | 1 | Нисходящий | Сдвиг | Восходящий | Захват |
Для получения дополнительной информации о режимах SPI и их конфигурировании обратитесь к документации на микроконтроллеры XMEGA.
Модуль SPI в XMEGA предназначен для высокоскоростной передачи данных между микроконтроллером XMEGA и другими устройствами с интерфейсом SPI. С помощью управляющих битов можно гибко настроить этот модуль для достижения безупречного качества связи.
Модуль SPI состоит из тактового генератора, статусной и управляющей логики, и управляется регистрами, перечисленными в таблице 3-1.
Таблица 3-1. Регистры модуля SPI
| Имя регистра | Структура и ее элемент |
|---|---|
| Регистр управления модулем SPI | SPIx.CTRL |
| Регистр управления прерываниями модуля SPI | SPIx.INTCTRL |
| Регистр статуса модуля SPI | SPIx.STATUS |
| Регистр данных модуля SPI | SPIx.DATA |
Все управляющие биты, за исключением битов настройки уровня прерываний, находятся в регистре CTRL. Два бита управления уровнем прерываний находятся в регистре INTCTRL. Флаги прерываний и обнаружения коллизий записи данных находятся в регистре STATUS.
Регистр DATA предназначен для чтения/записи (передачи) данных. При чтении этого регистра возвращаются данные, находящиеся в настоящее время в регистре сдвига модуля SPI. Запись данных в этот регистр будет инициировать передачу данных. Система имеет одинарную буферизацию в направлении передачи и двойную буферизацию в направлении приема. В результате этого новые данные не будут записаны в регистр DATA до тех пор, пока полностью не закончится цикл сдвига. Во избежание потери данных полученный байт должен быть прочитан из регистра DATA до того, как следующий байт будет полностью передан.
В режиме ведущего линия SS полностью настраиваема из программы, и обычно используется в одном из этих трех вариантов:
Если линия SS модуля SPI настроена как вход, она выполняет функцию, описанную в первом пункте только что представленного списка. Такая функция линии SS реализована аппаратно в модуле SPI, а для работы модуля в роли ведущего на линии SS должен присутствовать высокий логический уровень. Если другое устройство на шине SPI установит низкий логический уровень на линии SS, модуль SPI для избежания конфликта перейдет в режим ведомого, и, следовательно, перестанет управлять линиями SCK и MOSI. Переход в режим ведомого сопровождается установкой флага прерывания SPI и генерацией прерывания, если они включены.
Настройка линии SS в качестве выхода позволяет получить последние два типичных варианта использования, так как в этом случае она управляется программно и не влияет на работу модуля SPI. При настройке линии SS как выход она ничем не отличается от любой другой линии ввода/вывода общего назначения.
Нередко к одной шине подключено несколько ведомых устройств, а приложение обращается только к одному ведомому одновременно. Такую конфигурацию можно организовать используя несколько линий ввода/вывода общего назначения, по одной на каждое ведомое устройство (как показано на рисунке 2-2), или же через какую-нибудь внешнюю логику для сокращения числа необходимых линий ввода/вывода.
Драйвер, приложенный к этой статье, поддерживает оба режима работы (режимы ведущего и ведомого), а так же оба метода взаимодействия с модулем (через прерывания и методом опроса флагов). Драйвер предназначен для быстрого создания прототипов и для знакомства с модулем SPI микроконтроллеров XMEGA.
Исходный код драйвера модуля SPI содержит следующие файлы:
Полный обзор доступных функций интерфейса драйвера и их использования доступны в документации к исходному коду.
В архиве, приложенном к статье, вложено два примера использования драйвера модуля SPI, один из которых использует прерывания, а второй опрашивает флаги прерываний. В обоих примерах модуль SPIC используется в режиме ведущего, а SPID в режиме ведомого.
Примеры использования драйвера модуля SPI содержат следующие файлы с исходным кодом:
Пример кода на основе прерываний использует драйвер SPI для создания экземпляров модулей, один из которых инициализируется в режиме ведущего, а второй в режиме ведомого. Далее создается пакет данных и отправляется ведомому. После получения данных ведомым модулем в обработчике прерываний данные инкрементируются и снова помещаются в регистр данных, чтобы отправить их назад ведущему. Обработчик прерываний модуля в режиме ведущего так же передает количество байт, содержащихся в пакете данных. При поднятии флага завершения пакетной передачи данных ведущий проверяет полученные данные на корректность.
Пример кода на основе опроса флагов прерываний использует драйвер SPI для создания экземпляров модулей один из которых инициализируется в режиме ведущего, а второй в режиме ведомого. Пример состоит из двух частей:
Во-первых, ведущий за один раз отправляет ведомому один байт, а ведомый инкрементирует полученный байт и помещает его в регистр сдвига. Затем ведомый посылает фиктивный байт с целью получения байта от ведомого. После этого ведущий проверяет корректность полученного значения.
Во второй части кода ведущий инициализирует и отправляет ведомому пакет данных. Ведомый не изменяет данные, а просто помещает их в регистр сдвига чтобы передать их назад ведущему. Когда весь пакет передан, ведущий проверяет равенство между принятыми и отправленными данными (за исключением последнего байта, который не будет возвращен ведущему).
Весь исходный код подготовлен для автоматического генерирования документации с помощью программы Doxygen. Doxygen это утилита, предназначенная для генерирования документации из исходных кодов путем анализа исходного кода и специальных ключевых слов. Более подробно про утилиту Doxygen можно узнать на сайте http://www.doxygen.org. Скомпилированная средствами Doxygen документация также поставляется с исходным кодом, прилагаемом к этому документу и доступна из файла readme.html, расположенного в папке с исходным кодом.