Подключение к ножкам микроконтроллера. Подключение кнопки к AVR

Мы провели эмуляцию схемы в программе Proteus, помигали светодиодом и научились прошивать наш виртуальный микроконтроллер. Наверняка многим из читателей пришла в голову мысль: “А можно ли помигать светодиодом, использую кнопку, подключенную к МК?

Да, разумеется, это возможно. Реализуется довольно легко. Причем можно сэмулировать кнопку как с фиксацией так и без фиксации. Причем в программе Proteus применить оба типа кнопок можно с помощью одного и того же одинакового макроса кнопки. В каких случаях это может быть полезно? Например, нам требуется осуществить выбор режимов работы устройства. Давайте разберем подробнее, как это реализовать с помощью микроконтроллера, и проведем эмуляцию в программе Proteus.


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

Итак к делу. Так выглядит у нас наша схема в программе Proteus (кликните для увеличения):

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

Как мы уже разобрали, питание и землю мы берем во вкладке “Терминал”. Обозначаются они у нас соответственно Power и Ground.

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


Перед использованием нам нужно выбрать кнопку в библиотеке аналогично остальным деталям. Для этого нужно набрать в поле “Маска” слово “but”. Затем в поле “Результаты” слово “BUTTON”:


После этого кнопка появиться у нас в списке, вместе с выбранными деталями, применяемыми в проекте.

Какие порты у нас используются в проекте. Ниже на рисунке мы видим отходящие линии от портов РA0, РВ0, РВ1, РВ2 и РВ3. К порту В у нас подключены светодиоды, а к порту А – кнопка.

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

Номинал резистора достаточно взять равным 200 Ом. Итак, когда мы нажимаем кнопку, мы соединяем порт РА0 с +5 вольт питания, и если мы опросим ножку РА0 на наличие напряжения или его отсутствие, мы сможем влиять на выполнение нашей программы.

Скрины с текстом нашей программы я привел ниже:


Итак отличия от прошлого проекта заключаются в том, что все 8 выводов порта РА мы конфигурируем на вход, выводы порта РВ0 – РВ3 мы конфигурируем на выход, а РВ4 – РВ7 на вход.


Затем мы используем в нашей программе проверку условия “ if”


Итак, мы видим в строчке после “if”, в скобках, условие выполнения. Код ниже выполняется, если на порту PA0 у нас присутствует логический ноль, или ноль вольт. Этот текст в скобках – сдвиг бита порта. Мы разберем в одной из следующих статей, а пока достаточно принять на веру, что этим мы опрашиваем кнопку на отжатие . Затем в фигурных скобках идет текст программы, который выполняется, если условие верно. Если условие не верно, программа продолжает выполняться дальше, пропустив текст в фигурных скобках.

Аналогично, с помощью условия “if” мы опрашиваем кнопку на нажатие . Обратите внимание, текст у нас в скобках изменился. Это означает что если на ножке РА0 у нас логическая единица, мы выполняем условие, то есть текст в фигурных скобках. То есть другими словами, у нас при отжатой кнопке, поочередно загораются и тухнут светодиоды с первого по четвертый, а при нажатии и удерживании, загораются и тухнут с четвертого по первый. Таким образом, мы можем влиять на выполнение программы, с помощью нажатия кнопки, опрашивая наличие на ней логического нуля, или логической единицы

Также , в котором находятся файл “сишник”, HEX и файл Протеуса.

А вот и видео

Что нужно для того, чтобы стать профессиональным разработчиком программ для микроконтроллеров и выйти на такой уровень мастерства, который позволит с лёгкостью найти и устроиться на работу с высокой зарплатой (средняя зарплата программиста микроконтроллеров по России на начало 2017 года составляет 80 000 рублей). ...

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

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

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


Дребезг контактов возникает во время замыкания или размыкания контактов. Посмотрите на рисунок:

Изначально контакт разомкнут.

Когда мы начинаем замыкать контакт (нажимаем на кнопку), то замыкание происходит не сразу.

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

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

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

А мы то ожидаем, что одно нажатие кнопки - это одно переключение входа микроконтроллера. Но на самом деле это не так. Потому что дребезг контактов вносит свою лепту в усложнение жизни инженеров.

Представьте, что наши кнопки - это клавиатура телефона. Мы нажимаем цифру 8, подразумевая, что эта цифра будет набрана телефоном один раз. Но телефон вместо этого набирает 5 или 10 восьмёрок, потому что разработчики телефона не удосужились предусмотреть защиту от дребезга контактов. Станете вы пользоваться таким телефоном?

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

Устранение дребезга контактов

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

Есть два способа борьбы с дребезгом контактов:

  1. Аппаратный
  2. Программный

Аппаратное подавление дребезга контактов

Аппаратное подавление дребезга - это схемные решения, которые позволяют устранить этот неприятный эффект. Чаще всего это простая RC-цепь, или вообще только один конденсатор.

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

Простая схема устранения дребезга контактов приведена на рисунке:

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

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

Программное подавление дребезга контактов

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

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

Самое простое и самое распространённое программное решение для борьбы с дребезгом - это временная задержка. Алгоритм простой:

  1. При изменении уровня сигнала на входе на противоположный включаем таймер (например, на 100 миллисекунд).
  2. После истечения задержки проверяем сигнал. Если он остался изменённым, то считаем, что кнопка нажата (или отпущена - в зависимости от того, какое изменение сигнала обнаружено). Если же он вернулся в исходное состояние, то считаем это помехой и не реагируем на сигнал.

Бывают особые случаи, когда быстрое переключение контактов - это обычное состояние системы. Ну например, если есть какой-то датчик, который по логике работы не может принимать фиксированное значение на длительное время. То есть идёт как бы непрерывный дребезг контактов. И в этом бесконечном потоке нам надо как-то определить, какой же всё-таки сигнал на входе.

В этом случае можно применить следующий алгоритм:

  1. Посчитать количество и/или продолжительность замкнутого и разомкнутого состояния контакта в единицу времени (например, в секунду).
  2. По наибольшему количеству (или времени) определить конечное состояние сигнала.

Например, если за секунду на входе у нас 50 раз была логическая 1, и 20 раз - логический 0, то можно считать, что на входе единица. Разумеется, здесь нужен индивидуальный подход в зависимости от задачи.

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


Первым примером в изучении микроконтроллеров является подключение и управление светодиодом, это самый простой и наглядный пример. Этот пример стал классическим при изучении микроконтроллеров, как программа "Hello World!" при изучении прочих языков программирования.

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

Из документации на микроконтроллер мы знаем, что у микроконтроллеров AVR максимальный ток, который способна пропустить каждая линия порта ввода/вывода составляет 40 mA. Превышение этого значения выведет из строя вывода порта. Поэтому ток, протекающий через вывод микроконтроллера не должен превышать 30 mA , самым оптимальным будет ток 20 mA.

Подключить светодиод к микроконтроллеру можно двумя способами

1. Подключение маломощного светодиода

Если ток потребления светодиода в рабочем режиме не превышает 30 мА, а номинальное напряжение не превышает напряжения питания микроконтроллера, то мы можем подключать его к линии порта ввода/вывода.

Что бы ограничить ток, протекающий через ножку микроконтроллера нужно рассчитать номинал резистора R1 .

Сопротивление рассчитывается по формуле:

R = (Vs - Vd) / I

где Vs - напряжение источника питания, Vd - прямое напряжение светодиода, а I

R = (5 V - 2.5 V) / 0.020 A = 150 Om

Таким образом, мы нашли R1 = 150 Om и дальше подбирается ближайшее большее значение сопротивления.

Если не известно прямое напряжение светодиода, сопротивление можно рассчитать по закону Ома.

R = U / I

где U - напряжение источника питания, а I - номинальный ток светодиода.

R = 5 V / 0.020 A = 250 Om

Определив номинал резистора R1 , необходимо рассчитать мощность P , измеряемая в ваттах, которая будет выделяться в резисторе, в виде тепла при протекании тока в цепи.

P = I * U

где U - напряжение, приложенное к участку цепи, а I - номинальный ток светодиода

P = 0.020 A * 5 V = 0.1 W

Рассчитав выделяемую мощность на резисторе, выбираем ближайшее большее значение мощности резистора. Если рассеиваемой мощности резистора будет недостаточной, то он может выйти из строя.

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

2. Подключение мощного светодиода

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

Таким образом, мы ушли от токовых ограничений вывода линии порта микроконтроллера. Резистор на базе - ограничительный. Может варьироваться в широких пределах 1-10 kOm, в любом случае транзистор будет работать в режиме насыщения. Использовать можно любой N-P-N транзистор. Коэффициент усиления, практически не имеет значения. Выбирается транзистор по току коллектора (нужный нам ток) и напряжению коллектор - эмиттер (напряжение которым запитывается нагрузка). Необходимо учитывать, что значение максимально допустимого тока коллектора транзистора должно быть больше чем значение номинального тока светодиода, а так же не забывать про рассеиваемую мощность транзистора.

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

1. Собрать нашу схему в симуляторе Proteus. Этот способ хорош тем, что можно быстро собрать схему, не нужно тратить деньги на приобретение радиокомпонентов.

2. Собрать схему на макетной плате и прошить микроконтроллер программатором. Придется потратить деньги, но мы получим опыт подкрепленный практикой.

Собрав схему можно преступить к написанию программы в
Исходный код:

#include //Включаем библиотеку для работы с микроконтроллером ATMega8 #include //Включаем библиотеку для организации задержек #define led 10 //Создаем идентификатор led void main(void) { PORTC=0x00; //Выставляем все выходы порта C на 0, то есть, выключаем весь порт C DDRC=0xFF; //Делаем порт C, как выход, чтобы на выходах порта было напряжение 5В while (1) //Организовываем бесконечный цикл { PORTC.5=1; //Включаем светодиод на 5-м выходе порта C delay_ms(led); //Делаем задержку, в миллисекундах PORTC.5=0; //Выключаем светодиод на 5-м выходе порта C delay_ms(led); //Делаем задержку, в миллисекундах } }

Описание программы:

Директивой #include подключаем внешние файлы. Заголовочный файл используемого микроконтроллера mega8.h и функцию задержки delay.h . Перед компиляцией CodeWisioneAVR вставит вместо строки

#include

#include

Директивой

#define led 10

определяем идентификатор led . Перед компиляцией CodeWisioneAVR в тексте программы заменит led на значение 30 .

Объявляем основную функцию программы main строчкой

Void main(void)

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

В выходной регистр порта C записываем ноли,

PORTC=0x00;

соответственно на всех ножках порта C будет напряжение 0 В.

В регистр направления данных порта C записываем единицы,

DDRC=0xFF;

порт будет работать как выход.

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

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

Нам нужно переключить только одну ножку порта C , для этого мы воспользовались побитным доступом к портам ввода/вывода микроконтроллера. Указав в регистр порта С бит в который мы запишем значение

PORTC.5 = 1; //(5 В)

PORTC.5 = 0; //(0 В)

мы включаем или отключаем наш светодиод.

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

Delay_ms(led)

которую подключили в начале программы файлом delay.h . Задержка генерируется в миллисекундах. Все идентификаторы led в программе будут заменены при компиляции на указанное значение 30 , т.е. задержки между интервалами включения и выключения будут по 30 миллисекунд.

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

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

Пример будем рассматривать на микроконтроллере ATMega8 .

Программу писать будем в Atmel Studio 6.0 .

Эмулировать схему будем в Proteus 7 Professional .

Самой распространенной задачей при создании проектов для микроконтроллеров является подключение кнопок. Несмотря на простоту, эта задача имеет существенные, возможно и неочевидные особенности.
Если подключить один из контактов кнопки, например, к общему проводу («земле»), а второй к выбранной линии порта ввода/вывода микроконтроллера, который переключен в режим «Вход», то выяснится, что такой метод не работает. При нажатии кнопки линия порта микроконтроллера соединяется с землей, и программа будет считывать лог.«0» с этой линии порта ввода/вывода, но при отпущенной кнопке вывод микроконтроллера не будет соединен ни с чем, что часто и называют «висит в воздухе». В таком случае программа будет считать с вывода и лог.«0» и лог.«1» случайным образом, так как на не к чему не присоединённую линию порта ввода/вывода будут наводится наводки.
Правильное подключение предполагает, что в разомкнутом состоянии вывод микроконтроллера должен быть соединен через резистор, например с шиной питания, а в замкнутом - с землей, либо наоборот. Сопротивление резистора не должно быть слишком маленьким, чтобы ток, текущий через него при замкнутых контактах кнопки не был слишком большим. Обычно используют значения порядка 10-100 кОм.

Рис: Подключения кнопки с подтянутой шиной питания.

- при отжатой кнопке равно лог.«1»;
- при нажатой кнопке равно лог.«0»;

Рис: Подключения кнопки с подтянутой землей.
При таком подключении состояние линии порта ввода вывода будет:
- при отжатой кнопке равно лог.«0»;
- при нажатой кнопке равно лог.«1»;

- подключения к линии порта ввода/вывода кнопки с подтянутой шиной питания:

#include // Основная программа int main(void) { // Настраиваем порты ввода/вывода DDRB = 0b11111111; //Настраиваем все разряды порта B на режим "Выход" PORTB = 0b00000000; //Устанавливаем все разряды порта B в лог.«0» (На выходе порта напряжение равное GND) DDRD = 0b00000000; //Настраиваем все разряды порта D на режим "Вход" PORTD = 0b11111111; //Устанавливаем все разряды порта D в лог.«1» (На выходе порта напряжение равное Vcc) // Вечный цикл while (1) { //Проверяем: если состояние PD0 лог.«0» то кнопка нажата if ((PIND&(1 << PD0)) == 0) { //Состояние PB0 устанавливаем в лог.«1» PORTB |= (1 << PB0); } else { //Состояние PB0 устанавливаем в лог.«0» PORTB &= ~(1 << PB0); } } }

- подключения к линии порта ввода/вывода кнопки с подтянутой землей:

// Подключаем внешние библиотеки #include #include // Основная программа int main(void) { // Настраиваем порты ввода/вывода DDRB = 0b11111111; //Настраиваем все разряды порта B на режим "Выход" PORTB = 0b00000000; //Устанавливаем все разряды порта B в лог.«0» (На выходе порта напряжение равное GND) DDRD = 0b00000000; //Настраиваем все разряды порта D на режим "Вход" PORTD = 0b11111111; //Устанавливаем все разряды порта D в лог.«1» (На выходе порта напряжение равное Vcc) // Вечный цикл while (1) { //Проверяем: если состояние PD0 лог.«1» то кнопка нажата if ((PIND&(1 << PD0)) == 1) { //Состояние PB0 устанавливаем в лог.«1» PORTB |= (1 << PB0); } else { //Состояние PB0 устанавливаем в лог.«0» PORTB &= ~(1 << PB0); } } }

Подключение питания.

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

К счастью, большинство микроконтроллеров нормально работают в широ­ком диапазоне внешних условий. Единственное, на что следует обратить вни­мание при разработке приложения, - это развязка питающего напряжения. Как правило, для развязки используется танталовый конденсатор емкостью 0,1мкФ, который подключается как можно ближе выводам питания. Этот кон­денсатор обеспечит повышенный выходной ток при переходных процессах, предохраняя аппаратуру отложных сбросов и искажения данных. Таким обра­зом простое включение конденсатора избавит вас от множества проблем.

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

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

В этой схеме сигнал RESET на входе микроконтроллера становится актив­ным (принимает значение логического 0) приблизительно через 22 мс (вре­мя задержки Td = 2,2 RC) после включения питания. Этого времени доста­точно для стабилизации напряжения питания и установки требуемой частоты тактового генератора прежде, чем начнет работать микроконтроллер.

Кнопка RESET используется в процессе разработки устройства для сбро­са микроконтроллера в начальное состояние. При отладке устройства очень полезно иметь возможность выполнения сброса, чтобы обеспечить повтор­ный запуск микроконтроллера. Резистор сопротивлением 100 Ом, который включен последовательно с конденсатором, служит для ограничения тока разряда конденсатора в момент сброса (заряженный конденсатор является источником большого тока, когда он закорачивается на «землю»). Эта схема может быть использована для запуска микроконтроллеров, у которых сигнал RESET имеет высокий активный уровень (например, микроконтроллер 8051), путем инвертирования напряжения на конденсаторе (например, с помощью микросхемы типа 7404).


Рис. 2.10 - Схема формирования сигнала запуска RESET.

Для некоторых микроконтроллеров можно удалить RC-цепь в схеме за­пуска, так как внутри них имеется схема, обеспечивающая задержку включе­ния (пуск тактового генератора и начало выполнения первой команды про­граммы). В этом случае схема запуска может быть упрошена, как показано на рис. 2.11. Посмотрев на эту схему, вы, возможно, подумаете, что схему можно еще более упростить, просто подключив вывод RESET к шине питания Vdd. Это верно, но использовать такое включение следует только после того, как схема будет полностью отлажена. Однако при этом целесообразно включить токоограничивающий резистор, чтобы иметь возможность повторного запус­ка путем закорачивания вывода RESET на «землю».

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

Для решения этой проблемы существуют устройства - мониторы пита­ния, которые следят за уровнем напряжения Vcc/Vdd. Если это напряжение падает ниже определенного уровня (обычно 4.5В), то вырабатывается сигнал RESET. Как правило, такие мониторы питания содержат схему задержки и работают аналогично описанной выше RC-схеме запуска. Они монтируются в такой же корпус, как трехвыводной транзистор.

Рис. 2.11 - Модифицированная схема RESET.

Похожие статьи