цифровых входных/выходных порта на AVR
8-разрядные микроконтроллерыAVR® управляют приложениями через цифровые входы и выходы (I/O). Эти контакты могут контролировать любое напряжение, присутствующее как вход с высоким импедансом, и подавать или потреблять ток как цифровой выход высокого или низкого напряжения. Эти контакты обычно организованы в группы по восемь и называются портами. AVR использует алфавит для обозначения этих портов, например: PortA, PortB и т. д. Контакты порта A обозначаются как PA0 — PA7.
Все порты AVR имеют настоящую функцию чтения-изменения-записи при использовании в качестве обычных цифровых портов ввода/вывода. Это означает, что направление одного вывода порта может быть изменено без непреднамеренного изменения направления любого другого. То же самое относится к изменению значения привода (если он сконфигурирован как выход) или включению/отключению подтягивающих резисторов (если он сконфигурирован как вход).
Драйвер контактов достаточно надежен для прямого управления светодиодными дисплеями. Все выводы порта имеют индивидуально выбираемые подтягивающие резисторы с сопротивлением, инвариантным к напряжению питания. Все контакты ввода/вывода имеют защитные диоды как для VCC, так и для земли, как показано на рисунке.
Каждый порт состоит из трех регистров:
где x = имя порта (A, B, C или D)
Эти регистры определяют настройку цифровых входов и выходов. Выводы ввода-вывода также могут использоваться совместно с внутренними периферийными устройствами.
Например, аналого-цифровой преобразователь (АЦП) может быть подключен к контакту ввода-вывода вместо цифрового контакта. В этом случае регистры вывода ввода-вывода настраивают его как высокоимпедансный вход с тремя состояниями.Где n = номер бита вывода в регистре порта
Биты DDxn в регистре DDRx выбирают направление этого вывода. Если DDxn записывается в «1», Pxn настраивается как выходной контакт. Если DDxn записывается в «0», Pxn настраивается как входной контакт.
Биты PORTxn в регистре PORTx выполняют две функции. Они могут управлять выходным состоянием вывода и настройкой входного вывода.
В качестве вывода:
Если в бит записывается ‘1’, когда контакт сконфигурирован как выходной, на контакт порта устанавливается высокий уровень. Если в бит записывается «0», когда контакт сконфигурирован как выходной, на выводе порта устанавливается низкий уровень.
В качестве входа:
Если в бите записана «1», когда вывод сконфигурирован как входной, активируется подтягивающий резистор. Если в бит записывается «0», когда вывод сконфигурирован как входной, вывод порта имеет три состояния.
Биты 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, так как это может вызвать чрезмерные токи, если контакт случайно сконфигурирован как выход.
Вернуться к началу
·
4 июня 2015 г.Дмитрий Викторов
Сегодня я решил поэкспериментировать с железом и создать проект Hello World на микроконтроллере. Я использовал для этой цели ARV ATmega16, так как он был у меня в коллекции электронных компонентов. Я купил его несколько лет назад, мечтая создать робота. Кроме того, я купил серийный программатор RS232 JONIS PROG (эта программатор JDM, самодельный парень из магазина электронных компонентов). Однако мой старый ПК в то время сломался, поэтому у меня был только ноутбук без интерфейса последовательного порта, поэтому я забыл о своей мечте на несколько лет. Теперь у меня есть настольный ПК, но его COM-порт RS232 был недоступен (печально, но старые интерфейсы вымирают). Но после вскрытия корпуса обнаружил, что на материнской плате есть:
Внутренний COM-порт RS232 Gigabyte GA-Z77-DS3HУ меня также есть старая интерфейсная карта параллельного порта LPT с дополнительными панелями COM-портов. Но размеры панелей не подходят к моему корпусу:
LPT + 2 платы COM-интерфейсаРешил использовать внешнюю COM-панель нестандартным способом. Выглядит некрасиво, но работает и это для меня главное:
Нестандартный способ встраивания внешней COM панелиПосле некоторых исследований я нашел два рабочих решения для записи HEX дампа в контроллер AVR с помощью моего программатора JONIS PROG:
Я протестировал свой программатор с обоими программами, и оба они могут считывать FLASH-память и FUSE-биты моего ATmega16. Я выбираю AVRDUDESHELL окончательно, потому что он работает намного быстрее и я вижу, что он регулярно обновляется.
Что ж, пора создать простенькую схему и написать программу для управления ею. Я нашел простую схему и реализовал ее:
Схема мигания светодиода ATmega16Как мы видим, контроллер будет выводить данные на пин 1, включая и выключая LED1, поэтому установим нулевой бит порта B для включения LED1 и сбросьте его, чтобы выключить. Контакт 2 используется как вход: когда кнопка S1 отпущена, состояние первого бита порта B будет установлено, в противном случае не установлено. Хочу заметить, что я использовал R1 равный 2 кОм вместо 330 Ом, т.к. использовал очень чувствительный светодиод. Я думаю, что лучше выбрать R1, соответствующий светодиоду, рассчитывая, что через него будет проходить 5В. В случае неизвестного параметра светодиода можно выбрать какое-либо значение, скажем, 2 кОм, уменьшая его до тех пор, пока свет светодиода не станет достаточно ярким. Это будет нормально для тестовых целей. R2 может быть любым от 10 кОм до 100 кОм.
Затем я написал простую программу на C для мигания светодиодом. Эта программа устанавливает нулевой бит порта B (вывод 1 микросхемы) в качестве вывода и использует первый бит порта B (вывод 2 микросхемы) в качестве ввода для изменения частоты мигания.
Основной исходный файлЯ использовал Atmel Studio 6 для разработки программ и обнаружил, что это идеальная IDE на основе Microsoft Visual Studio 2010 со встроенным Visual Assist. Он имеет возможность загружать двоичный файл прямо в чип, но для этого требуется поддерживаемый программатор. Вместо этого я использовал AVRDUDESHELL, как писал ранее, потому что Atmel Studio 6 не поддерживает программистов JDM. В настройках проекта я выбрал свой чип ATmega16. Полное решение Atmel Studio 6 можно загрузить с github.
Atmel Studio позволяет выполнять отладку контроллера с использованием различных аппаратных средств и симулятора. Я попробовал отладку симулятора. Но, как я заметил, задержки на симуляторе намного больше, чем на реальном оборудовании. Будет лучше перейти к настройкам набора инструментов и отключить любую оптимизацию для конфигурации отладки. Таким образом, поведение отладчика будет более адекватным в режиме пошаговой отладки. Можно открыть I/O View и смоделировать кнопку S1, установив значение вывода 2 на 1 или 0.
Итак, после игры с симулятором я построил шестнадцатеричный релиз, который можно найти в папке Release с шестнадцатеричным расширением. Это файл, который я записал в свой чип с помощью AVRDUDESHELL.
Также хотелось бы упомянуть о битах FUSE. Скорее всего, новый чип не требует их модификации для этого Hello World. AVRDUDESHELL и PonyProg позволяют их читать и проверять. Есть сервисы для расчета битов FUSE, например http://www.engbedded.com/fusecalc. Я выбрал из списка там свою микросхему ATmega16 и обнаружил, что у меня конфигурация FUSE такая же, как на сайте. Больше всего я беспокоился о включении внутренних часов, но, как я видел, они были включены по умолчанию. Лучше не трогать FUSE, если не знаете их значения, потому что чип легко заблокировать, и он не будет перезаписан программистом провайдера.
Вот видео как это выглядит:
Что дальше? Я думаю, что соберу новый USB-программатор, совместимый с Atmel Studio. USB-программатору обычно требуется микроконтроллер для обработки USB-сигналов, поэтому я буду использовать свою старую JONIS PROG для создания прошивки нового программатора. Кстати, на это можно смотреть, как на проблему курицы и яйца (чтобы сделать яйцо, нужна курица, а чтобы родить курицу, нужно еще одно яйцо). Что ж, для сборки USB программатора нам понадобится еще один программатор. Самые простые программаторы можно собрать без программируемых контроллеров для LPT или COM порта, а схемы несложно найти в инете. Но что, если в будущем у нас не будет портов RS232 и LPT на наших компьютерах? Насколько я знаю, в магазинах есть переходники для преобразования USB в RS232 и LPT, но они не полноценные. Например, такие COM-адаптеры не могут работать в режиме битбанга, необходимом для сборки COM-программатора без прошивки.