Использование SPI в Xmega

    Данная статья просвещенна особенностям использования и настройки SPI микропроцессора Xmega.
    SPI (англ. Serial Peripheral Interface - последовательный периферийный интерфейс) - последовательный синхронный стандарт передачи данных в режиме полного дуплекса, разработанный компанией Motorola для обеспечения простого и недорогого сопряжения микроконтроллеров и периферии. SPI также иногда называют четырёхпроводным (англ. four-wire) интерфейсом.
    В отличие от стандартного последовательного порта (англ. standard serial port), SPI является синхронным интерфейсом, в котором любая передача синхронизирована с общим тактовым сигналом, генерируемым ведущим устройством (процессором).
    Последовательные шины все больше вытесняют параллельные благодаря простоте соединений и постоянно увеличивающейся эффективности, при которой более высокая скорость передачи данных по параллельной шине теряет свою значимость. К типичным периферийным устройствам с последовательным интерфейсом относятся преобразователи (ЦАП и АЦП), различные виды памяти (RAM и EEPROM), часы реального времени, различные датчики, контроллеры LCD, CAN, USB и т.д.
    Простейшая реализация SPI показана на следующем рисунке:
    Шина SPI
    Интерфейс SPI в основном используется в синхронных последовательных передачах со связями типа ведущий(master)/ведомый(slave). Ведущее устройство инициирует и управляет передачей, в то время как ведомое устройство отвечает.
    SPI является дешевым полноценным дуплексным (двухсторонним) интерфейсом позволяющим высокоскоростной обмен между ведущим и ведомым устройствами. У SPI нет конкретного высокоуровневого протокола обмена, что позволяет сократить дополнительные расходы. Недостатком является лишь то, что нет никакого подтверждения и управления потоком передачи данных и ведущее устройство даже не должно знать о присутствии ведомого устройства.
    Линии (каналы) данных и управления
    Стандартная конфигурация SPI две управляющих линии и две линии данных. Линиями данных являются MOSI (Master Out, Slave In, что переводиться как выход Ведущего, вход Ведомого) и MISO (Master In, Slave Out, что переводиться как вход Ведущего, выход Ведомого), передающие данные каждая в свое направление. Линиями управления являются SCK (SPI lock или блокировка SPI) и SS (Slave Select - выбор Ведомого). При использовании линии SS ведущее устройство выбирает ведомое понижением уровня линии до логического нуля и подает тактовый сигнал. При этом данные передаются в обе стороны одновременно, а далее протокол высокого уровня может определить значение каждого переданного байта. Соединение Ведущего и Ведомого устройства показано на следующем рисунке:
   Если имеется несколько ведомых устройств, у каждого из которых свой уникальный адрес, то ведущее устройство генерирует независимый сигнал SS для каждого из них. Что показано на следующем рисунке:
    Режимы и настройки
    Отсутствие официальной спецификации по SPI соединениям дает гибкость при создании устройств. Полярность часов (CPOL) и фаза часов (CPHA) определяется в настройках перед началом работы и должны быть одинаковыми для соединяемых устройств.
    Режимы работы SPI определены в следующей таблице:
    Работа модуля SPI при разных режимах показана на следующем рисунке:
    Ножка выбора ведомого SS
    В регистре ведущего ножка SS полностью
    Настраивается программно и, как правило, используется один из 3 следующих вариантов:
    - Ножка SS используется как вход (источник прерываний) от другого ведущего устройства (или нескольких ведущих устройств) подсоединенных к шине;
    - Ножка SS используется как сигнал активизации ведомого устройства;
    - Ножка SS используется как ножка ввода/вывода общего назначения.
    Если ножка SS модуля SPI настроена как вход, то она выполняет функцию, описанную в первом пункте представленного выше списка. Эта функция SS реализована в модуле SPI аппаратно и для работы модуля в качестве ведущего устройства ножка SS должна иметь высокий логический уровень. Если другое ведущее устройство подключенное к шине SPI переведет сигнал на ножке SS в низкий уровень, то модуль SPI во избежание конфликтов на шине перейдет в режим ведомого устройства и прекратит управление линиями SCK и MOSI. Переход в режим ведомого устройства будет обозначен установкой флага прерывания SPI и генерацией прерывания при условии, что прерывания разрешены.
    Настройка ножки SS как выхода позволяет реализовать две последние функции, описанные в представленном выше списке, при которых она управляется программно и не зависит от работы SPI модуля. При настройке ножки SS как выход она ничем не отличается от любой другой ножки ввода-вывода.
    Зачастую к одной шине подключается несколько ведомых устройств, в то время как устройство одновременно обращается только к одному из них. Такую конфигурацию можно реализовать с использованием нескольких ножек ввода-вывода, по одной на каждое ведомое устройство или же при использовании некой внешней логической цепи для сокращения количества используемых ножек.
    Режим Ведущего
    Когда SPI используется для организации ведущего устройства, то автоматическое управление линией SS не осуществляется. Ножка SS должны быть настроена как выход и управляться пользовательской программой. Если к шине подключено несколько ведомых и/или ведущих устройств, то SPI ведущего устройства может использовать любые имеющиеся у него ножки ввода-вывода общего назначения для управления линиями SS каждого подключенного к шине ведомого устройства.
    После записи байта в регистр данных начинает работу генератор тактовой частоты шины SPI и аппаратно выполняется передача сдвигом восьми бит данных в подчиненное устройство. По завершении сдвига одного байта, генератор тактовой частоты шины SPI останавливается и устанавливается флаг прерывания модуля SPI. Записью нового байта в регистр данных ведущее устройство может продолжить передачу данных или же оно может сигнализировать о завершении передачи данных установкой низкого уровня на линии SS. Последний принятый байт данных будет храниться в буферном регистре.
    Если ножка SS настроена как вход, то необходимо учитывать, что работа ведущего устройства будет возможной, только если на этом входе будет присутствовать высокий уровень. Если же вывод SS будет работать как вход и на нем будет присутствовать низкий уровень, то модуль SPI будет интерпретировать такую ситуацию, как попытку другого ведущего устройства захватить управление шиной. Во избежание конфликтов на шине, ведущее устройство выполнит следующие действия:
    1. Переход в ведомый режим.
    2. Установка флага прерывания модуля SPI.
    Режим Ведомого
    Когда SPI используется для организации ведомого устройства, он будет находиться в состоянии ожидания до тех пор, пока на ножке SS не появиться высокий уровень, при этом в процессе ожидания линия MISO будет находиться в третьем (высокоимпедансном) состоянии. Когда модуль находится в состоянии ожидания, программа имеет возможность обновления содержимого регистра данных, но данные не будут передаваться даже при наличии тактовых импульсов на линии SCK. После установки низкого уровня на ножке SS и при условии настройки ножки MISO как выхода, ведомое устройство начнет передачу данных сдвигом по первому тактовому импульсу на линии SCK. По завершении передачи сдвигом одного байта данных, будет установлен флаг прерывания модуля SPI. Ведущее устройство может помещать новые данные в регистр данных до того как будут прочитаны предыдущие. Последний принятый байт данных будет хранится в буферном регистре.
    Если ножка SS вновь перейдет в высокое состояние, то это приведет к сбросу логики SPI и невозможности ведомого устройства дальнейшего приема данных. Если это произойдет во время передачи, то все частично принятые сдвиговым регистром данные будут потеряны.
    Ножка SS используется для сигнализации начала и окончания передачи, она также полезна для синхронизации пакетов/байтов за счет поддержания синхронизма счетчика битов подчиненного устройства и генератора часов в ведущем устройстве.
    Модуль SPI в микропроцессорах XMEGA
    Модуль SPI в микропроцессорах XMEGA разработан для высокоскоростной передачи данных между микропроцессором XMEGA и другими устройствами по SPI интерфейсу. Биты управления позволяют гибкую настройку SPI для безупречного подключения к другим устройствам.
    Регистры SPI в микропроцессорах XMEGA
    Модуль SPI состоит из генератора опорной частоты, логики опроса состояний и управляющей логики использующие регистры представленный в следующей таблице:
    Все управляющие биты за исключением битов установки уровня прерываний расположены в регистре CTRL. Два бита управляющие уровнем прерываний находятся в регистре INTCTRL, а при факте прерывания по SPI устанавливается соответствующий флаг в регистре STATUS.
    Регистр данных является регистром записи/чтения и предназначен для непосредственной передачи данных. Чтение этого регистра возвращает текущие данные, находящиеся в сдвиговом регистре SPI, в то время как запись будет вызывать передачу данных. Система имеет одинарную буферизацию в направлении передачи и двойную - в направлении приема. В результате работы модуля SPI новые данные не должны быть записаны в регистр данных до того как полностью завершиться цикл сдвига. Во избежании потери данных приятные данные должны быть прочитаны из регистра данных до того как будет полностью переданный следующие данные.
    Напоследок приложим реальный пример по обмену с помощью SPI, выполненный на микропроцессоре Xmega 128A1.
    Пример. Часто возникает необходимость передачи в другие микросхемы системы управления необходимых данных по протоколу SPI, которые выполняют необходимые преобразования с полученными данными.
    Задача 1: Написать программу посылки значения напряжения с заданной частотой по SPI в микросхему 12-битного ЦАП AD5324, к выводу которой подключен светодиод.
    Б удем использовать внутренний RC-генератор с частотой 2 МГц, передачу с заданной частотой будем осуществлять по прерыванию таймера ТС0 настроенного на 1 Гц. Более подробную информацию о настройке таймера на заданную частоту можно найти в статье «Использование таймера на Xmega A», а по настройке и обработке прерываний в статье «Использование прерываний микропроцессора Xmega». Для передачи будем использовать модуль SPI C настроенный на режим ведущего (с ножками PС4 – SS, PC5 – MOSI, PC7 – SCK), настроенные как выходы, а ножка SS как подтянутая вверх. Более подробную информацию по настройке ножек портов можно найти в статье «Настройка и использование ножек Xmega A». Задача усложняется тем, что модуль SPI микропроцессора Xmega A является 8-битным, в то время как AD5324 принимает 16-битные слова, поэтому передача должна осуществляться непрерывно по два байта, для осуществления непрерывной передачи настроим модуль SPI на максимально возможный коэффициент деления частоты процессора – 128. Поскольку ЦАП нам не отвечает, то ножку MISO задействовать не требуется. Для упрощения будем подавать постоянное значение напряжения, а именно 0x37FF, что расшифровывается согласно описанию на AD5324 как выдача на канал 0 полвины опорного напряжения при нормальном режиме работы ЦАП. Соберем следующую схему соединения Xmega 128A1 и AD5324:
    При таком подключение и посылке кода 0x37FF на ножке 2 AD5324 будет напряжение 2,5В и при резисторе R=100Ом светодиод будет достаточно ярко гореть, если уменьшать посылаемое значение (7FF), то светодиод будет уменьшать яркость горения.
    Код работающей программы передатчика для процессора Xmega 128A1 имеет следующий вид:
PORTC.DIRSET=0xB0;        // Настройка ножек 4,5,7 (SS, MOSI, SCK) порта C как выход
PMIC.CTRL = 1; // приоритет прерываний уровня low
PORTC.PIN4CTRL = PORT_OPC_WIREDANDPULL_gc; // Настройка ножки 4 порта С (SS) поднянтуой к верхнему уровню
PORTC.OUTSET = PIN4_bm; // Установка высокого уровня (нет выбора подчиненного устройства)
SPIC.CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_PRESCALER_DIV128_gc; // Настройка модуля SPIC в простой режим, как ведущее устройство, с частотой 1/128 fprc
__enable_interrupt(); // Разрешение прерываний
while(1) {} // Основной бесконечный цикл
}
#pragma vector=TCC0_OVF_vect // обработка прерываний по переполнению таймера TCС0
__interrupt void irqTCC0_OVF_vect(void)
{
Tx_cnt = 0; // Очистка счетчика передачи
PORTC.OUTCLR = PIN4_bm; // установка SS в низкий уровень - выбор ведомого устройства перед началом передачи
for (int i=Tx_cnt; i<Tx_L; i++) // если посылка передана не вся, то
{
SPIC.DATA=Tx_buf[i]; // запись в буфер SPI следующего байта
while(!(SPIC.STATUS & (1<<SPI_IF_bp))); // ожидания окончания передачи байта по SPI
Tx_cnt=i; // увеличение счетчика переданных байтов
}
PORTC.OUTSET = PIN4_bm; // установка SS в высокий уровень - освобождение ведомого устройства после окончания передачи
}

    Blogger Comment
    Facebook Comment

0 коммент.:

Отправить комментарий