Работа с портами avr: Управление портами микроконтроллеров AVR на языке программирования С (Си)

Устройство и работа портов ввода-вывода микроконтроллеров AVR. Часть 1 / Хабр

Работа портов ввода/вывода

Изучив данный материал, в котором все очень детально и подробно описано с большим количеством примеров, вы сможете легко овладеть и программировать порты ввода/вывода микроконтроллеров AVR.

  • Часть 1. Работа портов ввода/вывода
  • Часть 2. Подключение светодиода к линии порта ввода/вывода
  • Часть 3. Подключение транзистора к линии порта ввода/вывода
  • Часть 4. Подключение кнопки к линии порта ввода/вывода

Пример будем рассматривать на микроконтроллере 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) — при этом открывается уже нижний вентиль, что дает на выводе около нуля вольт.

Порты ввода-вывода микроконтроллера ⋆ diodov.net

В этом статье мы напишем первую программу и научимся программировать порты ввода-вывода микроконтроллера.

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

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

Порты ввода-вывода микроконтроллера

Микроконтроллер ATmega8 имеет 28 выводов, каждый из них выполняет определенные функции. Светодиод можно подключить к большинству выводов, однако, не ко всем, ведь минимум пара выводов занята под питание. Чтобы четко знать назначение каждого вывода МК воспользуется даташитом. В даташите находим распиновку (обозначение) всех выводов.

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

Для работы микроконтроллера, впрочем, как и любой другой микросхемы, необходимо напряжение. Во избежание ложных срабатываний МК нужно питать только стабильным напряжением от 4,5 В до 5,5 В. Этот диапазон напряжений строго регламентирован и приведен в даташите.

Плюс («+») источника питания подсоединяется в 7-й ножке, обозначенной VCC. Минус («-») – к 8-й или 22-й ножке, которые имеют обозначение GND (GND – сокращенно от ground – «земля»).

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

Микроконтроллер ATmega8 имеет три порта ввода-вывода: B, C и D. Порты могут быть полными и неполными. Полный порт состоит из восьми бит и соответственно имеет столько же одноименных выводов. У неполного порта меньше 8 бит, поэтому число выводов такого порта также менее восьми.

У данного МК порты B и D полные. А порт C неполный и имеет семь бит. Еще раз обращаю внимание, что нумерация битов начинается с нуля, например PB0, PB1, PB2…

Не удивляйтесь, что у ATmega8 отсутствует порт A. Другие МК, имеющие большее число выводов, могут содержать как порт A, так и порт E. У микроконтроллеров с меньшим числом выводов может быть только один порт и тот неполный.

Знакомство с Atmel Studio 7

Теперь перейдем к написанию кода программы. Наша первая программа будет устанавливать + 5 В на нулевом бите порта C PC0, т.е. на 23-м выводе микроконтроллера.

Запускаем Atmel Studio.

Сначала необходимо создать проект. Для этого в открывшемся окне кликаем по вкладке New Project.

Также проект можно создать, кликнув по вкладке File. В выпавшем меню следует выбрать New и далее Project. Или нажать комбинацию клавиш Ctrl+Shift+N.

В появившемся окне выбираем язык программирования C/C++ и кликаем по вкладке.

Далее нам нужно задать имя и место на диске для нашего проекта. Назовём наш первый проект именем 1 в строке для ввода Name. Изменить место расположения файла можно кликнув по кнопке Browse напротив строки Location. Если оставить галочку возле Create directory for solution, то в выбранном месте автоматически создастся папка с именем проекта. В данной папке помимо проекта будут созданы и другие вспомогательные файлы, поэтому я рекомендую не убирать галочку.

После того, как имя проекта и его место выбраны, нажимаем кнопку OK. Снова появляется окно. В нем нам нужно выбрать тип микроконтроллера. В нашем случае – это ATmega8. Кликаем по вкладке Device Family. В выпавшем меню выбираем серию микроконтроллеров ATmega.

С помощью прокрутки находим и выделяем микроконтроллер ATmega8 и наживаем кнопку OK.

В открывшемся окне мы видим, что Atmel Studio нам автоматически сформировала заготовку или же шаблон программы.

 

Рассмотрим все по порядку.

Atmel Studio 7 | Первая программа

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

Цвет комментариев и других элементов программы можно изменять в настройках Atmel Studio.

/*

 * 1.c

 *

 * Created: 07.08.2017 16:57:59

 * Author : ZBL

 */

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

/* — начало комментария

.

.

.

.

*/ — конец комментария

Весь текс, который помещен между /* и */ полностью пропускается компилятором.

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

// Здесь пишется однострочный комментарий

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

Директива препроцессора

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

#include <avr/io.h>

Эта строка указывает компилятору, что к данному файлу нужно подключить другой файл с именем io.h, который находится в папке avr. В подключаемом файле находится информация о базовых настройках микроконтроллера.

По сути, можно было бы и не подключать файл io.h, а набрать его содержимое вручную, однако это очень неудобно.

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

io – название файла, которое происходит от сокращения input/output – ввод/вывод.

.h – расширение файла, название его происходит от слова header – заголовок.

Теперь все вместе. io.h – это заголовочный файл, в котором записана информация о настройках ввода-вывода микроконтроллера.

Главная функция main 

Ниже нам встречается следующая строка:

int main(void)

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

В синтаксисе языка Си идентификатором функции служат круглые скобки

()

Внутри скобок помещено слово void (void). Оно обозначает пустота. Это указывает на то, что функция main ничего не принимает, т. е. не принимает никаких аргументов. По мере написания более сложных программ, мы детальнее остановимся на этом моменте.

int – это целочисленный тип данных. В данном случае функция работает с целыми числами: как положительными, так и отрицательными. Существуют и другие типы данных, например с плавающей запятой, символьные и др. Более подробно мы будем рассматривать типы данных по мере необходимости или в отдельной статье. Однако для функции main рекомендуется всегда использовать тип данных int, поскольку конструкция int main(void) определена стандартом языка Си и распознается любым компилятором.

Область действия функции определяется фигурными скобками

{

.

.     → тело функции

.

}

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

В общем случае любая функция имеет следующую конструкцию:

тип данных имя функции(агрумент)

{

тело функции (код)

}

Функция while

Внутри функции main находится функция while:

while (1)

    {

    }

While переводится с английского «пока». Это говорит о том, что программа, которая находится в теле данной функции, будет выполняться до тех пор, пока условие истинно. Единица в круглых скобках указывает, что условие истинно, поэтому код программы, написанный в данной функции, будет повторяться бесконечное число раз, т.е. программа будет зациклена. Для чего это делается? Дело в том, что микроконтроллер должен непрерывно выполнять записанную программу. Поэтому программа не может просто взять и оборваться. Микроконтроллер всегда опрашивает порты ввода-вывода либо выдает в них сигналы, даже находясь в ждущем режиме.

Теперь, когда мы рассмотрели основные элементы конструкции программы, давайте посмотрим целиком на базовый шаблон. Без комментариев он имеет следующий вид:

#include <avr/io.h>

int main(void)

{

         while (1)

    {

    }

}

Программирование портов ввода-вывода микроконтроллера ATmega8

Сейчас мы уже можем дополнить программу нужным нам кодом. Первым делом необходимо настроить нулевой бит порта C PC0 на выход.

Мы уже знаем, что МК может, как принимать, так и выдавать сигнал, т.е. выводы (порты) его могут работать как входы и как выходы. Поэтому предварительно нужно настроить вывод МК на соответствующий режим. Для этого в микроконтроллере есть специальный регистр, который называется DDR – direct data register – регистр направления данных.

У каждого порта есть свой такой регистр. Например, регистр порта C называется DDRC, порта B – DDRB, порта D – DDRD.

Чтобы настроить вывод порта на вход в регистр DDR необходимо записать ноль, а на выходединицу.

Команда настройки нулевого бита порта C выглядит следующим образом

DDRC = 0b0000001;

Данной командой в регистр DDRC записывается двоичное число равное десятичному 1. Префикс 0b идентифицирует данное число, как двоичное.

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

Также можно записать в регистр шестнадцатеричное число:

DDRC = 0x1;

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

Давайте рассмотрим еще один пример. Допустим нам необходимо настроить нулевой, третий и седьмой биты порта B на выход, а остальные биты на вход. Для этого случая код имеет такой вид:

DDRB = 0b10001001;

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

Регистр микроконтроллера PORT

После того, как мы настроили нулевой бит порта C PC0 на выход, нужно еще выполнить настройку, чтобы на данном выводе появилось напряжение +5 В. Для этого необходимо установить нулевой бит в регистре PORT. Если бит установлен в единицу, то на выводе будет +5 В (точнее говоря величина напряжения питания микроконтроллера, которая может находится в пределах 4,5…5,5 В для микроконтроллера ATmega8). Если бит установлен в ноль, — то на выводе будет напряжение, величина которого близка к нулю.

Каждый порт имеет свой регистр: порт A – PORTA, порт B – PORTB, порт C – PORTC.

И так, чтобы получить на выводе PC0 напряжение +5 В, необходимо записать такую команду:

PORT = 0b0000001;

Обратите внимание на то, что каждая команда заканчивается точкой с запятой.

Таким образом, чтобы засветить светодиод, нам необходимы всего лишь две команды:

DDRC = 0b0000001;

PORTС = 0b0000001;

Первой командой мы определяем вывод PC0 как вход, а второй устанавливаем на нем напряжение +5 В.

Полный код программы выглядит так:

#include <avr/io.h>

int main(void)

{

     DDRC = 0b0000001;

      

    while (1)

    {

     PORTC = 0b0000001;

    }

}

Здесь необходимо заметить следующее: команда DDRC = 0b0000001; выполнится всего один раз, а команда PORTC = 0b0000001; будет выполняться все время в цикле, поскольку она находится в теле функции while (1). Но даже если мы вынесем команду за пределы функции и поместим ее после DDRC = 0b0000001;, светодиод и в этом случае будет светиться все время. Однако, разместив команду PORTC = 0b0000001; в теле while (1), мы делаем явный акцент на том, что светодиод должен светится все время.

Компиляция файла

Теперь, когда код полностью готов, его нужно скомпилировать. Для этого необходимо нажать клавишу F7 или кликнуть по кнопке Build и в выпавшем меню выбрать Build Solution.

Если ошибок в коде нет, то файл скомпилируется, а в нижней части экрана появится запись о том, что проект скомпилирована успешно: Build succeeded.

Таким образом программируются порты ввода-вывода микроконтроллера практически любого типа. Следующий наш шаг – это запись кода в микроконтроллер. Также можно проверить корректность работы кода с помощью программы-симулятора микроконтроллеров – Proteus.

Скачать файлы Программа 1

цифровых входных/выходных портов на AVR

цифровых входных/выходных порта на AVR

8-разрядные микроконтроллеры

AVR® управляют приложениями через цифровые входы и выходы (I/O). Эти контакты могут контролировать любое напряжение, присутствующее как вход с высоким импедансом, и подавать или потреблять ток как цифровой выход высокого или низкого напряжения. Эти контакты обычно организованы в группы по восемь и называются портами. AVR использует алфавит для обозначения этих портов, например: PortA, PortB и т. д. Контакты порта A обозначаются как PA0 — PA7.

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

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

Каждый порт состоит из трех регистров:

  • DDRx – Регистр направления данных
  • PORTx — регистр вывода контактов
  • PINx — Регистр ввода контактов

где x = имя порта (A, B, C или D)

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

  • Биты DDxn доступны по адресу ввода/вывода DDRx
  • Биты PORTxn по адресу ввода/вывода PORTx
  • битов PINxn по адресу ввода/вывода PINx

Где n = номер бита вывода в регистре порта

DDxn

Биты DDxn в регистре DDRx выбирают направление этого вывода. Если DDxn записывается в ‘1’, Pxn настраивается как выходной контакт. Если DDxn записывается в «0», Pxn настраивается как входной контакт.

PORTxn

Биты PORTxn в регистре PORTx выполняют две функции. Они могут управлять выходным состоянием вывода и настройкой входного вывода.

В качестве вывода:
Если в бит записывается ‘1’, когда контакт сконфигурирован как выходной, на контакт порта устанавливается высокий уровень. Если в бит записывается «0», когда контакт сконфигурирован как выходной, на выводе порта устанавливается низкий уровень.

В качестве входа:
Если в бите записана «1», когда вывод сконфигурирован как входной, активируется подтягивающий резистор. Если в бит записывается «0», когда вывод сконфигурирован как входной, вывод порта имеет три состояния.

PINxn

Биты PINxn в регистре PINx используются для чтения данных с вывода порта. Когда контакт сконфигурирован как цифровой вход (в регистре DDRx) и включена подтяжка (в регистре PORTx), бит будет указывать состояние сигнала на контакте (высокий или низкий).
Примечание: Если порт сделан выходным, то чтение регистра PINx даст вам данные, которые были записаны на контакты порта.

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

Все выводы PORTA, установленные как входы с включенной подтяжкой и последующим чтением данных из PORTA:

 DDRA = 0x00; // сделать PORTA все входы
ПОРТ = 0xFF; //включаем все подтягивания
данные = ПИНА; //считываем контакты PORTA в переменные данные
 

PORTB настроен на входы с тремя состояниями:

 DDRB = 0x00; // сделать PORTB все входы
ПОРТБ = 0x00; // отключаем подтягивания и переводим все контакты в три состояния
 

Младший полубайт PORTA установлен как выходы, старший полубайт как входы с включенными подтяжками:

 DDRA = 0x0F; //вывод нижних выводов, ввод верхних выводов
ПОРТ = 0xF0; //выходные контакты установлены на 0, входные контакты включают подтягивания
 

Доступен пример проекта, управляющего контактом ввода-вывода вместе с простой отладкой.

Проект цифрового ввода-вывода на AVR Xplained 328PB

Пример проекта, упомянутого в видео

[| Пример ввода-вывода со ссылкой на видео]]

Переключение между входом и выходом

При переключении между тройным состоянием ({DDxn, PORTxn} = 0b00) и высоким выходом ({DDxn, PORTxn} = 0b11) , должно иметь место промежуточное состояние либо с включенным подтягиванием {DDxn, PORTxn} = 0b01) , либо с низким выходным сигналом ({DDxn, PORTxn} = 0b10) .

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

Переключение между входом с подтягиванием и низким выходом вызывает ту же проблему. Вы должны использовать либо три состояния
({DDxn, PORTxn} = 0b00) , либо выходное высокое состояние ({DDxn, PORTxn} = 0b11) в качестве промежуточного шага.

Блокировка отключения подтягивания

Бит отключения подтягивания PUD в регистре MCUCR может переопределить настройки подтягивания DDRx и PORTx .

Когда этот бит записывается в единицу, подтягивания в портах ввода-вывода отключаются, даже если регистры DDxn и PORTxn сконфигурированы для включения подтягиваний ({DDxn, PORTxn} = 0b01 ) .

Переключение контакта ввода/вывода

Запись ‘1’ в PINxn переключает значение PORTxn независимо от значения DDRxn. Инструкцию по сборке SBI можно использовать для переключения одного бита в порту.

Неподключенные контакты

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

Самый простой способ обеспечить определенный уровень неиспользуемого штифта — включить внутреннюю подтяжку. В этом случае подтягивание будет отключено во время сброса. Если важно низкое энергопотребление во время сброса, мы рекомендуем использовать внешний подтягивающий или подтягивающий резистор. Не рекомендуется подключать неиспользуемые выводы напрямую к VCC или GND, так как это может вызвать чрезмерные токи, если контакт случайно сконфигурирован как выход.

  Вернуться к началу

Выход порта AVR на C

Серия микроконтроллеров AVR ссылается на свои порты ввода-вывода как PORTA, PORTB, PORTC, PORTD и так далее.

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

Как настроить контакты порта AVR

Например, вы можете настроить первые 4 бита PORTA для использования в качестве входов, а старшие 4 бита PORTA для использования в качестве выходов. Регистры направления данных В микроконтроллерах серии AVR, прежде чем вы сможете использовать порт для ввода или вывода, вы должны убедиться, что порт сконфигурирован либо как вход, либо как выход. Это делается с помощью регистров направления данных или ГДР . Для каждого из портов на вашем чипе имеется DDR, например: DDRA , DDRB , DDRC , DDRD и так далее.

Каждый регистр DDRx имеет ширину 8 бит. Записав 1 в любой бит регистра DDRx, вы настраиваете соответствующий контакт на PORTx как выход.

DDRx: 1 = ПИН-код НАСТРАИВАЕТСЯ КАК ВЫХОД

Аналогичным образом, если вы записываете 0 на контакт в регистре DDRx, вы указываете, что этот контакт должен быть настроен как вход. Мы рассмотрим ввод порта в нашем руководстве по вводу порта AVR.

Чтобы установить все биты PORTA в качестве вывода, вам нужно записать все 1 в DDRA. Следующие 2 команды идентичны и настроят все контакты PORTA как выходы.

 ДДРА = 0xFF;
ДДРА = 255; 

Обе линии записывают двоичный код 11111111 в DDRA, поэтому каждый вывод PORTA будет в режиме вывода.

Вы можете использовать любую строку в своей программе. Выход порта Чтобы фактически отправить данные через порт, вы просто назначаете значение, которое вы хотите отправить через порт, в предопределенное место PORTx (замените x на правильный порт). Таким образом, чтобы отправить данные из PORTA, после того как вы инициализировали их для всех выходов, будут работать следующие строки:

 ПОРТ = 0xAA;
ПОРТ = 170; 

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

Когда вы записываете 1 на вывод порта, вы указываете этому контакту порта перейти на HIGH . Аналогичным образом, когда вы записываете 0 на вывод порта, вы сообщаете этому контакту порта значение 9.0016 НИЗКИЙ .

PORTx: 1 = ВЫХОДНОЙ КОНТАКТ, УПРАВЛЯЕМЫЙ ВЫСОКИМ

Код образца

Вот полный пример вышеуказанных концепций, готовый для вставки в ваш AVRStudio и компиляции.

 // **************************************************** ************************************
// Включает
// ******************************************************* **********************************
#include 
#include 
// ******************************************************* **********************************
// Основной
// ******************************************************* **********************************
интервал основной (пустой)
{
    // настроить PORTA как выход
    ДДРА = 0xFF;
    // основной цикл
    пока (правда)
    {
        // включаем каждый второй бит на PORTA, шаблон 10101010
        ПОРТ = 0xAA;
    }
} 

Вы можете скачать полный исходный код здесь.

Вперед, компилируйте

Вы должны иметь возможность скопировать и вставить этот код прямо в AVRStudio и нажать кнопку Build Active Configuration (она выглядит как белая корзина с двумя синими стрелками вниз, или нажмите F7). Для меня этот код компилируется в 160 байт.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *