Порты ввода-вывода XMega

   Данная статья просвещенна особенностям использования и настройки ножек микропроцессора Xmega A и может являться базовым уроком для изучения работы с семейством микропроцессоров Xmega.
    Обозначение
    Ножки ввода/вывода в микропроцессоре Xmega A сгруппированы в порты ввода/вывода по 8 ножек в каждом. Порты ввода/вывода обозначаются PORTx, где x – имя порта, например. PORTA, PORTB и т.д. Отдельные ножки портов обозначаются как Pxn, где x - имя порта, и n – номер ножки, например. PA0, PA1 и т.д.
    Некоторые регистры включают в себя все ножки порта. В этих регистрах бит n соответствует ножке n. Другими словами, младший бит соответствует ножке 0, а старший ножке 7.
    Конфигурация и использование портов
    Настройка ножек порта осуществляется через регистр DIR. Ножка n устанавливается как выход при равенстве «1» соответствующего бита DIRn в регистре DIR. Если бит DIRn равен «0», то ножка порта устанавливается как вход.
    Регистр DIR может быть изменен непосредственной записью регистра или через стробовые регистры DIRSET, DIRCLR и DIRTGL. Запись битовой маски в DIRSET установит соответствующие биты в регистре DIR. Запись битовой маски в DIRCLR очистит соответствующие биты в регистре DIR. А запись битовой маски в DIRTGL инвертирует соответствующие биты в регистре DIR.
    Управление выходным значением ножек порта
    Выходным значением ножек порта управляют через регистр OUT. Настройка ножки порта в соответствующие значение выхода устанавливается в регистре OUT. На выходе ножки n будет высокий уровень сигнала при соответствующем бите OUTn равном «1» и низким при «0», при условии, что ножка сконфигурирована на выход и бит инверсии не установлен.
    Регистр OUT может быть изменен непосредственной записью регистра или через стробовые регистры OUTSET, OUTCLR и OUTTGL. Запись битовой маски в OUTSET установит соответствующие биты в регистре OUT. Запись битовой маски в OUTCLR очистит соответствующие биты в регистре OUT. А запись битовой маски в OUTTGL инвертирует соответствующие биты в регистре OUT.
    Чтение логического состояния ножек порта
    Логическое состояние порта может быть получено чтением регистров IN. Текущее логическое состояние ножки n может быть считано с бита INn независимо от настройки порта.
    Настройка ножек
    У каждой ножки ввода/вывода есть свой собственный регистр конфигурации PINnCTRL, где n – номер ножки. Через эти регистры можно конфигурировать настройки конкретных ножек.
    1. Настройка выходов/подтяжки.
    Для ножек настроенных как выход возможны следующие конфигурации:
    Конфигурация выхода:
    • В конфигурации “Totempole” выход жестко привязан или к VCC или к GND в соответствии с битом в регистре OUT.
    • В конфигурации “Wired-OR”, при записи «1» в соответствующий бит OUTn ножка n будет жестко привязана к VCC. Запись «0» в OUTn для соответствующей ножки, позволяет ножке потянуться к GND внутренним или внешним подтягивающим резистором.
    • В конфигурации “Wired-AND”, при записи «0» в соответствующий бит OUTn ножка n будет жестко привязана к GND. Запись «1» в OUTn для соответствующей ножки, позволяет ножке потянуться к VCC внутренним или внешним подтягивающим резистором.
    Конфигурация подтяжки:
    • Конфигурация “удержание шины на входе и выходе” позволяет слабому держателю шины удерживать на ножке уровень несоответствующий какому-либо логическому состоянию (третье состояние).
    • Конфигурация "Подтянутый вниз" включает внутренний подтягивающий вниз резистор для данной ножки.
    • Конфигурация "Подтянутый вверх" включает внутренний подтягивающий вверх резистор для данной ножки.
    Настройка входов/чувствительности
    Настройка чувствительности входов используется для определения фронта или уровня на ножке настроенной как вход. Чувствительность входов может быть использована для запуска требований прерываний (IREQ) или событий при изменении уровня сигнала на ножке. Ножки входов/выходов поддерживают синхронную и асинхронную чувствительность. Синхронная чувствительность требует синхронизации от периферийных часов, в то время как асинхронная чувствительность не требует часов.
    Биты конфигурации входов/чувствительности управляют чувствительностью входа и входным цифровым буфером ножки ввода/вывода. Возможные конфигурации входов/ чувствительности:
    Возможны четыре варианта настройки чувствительности ножки: чувствительность переднего фронта, заднего фронта, обоих фронтов и низкого уровня сигнала. Также возможно добиться чувствительности верхнего уровня сигнала установкой чувствительности по низкому уровню и установкой бита инвертирования в регистре PINnCTRL. Если ножка используется для генерации событий и установлена в режим чувствительности по низкому уровню сигнала, ножка будет привязана к системе событий, т.е. уровень сигнала на ножке будет непосредственно привязан к системе событий.
    Установка бита отключения входного цифрового буфера отключает данный буфер, что может быть использовано в целях уменьшения потребления в случаях, когда данная ножка не используется или ножка используются только для аналоговых целей. Если входной цифровой буфер ножки отключен, то соответствующий бит в регистре IN будет всегда читаться как «0».
    Инверсия
    Бит инверсии в регистре PINnCTRL управляет полярностью ножки. Если в бит инверсии записать «0», то логика всех входов и выходов инвертируется.
    При установке бита инвертирования будет осуществляться инверсия в независимости от применения ножки. Например, возможно инвертировать выходной сигнал ШИМ реализованный на таймере-счетчике. Инвертирование удобно использовать для переключения между управлениями активным высоким или активным низким уровнями.
    Управление фронтом нарастания сигнала
    Запись «1» в бит управления фронтом нарастания сигнала (Slew-rate control) в регистре PINnCTRL позволяет завалить фронт нарастания на данной ножке. Это очень удобно использовать для уменьшения проблем электромагнитной совместимости, вызванные переключением логических уровней на ножках порта.
    Настройка и использование прерываний по порту  
    Прерывания по порту ввода/вывода могут быть использованы для генерации прерываний вызванных изменением уровня сигнала на ножке и для выхода из спящего режима.
    Настройка прерываний по порту
    Каждый порт Xmega имеет два прерывания.
    Настройка ножки на прерывание осуществляется в 3 этапа. Например, настройка на прерывание 0 осуществляется следующим образом:
    1. Настройка входа/чувствительности в регистре PINnCTRL для каждой ножки, по которой будет срабатывать прерывание.
    2. Запись маски соответствующей ножкам, которые могут вызвать прерывание в регистр INT0MASK.
    3. Выбор уровень приоритета прерывания INT0LVL в регистре INTLVL.
    Отметим, что настройка уровня прерываний должна быть включена в программируемом многоуровневом контроллере прерываний (PMIC) и установлен флаг разрешения глобальных прерываний.
   Асинхронная чувствительность
    Xmega поддерживает два уровня асинхронизации. Ножка 2 на каждом порту имеет полную поддержку полного асинхронного режима, в то время как другие – ограниченного.
    Низкого уровня сигнала Да Уровень сигнала должен быть постоянным
    Использование прерываний по порту для выхода из спящего режима
    Любая ножка порта может быть использована для пробуждения микропроцессора Xmega. Однако, уровень поддержки асинхронной чувствительности ножки используемой для пробуждения определяет какие могут быть настройки чувствительности и каков будет флаг прерывания после пробуждения.
    Эффективное использование портов ввода/вывода
    Для Xmega возможны два варианта позволяющие уменьшить размер кода и увеличить скорость выполнения: настройка нескольких ножек одновременно и виртуальные порты.
    Настройка нескольких ножек одновременно
    Наличие собственного регистра настройки для каждой ножки увеличивает гибкость, но одновременно может увеличить код программы. Возможность одновременной настройки нескольких ножек одного порта реализована в алгоритме настройки нескольких ножек одновременно (multi-pin configuration). Для начала необходимо записать соответствующий ножке бит в регистр MPCMASK в модуле PORTCFG. Запись конфигурации PINnCTRL для любой из ножек порта при установленном MPCMASK приведет к записи данной конфигурации во все ножки соответствующие битовой конфигурации в MPCMASK, при этом регистр MPCMASK автоматически обнулится. Если изменять настройки ножки, для которой незаписан соответствующий бит в регистре MPCMASK – настройки ее не изменяться.
    Обратите внимание, что конфигурация нескольких ножек одновременно не прерывается выполнением записи в PINnCTRL. Если регистр MPCMASK уже установлен, прерывание выполнено, и работа прерывания разрешена по любой из ножек PINnCTRL, то возможна настройка отличного от заданного порта ввода/вывода. Поэтому рекомендуется настраивать конфигурацию нескольких ножек одновременно при отключенных глобальных прерываниях.
    Виртуальные порты
    Некоторые команды в процессорах AVR работают только с адресами расположенными в пространстве ввода/вывода. Применение этих команд позволяет выполнить требуемое действие быстрее и с меньшим использованием памяти, чем при использовании их аналогов работающих с памятью данных. Все регистры портов ввода/вывода микропроцессоров Xmega имеют адреса вне области ввода/вывода.
   Решением данной проблемы является использование виртуальных портов. Четыре порта ввода/вывода могут быть перенесены в виртуальные порты, имеющие регистры в области ввода/вывода. Виртуальные порты имеют регистры DIR, OUT, IN и INTFLAGS доступные из пространства ввода/вывода. Остальные регистры портов ввода/вывода используются в обычном режиме.
    Разница между командами в пространстве ввода/вывода и пространстве памяти
Время выполнения и размер кода для специальных команд в пространстве ввода/вывода показана в следующей таблице:
    Заметим, что команды, выполняемые в пространстве данных, могут использоваться для регистров с адресами находящимися в пространстве ввода/вывода, т.к. пространство ввода/вывода находится в пространстве данных.
    Хотя разница во времени и размере кода для одной команды не велика, но в реальной программе она может достигать огромных размеров. Для примера рассмотрим настройку ножки PC0 в состояние логической единицы без изменения состояний других ножек с использованием пространства ввода/вывода и пространства данных.
    Для пространства ввода/вывода (регистр PORTC соответствует PVIRT0):
sbi PVIRT0_OUT, 0
    Размер этого кодекса - 1 слово, и время выполнения - 1 такт.
    Для пространства данных (непосредственная обработка регистра PORTC):
sbr r16, 0x01
sts PORTC_base + PORT_OUTSET_offset, r16
    Размер этого кодекса - 3 слова, и время выполнения - 3 такта.
    Как видно из примера можно существенно уменьшит размер кода и время выполнения программы при использовании виртуальных портов. Использовать виртуальные порты рекомендуется, когда требуется жесткое ограничения по времени и частое обращение к портам.
    Альтернативные функции портов
    У большинства ножек имеются альтернативны функции отличные от функций простого ввода/вывода. При включении альтернативной функции возможно прекращение работы ножки в обычном режиме и изменение установленного уровня сигнала. Это произойдет если к данной ножке подключено другое периферийное устройство и ему разрешено использовать эту ножку. Более подробная информация как используются ножки в альтернативных режимах написано в описании периферийных устройств подключенных к ним. Сигналы, переводящие ножку на периферийное устройство и блокирующие ее обычную работу недоступны для программного изменения и являются внутренними сигналами от периферийных устройств.
    Hесколько примеров применения с проверенными кодами программ.
    Пример 1. Простейшая программа ввода/вывода
    Задача: Установить порт С на чтение входов от 8 переключателей и показывать их состояния на 8 светодиодах подключенных к порту D.
    Настроить все 8 ножек порта D как выхода установкой регистра PORTD.DIR в значение 0xFF.
    Считать состояния порта C в регистре PORTC.IN.
    Вывод считанного состояния на порт D записью в PORTD.OUT.
    Повтор с шага 2.
    Код работающей программы для процессора Xmega A1 имеет следующий вид:
#include <ioxm128a1.h>                      // Объявление используемых библиотек
#include <ina90.h> // Объявление используемых библиотек
int main(void)
{
PORTD.DIR=0xff; // Настройка всех ножек порта D на выход
while(1) // Основной бесконечный цикл
{
PORTD.OUT=PORTC.IN; // Считывание значений с входов порта С и выдача их на порт D
}
}
    Пример 2. Настройка нескольких ножек одной командой  
    Задача: Установить ножки 0-3 порта С в режим Wired-AND с подтяжкой вверх (к питанию).
    Записать 0x0f в PORTCFG.MPCMASK, что соответствует объедению настроек ножек от 0-3.     Записать PORT_OPC_WIREDANDPULL_gc в PORTC.PIN0CTRL, что одновременно запишет требуемые настройки для ножек 0-3.  
Код работающей программы для процессора Xmega A1 имеет следующий вид:
#define ENABLE_BIT_DEFINITIONS   // разрешение использования групповых битовых имен
#include <ioxm128a1.h> // Объявление используемых библиотек
#include <ina90.h> // Объявление используемых библиотек
int main(void)
{
PORTCFG.MPCMASK=0x0f; // установка регистра объединения настроек ножек 0-3
PORTC.PIN0CTRL=PORT_OPC_WIREDANDPULL_gc; // запись настройки ножки PC0 в режим Wired-AND с подтяжкой вверх (к питанию), но за счет объедения настроек запись настроек произойдет для ножек 0-3
}
    Пример 3. Объединение реальных портов с виртуальными
    Задача: Привязать порта С к виртуальному порту 0 и порт D к виртуальному потру 1 и реализовать на них простейшую программу ввода/вывода (пример 1).
    Записать PORTCFG_VP0MAP_PORTC_gc в PORTCFG.VPCTRLA, что привяжет PORTC к VPORT0.
    Записать PORTCFG_VP1MAP_PORTD_gc в PORTCFG.VPCTRLA, что привяжет PORTD к VPORT1.
    Настроить все 8 ножек порта D как выхода установкой регистра VPORT1.DIR в значение 0xFF.
    Считать состояния порта C в регистре VPORT0.IN.
    Вывод считанного состояния на порт D записью в VPORT1.OUT.
    Повтор с шага 4.
Код работающей программы для процессора Xmega A1 имеет следующий вид:
#define ENABLE_BIT_DEFINITIONS // разрешение использования групповых битовых имен
#include <ioxm128a1.h> // Объявление используемых библиотек
#include <ina90.h> // Объявление используемых библиотек
int main(void)
{
VPORT1.DIR=0xff; // Настройка всех ножек виртуального порта 1 связанного с портом D на выход
while(1) // Основной бесконечный цикл
{
VPORT1.OUT=VPORT0.IN; // Считывание значений с входов порта С и выдача их на порт D через виртуальные регистры
}
}
    Пример 4. Настройка ножки ввода/вывода на генерацию прерываний
    Задача: Установить порт С на прерывание 0 с средним уровнем приоритета, с прерыванием по переднему (нарастающему) фронту на ножке PC0. По прерыванию инвертировать уровень сигнала на выходе ножки PD0.
    Настройка чувствительности входа ножки 0 на передний фронт.
    Записать 0x01 в PORTC.INT0MASK для выбора источника прерывания 0 ножки PC0.
    Установить IN0LVL в PORTC.INTCTRL равным PORT_INT0LVL_MED_gc для разрешения прерывания 0 среднего уровня приоритета.
    Настроить ножку PD0 как выход установкой регистра PORTD.DIR в значение 0x1F.
    Разрешить прерывания среднего уровня в регистре PMIC.
    Установить флаг разрешения глобальных прерываний.
    При прерывании по ножке порта D инвертировать уровень сигнала на выходе ножки PD0.
    Повтор с шага 7.
Код работающей программы для процессора Xmega A1 имеет следующий вид:
#define ENABLE_BIT_DEFINITIONS // разрешение использования групповых битовых имен
#include <ioxm128a1.h> // Объявление используемых библиотек
#include <ina90.h> // Объявление используемых библиотек
int main(void)
{
__disable_interrupt(); // Отключение прерываний
PORTC.PIN0CTRL=PORT_ISC_RISING_gc; // Установка чувствительности ножки PC0 к переднему (нарастающему) фронту
PORTC.INT0MASK=0x01; // установка маски прерываний 0 для порта C на прерывание по ножке 0
PORTC.INTCTRL = PORT_INT0LVL_MED_gc; // установка уровня medium прерываний 0по ножке 0 порта С
PORTD.DIR=0x01; // Настройка ножки PD0 на выход
PMIC.CTRL = PMIC_MEDLVLEN_bm; // Приоритет прерываний уровня medium
__enable_interrupt(); // Разрешение прерываний
while(1) { } // Основной бесконечный цикл
}
ISR(PORTC_INT0_vect) // Обработка прерывания 0 по ножкам порта C
{
PORTD.OUTTGL=0x01; // Переключение уровня сигнала на выходе ножки PD0
}
    Blogger Comment
    Facebook Comment

0 коммент.:

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