Робота портов ввода/вывода
Изучив данный материал, в котором все очень детально и подробно описано с большим количеством примеров, вы сможете легко овладеть и программировать порты ввода/вывода микроконтроллеров AVR.
- Робота портов ввода/вывода
- Подключение светодиода к линии порта ввода/вывода
- Подключение транзистора к линии порта ввода/вывода
- Подключение кнопки к линии порта ввода/вывода
Пример будем расматривать на микроконтроллере ATMega8.
Программу писать будем в Atmel Studio 6.0.
Емулировать схему будем в Proteus 7 Professional.
С внешним миром микроконтроллер общается через порты ввода вывода. Схема порта ввода вывода указана в даташите:
Но новичку разобраться довольно со схемой довольно сложно. Поэтому схему упростим:
Pxn – имя ножки порта микроконтроллера, где x буква порта (A, B, C или D), n номер разряда порта (7… 0).
Cpin — паразитная емкость порта.
VCC — напряжение питания.
Rpu — отключаемый нагрузочный верхний резистор (pull-up).
PORTxn — бит n регистра PORTx.
PINxn — бит n регистра PINx.
DDRxn — бит n регистра DDRx.
Рассмотрим, что же представляет собой вывод микроконтроллера. На входе микроконтроллера стоит небольшая защита из двух диодов (см.1), она предназначенная для защиты ввода микроконтроллера от кратковременных импульсов напряжения, превышающих напряжение питания. Если напряжение будет выше питания, то верхний диод откроется и это напряжение будет стравлено на шину питания, где с ним будет уже бороться источник питания и его фильтры. Если на ввод попадет отрицательное (ниже нулевого уровня) напряжение, то оно будет нейтрализовано через нижний диод и погасится на землю. Впрочем, диоды там хилые и защита эта помогает только от микроскопических импульсов и помех. Если же на ножку микроконтроллера подать вольт 6-7 при 5 вольтах питания, то внутренние диоды его не спасут.
Конденсатор (см.2) — это паразитная емкость вывода. Хоть она и крошечная, но присутствует. Обычно ее не учитывают, но она есть. Не забивай голову, просто знай это.
Дальше идут ключи управления (см.3,4). Каждый ключ подчинен логическому условию, которые нарисованы на рисунке. Когда условие выполняется — ключ замыкается.
Каждый порт микроконтроллера AVR (обычно имеют имена A, B и иногда C или даже D) имеет 8 разрядов, каждый из которых привязан к определенной ножке корпуса. Каждый порт имеет три специальных регистра DDRx, PORTx и PINx (где x соответствует букве порта A, B, C или D). Назначение регистров:
DDRx – Настройка разрядов порта x на вход или выход.
PORTx – Управление состоянием выходов порта x (если соответствующий разряд настроен как выход), или подключением внутреннего pull-up резистора (если соответствующий разряд настроен как вход).
PINx –Чтение логических уровней разрядов порта x.
PINхn – это регистр чтения. Из него можно только читать. В регистре PINxn содержится информация о реальном текущем логическом уровне на выводах порта. Вне зависимости от настроек порта. Так что если хотим узнать что у нас на входе — читаем соответствующий бит регистра PINxn. Причем существует две границы: граница гарантированного нуля и граница гарантированной единицы — пороги за которыми мы можем однозначно четко определить текущий логический уровень. Для пятивольтового питания это 1.4 и 1.8 вольт соответственно. То есть при снижении напряжения от максимума до минимума бит в регистре PINx переключится с 1 на 0 только при снижении напруги ниже 1.4 вольт, а вот когда напруга нарастает от минимума до максимума переключение бита с 0 на 1 будет только по достижении напряжения в 1.8 вольта. То есть возникает гистерезис переключения с 0 на 1, что исключает хаотичные переключения под действием помех и наводок, а также исключает ошибочное считывание логического уровня между порогами переключения.
При снижении напряжения питания разумеется эти пороги также снижаются.
DDRxn – это регистр направления порта. Порт в конкретный момент времени может быть либо входом либо выходом (но для состояния битов PINxn это значения не имеет. Читать из PINxn реальное значение можно всегда).
DDRxy = 0 – вывод работает как ВХОД.
DDRxy = 1 – вывод работает на ВЫХОД.
PORTxn – режим управления состоянием вывода. Когда мы настраиваем вывод на вход, то от PORTх зависит тип входа (Hi-Z или PullUp, об этом чуть ниже).
Когда ножка настроена на выход, то значение соответствующего бита в регистре PORTx определяет состояние вывода. Если PORTxn=1 то на выводе лог.1, если PORTxn=0 то на выводе лог.0.
Когда ножка настроена на вход, то если PORTxn=0, то вывод в режиме Hi-Z. Если PORTxn=1 то вывод в режиме PullUpс подтяжкой резистором в 100к до питания.
Таблица. Конфигурация выводов портов.
DDRxn PORTxn I/O Comment
0 0 I (Input) Вход Высокоимпендансный вход. (Не рекомендую использовать, так как могут наводится наводки от питания)
0 1 I (Input) Вход Подтянуто внутренне сопротивление.
1 0 O (Output) Выход На выходе низкий уровень.
1 1 O (Output) Выход На выходе высокий уровень.
Общая картина работы порта показана на рисунках:
Рис. DDRxn=0 PORTxn=0 – Режим: HI-Z – высоко импендансный вход.
Рис. DDRxn=0 PORTxn=1 – Режим: PullUp – вход с подтяжкой до лог.1.
Рис. DDRxn=1 PORTxn=0 – Режим: Выход – на выходе лог.0. (почти GND)
Рис. DDRxn=1 PORTxn=1 – Режим: Выход – на выходе лог.1. (почти VCC)
Вход Hi-Z — режим высокоимпендансного входа.
Этот режим включен по умолчанию. Все ключи разомкнуты, а сопротивление порта очень велико. В принципе, по сравнению с другими режимами, можно его считать бесконечностью. То есть электрически вывод как бы вообще никуда не подключен и ни на что не влияет. Но! При этом он постоянно считывает свое состояние в регистр PINn и мы всегда можем узнать что у нас на входе — единица или ноль. Этот режим хорош для прослушивания какой либо шины данных, т.к. он не оказывает на шину никакого влияния. А что будет если вход висит в воздухе? А в этом случае напряжение будет на нем скакать в зависимости от внешних наводок, электромагнитных помех и вообще от фазы луны и погоды на Марсе (идеальный способ нарубить случайных чисел!). Очень часто на порту в этом случае нестабильный синус 50Гц — наводка от сети 220В, а в регистре PINn будет меняться 0 и 1 с частотой около 50Гц
Вход PullUp — вход с подтяжкой.
При DDRxn=0 и PORTxn=1 замыкается ключ подтяжки и к линии подключается резистор в 100кОм, что моментально приводит неподключенную никуда линию в состояние лог.1. Цель подтяжки очевидна — недопустить хаотичного изменения состояния на входе под действием наводок. Но если на входе появится логический ноль (замыкание линии на землю кнопкой или другим микроконтроллером/микросхемой), то слабый 100кОмный резистор не сможет удерживать напряжение на линии на уровне лог.1 и на входе будет лог.0.
Режим выхода.
Тут, думаю, все понятно — если нам надо выдать в порт лог.1, мы включаем порт на выход (DDRxn=1) и выдаем лог.1 (PORTxn=1) — при этом замыкается верхний ключ и на выводе появляется напряжение, близкое к питанию. А если надо лог.0, то включаем порт на выход (DDRxn=1) и выдаем лог.0 (PORTxn=1) — при этом открывается уже нижний вентиль, что дает на выводе около нуля вольт.
Автор: expert_av