4927 subscribers

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

579 full reads
1,4k story viewsUnique page visitors
579 read the story to the endThat's 40% of the total page views
3 minutes — average reading time

Порт ввода-вывода предназначен для связи микроконтроллера с внешним миром, в цифровом виде. При этом никаких дополнительных предположений о формате данных или протоколе обмена не делается. В любом (за очень редким исключением) микроконтроллере есть как минимум один порт ввода-вывода.

При этом совершенно не обязательно, что порт позволяет обмениваться 8 битами информации. Вполне обычной является ситуация, когда порт реализует обмен всего несколькими битами, иногда даже одним. И эти биты не обязательно расположены по порядку.

В типичном случае каждый бит (вывод) порта может работать и как вход, и как выход. Но, по тем или иным причинам, могут накладываться дополнительные ограничения. Например, вывод может быть только выходом, или только входом.

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

Поскольку современные микроконтроллеры очень насыщены функционально, а число выводов микросхем ограничено, большинство выводов выполняет сразу несколько функций. Например, вывод может соответствовать биту порта ввода-вывода, входу АЦП, выходу встроенного ШИМ, входу программирования. И все это одновременно. Альтернативные функции выводов и управление ими сегодня рассматриваться не будут. Речь будет идти только о собственно портах.

Типы цифровых входов

Речь, как вы уже догадались, пойдет о выводах порта работающих как цифровые входы.

Простой (обычный) вход

Простой цифровой (логический) вход микроконтроллера. Иллюстрация моя
Простой цифровой (логический) вход микроконтроллера. Иллюстрация моя
Простой цифровой (логический) вход микроконтроллера. Иллюстрация моя

Здесь все просто, такой вход можно рассматривать как обычный вход любой цифровой (логической) микросхемы. Два диода, расположенные в микроконтроллере, защищают вход от слишком большого напряжения или напряжения отрицательной полярности.

В некоторых случаях на такой вход все таки требуется подавать более высокое напряжение, например, при записи программы. В этом случае верхний диод (подключенный между входом и напряжением питания Vdd) отсутствует. При этом защита входа обеспечивается другими способами, которые мы не будем рассматривать.

Вход с триггером Шмитта

Если входное напряжение может изменяться относительно медленно, между выводом порта и логикой микроконтроллера может устанавливаться триггер Шмитта

Цифровой вход микроконтроллера с триггером Шмитта. Иллюстрация моя
Цифровой вход микроконтроллера с триггером Шмитта. Иллюстрация моя
Цифровой вход микроконтроллера с триггером Шмитта. Иллюстрация моя

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

В некоторых случаях можно управлять наличием/отсутствием такого триггера.

Вход с подтягивающими резисторами

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

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

Кроме исключения неопределенного состояния подтягивающий резистор может обеспечивать некоторый минимальный ток через контакты кнопки, если речь идет о нашем примере.

Для уменьшения необходимого числа внешних компонентов подтягивающие резисторы для выводов работающих как входы могут устанавливаться внутри микроконтроллера

Цифровой вход микроконтроллера с подтягивающим резистором. Иллюстрация моя
Цифровой вход микроконтроллера с подтягивающим резистором. Иллюстрация моя
Цифровой вход микроконтроллера с подтягивающим резистором. Иллюстрация моя

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

На иллюстрации изображен внутренний резистор осуществляющий подтяжку к напряжению питания. Такие резисторы англо-язычной документации называют Pull-Up (подтягивающий в верх). Резисторы обеспечивающие подтяжку к уровню земли встречаются гораздо реже. Такие резисторы называют Pull-Down (подтягивающий вниз).

Подтягивающие резисторы могут устанавливаться как на обычные входы, так и на входы с триггерами Шмитта.

Типы цифровых выходов

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

Стандартный двухтактный выход

Такой выход можно рассматривать как обычный выход цифровых логических элементов.

Цифровой двухтактный выход микроконтроллера. Иллюстрация моя
Цифровой двухтактный выход микроконтроллера. Иллюстрация моя
Цифровой двухтактный выход микроконтроллера. Иллюстрация моя

Такой тип выхода в англо-язычной документации называется Push-Pull. Здесь тоже установлены защитные диоды. Я специально нарисовал их слева, что бы не отвлекать от собственно реализации выходного каскада.

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

Такой выход обеспечивает и путь для втекающего тока, и путь для вытекающего тока. При этом величина тока ограничивается и для собственно вывода, и для всех выводов порта в сумме. Имеется и ограничения на суммарный ток для микросхемы в целом.

О втекающих и вытекающих тока, как и о других параметрам микроконтроллеров я писал в статье "Микроконтроллеры для начинающих. Часть 35. Немного о электрических параметрах микроконтроллеров", повторяться не буду.

Открытый коллектор, открытый сток

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

Цифровой выход "открытый сток" микроконтроллера. Иллюстрация моя
Цифровой выход "открытый сток" микроконтроллера. Иллюстрация моя
Цифровой выход "открытый сток" микроконтроллера. Иллюстрация моя

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

Такие выходы можно объединять для реализации функции "монтажное ИЛИ". Такие выходы часто используются для работы с системной магистралью выходящей за пределы печатной платы модуля (I2C, например). В некоторых случаях такие выходы могут работать при напряжении превышающем напряжение питания микросхемы.

На иллюстрации показан выход "истинный открытый сток". Если верхний транзистор не исключен, но всегда закрыт, то выход по прежнему является выходом с открытым стоком. Но "истинным" его уже нельзя назвать. Чуть позже мы столкнемся с этой тонкостью в реальных микроконтроллерах.

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

Цифровой выход с ограничением скорости нарастания напряжения

Да, такие тоже бывают, хоть и реже. Ограничение скорости нарастания напряжения улучшает электро-магнитную совместимость за счет уменьшения уровня генерируемых помех. Но при этом снижается и максимальная частота, на которой может работать такой выход.

Ограничение скорости нарастания выходного напряжения достигается просто - ограничением тока через каналы выходных полевых транзисторов. Это эквивалентно повышению их сопротивления.

Но как можно изменить сопротивление канала? Тоже очень просто - сопротивление канала зависит от напряжения на затворе. Если уровень технологии производства интегральных транзисторов достаточно высок, можно достичь высокой степени их идентичности. А это позволяет получить весьма близкие характеристики "напряжение на затворе - ток стока". Остается лишь открывать выходные транзисторы уменьшенным напряжением на затворе и цель достигнута. Это лишь один из вариантов.

Я не буду отдельно иллюстрировать такие тонкости управления транзисторами, поскольку это уже схемотехника, а не собственно работа порта ввода-вывода.

Двунаправленная работа вывода порта

Большинство выводов портов работают в двух направлениях, и как вход, и как выход. Как это обеспечить и не получить лишние проблемы? Все достаточно просто и давно применяется в дискретных логических элементах.

Если в двухтактном выходном каскаде оба транзистора закрыты, то выход оказывается "подвешенным", ни с чем внутри микросхемы не соединенным. Это называется третьим состоянием выхода. У цифровых элементов, выходы которых можно переводить в третье состояние, имеется отдельный вывод, который часто называют "входом разрешения выхода". Например, OE (output enable).

Реализация двунаправленной работы порта ввода-вывода. Иллюстрация моя
Реализация двунаправленной работы порта ввода-вывода. Иллюстрация моя
Реализация двунаправленной работы порта ввода-вывода. Иллюстрация моя

Сигнал DIR определяет направление передачи информации, а инвертор исключает одновременную работу буферных элементов (показаны на иллюстрации треугольниками). Такая схема двунаправленного каскада не исключает ни одного из ранее рассмотренных типов входов и выходов.

Остается определиться с тем, как задается сигнал направления работы DIR и куда подключается такой двунаправленный каскад.

Регистр направления передачи

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

В микроконтроллерах AVR и STM8 регистры направления называются DDR, Data Direction Register. Полное имя для STM8, например, для порта А, будет PA_ODR. А для AVR - DDRA.

В микроконтроллерах PIC регистр определяющий направление передачи называется TRIS, TRI-State Register. И для порта А, например, полное имя будет TRISA. Ранее порты в PIC назывались GPIO, соответственно, и регистр направления передачи назывался TRISGPIO.

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

Один разряд (бит) порта микроконтроллера с регистром направления передачи. Иллюстрация моя
Один разряд (бит) порта микроконтроллера с регистром направления передачи. Иллюстрация моя
Один разряд (бит) порта микроконтроллера с регистром направления передачи. Иллюстрация моя

Регистр выходных данных

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

Регистр выходных данных в микроконтроллерах AVR называется PORT. Например, для порта А регистр выходных данных будет называться PORTA.

Точно так же называется регистр выходных данных в PIC. Однако, в простых PIC порты могут называться GPIO (General Purpose Input-Output). Соответственно, и регистр выходных данных, в таком случае, будет называться GPIOA (для порта A). Причем если порт в микроконтроллере один, то буква имени может вообще отсутствовать. Тогда и регистр будет называться просто GPIO. В более современных PIC регистр выходных данных и регистр входных данных разделены, о чем я расскажу чуть позже. При этом регистр выходных данных называется LAT. А полное имя, например, для порта А будет LATA.

В микроконтроллерах STM8 регистр выходных данных называется ODR. Например, для порта А полное имя будет PA_ODR.

Один разряд (бит) порта микроконтроллера с регистром направления передачи и регистром выходных данных. Иллюстрация моя.
Один разряд (бит) порта микроконтроллера с регистром направления передачи и регистром выходных данных. Иллюстрация моя.
Один разряд (бит) порта микроконтроллера с регистром направления передачи и регистром выходных данных. Иллюстрация моя.

На это иллюстрации я уже показал и внутреннюю системную магистраль микроконтроллера.

Обратите внимание, что теперь входной и выходной буферы не соединяются между собой (кроме как не самом выводе). Это совершенно логично, так как регистр ODR не может передавать информацию со своего выхода на вход, он однонаправленный.

Чтение входных данных

Я не случайно написал "чтение", а не "регистр". Посмотрите еще раз на последнюю иллюстрацию, не замечаете никакой проблемы?

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

Такая конфигурация порта ввода-вывода была (и есть) в относительно устаревших микроконтроллерах PIC, например. И именно из-за особенностей ее реализации регистр направления в PIC получил название TRIS.

Один разряд (бит) порта микроконтроллера PIC с регистром направления передачи и регистром выходных данных. Иллюстрация моя.
Один разряд (бит) порта микроконтроллера PIC с регистром направления передачи и регистром выходных данных. Иллюстрация моя.
Один разряд (бит) порта микроконтроллера PIC с регистром направления передачи и регистром выходных данных. Иллюстрация моя.

Здесь регистр направления TRIS действительно управляет третьим состоянием выходного буфера. А вот сигнал чтения внутренней системной шины разрешает работу входного буфера.

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

Это не всегда удобно, но работать с таким портом не очень сложно. Впоследствии мы все это увидим в примерах программ. В современных PIC, как и в микроконтроллерах AVR и STM8 регистры выходных данных и регистры входных данных разделены.

Функциональная схема одного разряда (бита) порта ввода-вывода микроконтроллера. Иллюстрация моя
Функциональная схема одного разряда (бита) порта ввода-вывода микроконтроллера. Иллюстрация моя
Функциональная схема одного разряда (бита) порта ввода-вывода микроконтроллера. Иллюстрация моя

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

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

Типовые операции с портами ввода-вывода

Для этого полного случая я и приведу названия соответствующих регистров для разных микроконтроллеров

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

На самом деле существует множество тонкостей связанных с использованием регистров. Например, запись в регистр PORT в PIC приводит к записи данных в и регистр LAT. А в AVR запись 1 в регистр PORT для соответствующего вывода, работающего в режиме входа, приводит к включению подтягивающего резистора. В STM8 регистр IDR доступен только для чтения.

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

Заключение

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

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