Добавить в корзинуПозвонить
Найти в Дзене
Разумный мир

Микроконтроллеры для начинающих. Часть 48. Порты ввода-вывода AVR

Нам осталось рассмотреть реализацию портов вывода в микроконтроллерах AVR. Это будет не сложной задачей после всего, что мы уже знаем о портах ввода-вывода. Напомню предыдущие статьи, материалы которых нам сегодня понадобятся, и на которые я буду ссылаться, что бы избежать повторений Как всегда, если вы их еще не прочитали, то советую это сделать до чтения сегодняшней статьи. Реализация портов ввода-вывода AVR Не смотря на то, что микроконтроллеры AVR имеют множество вариаций (хоть и меньше, чем PIC), порты ввода-вывода реализованы практически единообразно, но чуть менее логично, что в STM8 (на мой взгляд). Если внимательно посмотреть на иллюстрацию, что станет видно, что это очень похоже на порты в PIC (с регистрами LAT) и на STM8 (но немного проще). Давайте рассмотрим основные узлы порта Регистр DDR Этот регистр показан на иллюстрации триггером DDxn. Регистр выбора направления передачи данных. Его название и функционал идентичны одноименному регистру STM8. Функционал аналогичен и рег
Оглавление

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

Как всегда, если вы их еще не прочитали, то советую это сделать до чтения сегодняшней статьи.

Реализация портов ввода-вывода AVR

Не смотря на то, что микроконтроллеры AVR имеют множество вариаций (хоть и меньше, чем PIC), порты ввода-вывода реализованы практически единообразно, но чуть менее логично, что в STM8 (на мой взгляд).

Реализация одного разряда порта ввода-вывода в AVR. Из документации
Реализация одного разряда порта ввода-вывода в AVR. Из документации

Если внимательно посмотреть на иллюстрацию, что станет видно, что это очень похоже на порты в PIC (с регистрами LAT) и на STM8 (но немного проще). Давайте рассмотрим основные узлы порта

Регистр DDR

Этот регистр показан на иллюстрации триггером DDxn. Регистр выбора направления передачи данных. Его название и функционал идентичны одноименному регистру STM8. Функционал аналогичен и регистру TRIS PIC. Обратите внимание, что этот регистр принимает участие не только в управлении выходным буфером, но и управление подключением резисторов подтяжки. Регистр доступен и для записи, и для чтения.

Регистр PIN

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

Этот синхронизатор обеспечивает считывание состояния вывода в определенный момент машинного цикла выполнения команды. Это уменьшает влияние изменения состояния вывода во время считывания. Вообще говоря, подобная синхронизация есть и в PIC, и в STM8.

Ситуация с регистром PIN несколько более интересна, причем тут участвует и регистр PORT, о котором речь пойдет чуть позже. В отличии от регистра IDR STM8 в регистр PIN запись возможна (не всегда, смотрите примечание ниже).

Обращаю ваше внимание, что запись в регистр PIN возможна далеко не во всех микроконтроллерах AVR! Например, в ATmega16 и ATmega32 такой возможности нет. Поэтому нужно обязательно читать документацию на микроконтроллер.

Регистр PORT

Регистр выходных данных порта. Как и в других микроконтроллерах, записанные в этот регистр данные совсем не обязательно появятся на выводах микроконтроллера. На иллюстрации показан триггером PORTxn.

Регистр доступен и для записи, и для чтения. Причем операция чтения возвращает не текущее состояние вывода микроконтроллера, а записанные в регистр PORT данные. А вот с записью в регистр все интереснее, причем тут участвует и регистр PIN. Настало время разобраться с этим вопросом

PORT и PIN, особенности совместной работы

В STM8 регистры ODR и IDR четко разделены функционально. А вот в PIC и в AVR (некоторых) все устроено хитрее.

В PIC возможна запись и в регистр PORT, и в регистр LAT. Причем запись в LAT эквивалентна записи в PORT. В AVR запись в PIN (не всех микроконтроллеров) дает дает еще более интересный результат. Вот увеличенный фрагмент функциональной схемы

Фрагмент функциональной схемы одного разряда порта с возможностью записи в регистр PIN. Из документации
Фрагмент функциональной схемы одного разряда порта с возможностью записи в регистр PIN. Из документации

Обратите внимание, что сигналы WRx (запись в PORT) и WPx (запись в PIN) воздействуют на триггер PORTxn. При этом сигнал WPx (запись в PIN) дополнительно управляет мультиплексором, который выбирает записываемые данные.

Если мы записываем в разряд регистра PIN логический 0, то он будет записан в соответствующий разряд регистра PORT. А вот если мы попробуем записать в PIN логическую 1, то в регистр PORT запишется инвертированное состояние этого разряда регистра PORT до операции записи. То есть, мы записью 1 в разряд PIN инвертируем соответствующий разряд PORT. Причем независимо от режима работы вход/выход.

Другими словами, вот такой оператор

PINB3=1;

на самом деле инвертирует третий разряд регистра PORTB. То есть, PORTB3.

А вот так выглядит фрагмент функциональной схемы для микроконтроллеров без возможности записи в регистр PIN

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

Поэтому особую внимательность надо проявлять не только разработчикам устройств на PIC, но и разработчикам устройств на AVR.

Режимы работы портов

Очевидно, что переключение разрядов порта между режимами "вход" и "выход" осуществляется с помощью регистров DDR. Если разряд регистра DDR сброшен (равен 0), то вывод работает в режиме "вход". А если установлен, то как "выход".

А вот с подключением/отключением подтягивающих резисторов все менее логично. За возможность использования подтягивающих резисторов, в общем и целом, отвечает бит PUD регистра MCUCR. Мы уже встречались с этим регистром ранее. Точнее, этот бит запрещает резисторы подтяжки, если он установлен.

За управление резисторами собственно разрядов, в режиме "вход", отвечают регистры PORT. То есть, разряды регистров PORT, которые соответствуют работающим как цифровые входы выводов, содержат не данные, а управляют резисторами подтяжки. Если это разрешает бит PUD.

Если разряд регистра PORT сброшен, то соответствующий вывод (вход) является плавающим. А если установлен, то подключается подтягивающий резистор (к положительному выводу источника питания).

А это не только не совсем логично, но может и мешать. Например, мы зарядили внешний конденсатор (разумеется, через резистор) установив на выводе высокий уровень. Теперь нам надо переключиться в режим "вход" и дождаться разряда конденсатора внешней цепью. Но простого переключения направления работы будет недостаточно, так как нам будет мешаться 1 в регистре PORT. А сбросить разряд PORT мы можем только после переключения в режим входа, так как иначе мы просто сразу же разрядим конденсатор.

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

Цикл чтение-модификация-запись

В микроконтроллерах AVR он не представляет проблемы (как в PIC без LAT), так как переключение бита регистра PORT не приведет к чтению состояния выводов микроконтроллера. А значит, не окажет непредвиденного влияния на остальные биты порта.

Альтернативные функции выводов

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

Нам пока достаточно знать, что для использования вывода именно как цифрового входа/выхода порта необходимо отключить все модули, которые связаны с альтернативными функциями вывода. Этого достаточно в большинстве случаев.

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

Отслеживание изменения состояний выводов

Возможно формирование запросов прерывания при изменении состояния выводов портов. При этом не только выводов работающих как входы, но и выводов работающих как выходы. А это позволяет реализовать "программные прерывания", например, при включении нагрузки. Что несколько отличается от других микроконтроллеров.

Мы пока не изучали прерывания, поэтому и прерывания от портов рассматривать не будем. Это еще впереди. Пока лишь скажу, что формирование запросов прерывания при изменении состояния выводов управляется регистрами PCMSKx. Вместе с регистром PCICR. А сам флаг запроса, при необходимости, можно прочитать через регистр PCIFR.

Об остальном будет отдельный разговор.

Заключение

Вот мы и закончили знакомство с портами ввода-вывода, как в целом, так и с их реализацией в некоторых микроконтроллерах. Это было краткое и упрощенное знакомство, которое мы будем постепенно углублять в дальнейшем.

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

Что дальше? А дальше мы займемся несколькими практическими примерами работы с портами. Вы сможете повторить их сами, что бы попробовать свои силы и обрести немного уверенности в этих силах. И даже немного поэкспериментируем изучая особенности работы микроконтроллеров, которые мы уже изучили. Теперь мы к этому готовы.

Ну а потом будем двигаться дальше, изучая и другие модули микроконтроллеров.

До новых встреч!