Как подключить к микроконтроллеру кнопки

28/09/2009 - 21:00
   Почти ни одно изделие с микроконтроллером не обходится без кнопок. Тема эта уже избитая и во многом известная. Написанием этой статьи я не пытаюсь изобрести велосипед. Просто  решил собрать всю инфу по схемотехнике воедино. Думаю, что материал будет полезен начинающим.Чтобы не сбивать вас с толку, на приведенных ниже рисунках не показаны схемы питания, сброса и тактирования микроконтроллеров.

Способ первый - традиционный

самый простой способ подключения кнопки к микроконтроллеру
                             рис1а                                                                            рис1б
 
   Если кнопок немного и дефицита выводов мк не наблюдается, используем традиционный способ подключения.
   Когда кнопка отпущена – вывод мк через резистор соединен с “плюсом” питания (рис. 1а). Когда кнопка нажата – вывод мк соединен с землей. Подтягивающий резистор R1  ограничивает силу тока в цепи переключателя. Если бы его не было, то при нажатии кнопки мы бы просто закоротили наш источник питания.
   В большинстве современных микроконтроллеров есть встроенные подтягивающие резисторы, поэтому внешние можно не ставить (рис1б). В программе микроконтроллера нужно будет настроить используемый вывод на вход и включить внутренний подтягивающий резистор.
   Что произойдет, если вывод микроконтроллера окажется в режиме выхода? Это будет зависеть от состояния этого вывода. Если на выводе “логический  ноль” – ничего страшного не случиться, потому что - в первом случае (рис1а) величина втекающего тока ограничена резистором R1, а во втором случае (рис1б)  никакой ток вообще не потечет. При нажатии кнопки тоже ничего не случиться, поскольку разность потенциалов между выводом и “землей” в этом случае будет равна нулю.
   Если же на выводе будет ”логическая единица” и кнопка окажется нажатой, то через вывод микроконтроллера на землю потечет ток величиной в несколько десятков миллиампер и вывод порта может “погореть”. Предельно допустимый ток для вывода микроконтролера AVR согласно документации равен 40 мА. Поэтому иногда нелишним бывает поставить между выводом мк и кнопкой резистор номиналом в несколько сотен ом, например 330 (рис 1с). Так, например, подключены кнопки на отладочной плате STK500. Это сделано для подстраховки, чтобы пользователь нечаянно не спалил микроконтроллер в ходе своих эксперементов.
   Для своих макетов впрочем можно обойтись и без этого резистора. 
самый простой способ подключения кнопки к микроконтроллеру
 Рис 1с

Второй способ - с использованием диодов

подключение кнопок к микроконтроллеру с помощью диодов
Рис. 2а
подключение кнопок к микроконтроллеру с помощью диодов
Рис. 2б
     Используется когда кнопок больше двух, а выводы мк хочется сэкономить. Каждой кнопке в данном случае соответствует свой цифровой код, а  количество кнопок, которые можно таким способом повесить на N выводов мк =  2N  - 1. То есть на три вывода можно повесить 7 кнопок, на четыре – 15 и так далее... но я бы больше 7-ми вешать не стал. Увеличивается количество дополнительных внешних компонентов,  усложняется схема и программа мк. Кроме того, для большого количества кнопок есть и другие схемы включения. Подтягивающие резисторы на схеме не показаны, подразумевается, что используются внутренние.
   Кстати, через диоды еще можно завести сигналы от кнопок на вывод внешнего прерывания контроллера (рис. 3). При нажатии любой кнопки вывод внешнего прерывания через диод будет замыкаться на землю и вызывать прерывание (естественно при условии, что оно настроено и разрешено). Таким образом контроллеру не нужно будет постоянно опрашивать кнопки, эта процедура будет запускаться только по событию внешнего прерывания. 
подключение вывода прерывания через диоды ко всем кнопкам
                                                                             Рис. 3
 
   Данная схема актуальна не для всех микроконтроллеров AVR, потому что в некоторых моделях микроконтроллеров внешнее прерывание может возникать по любому изменению на любом выводе. (например в ATmega164P)
 

Третий способ – для матричной клавиатуры

подключение матричной клавиатуры к микроконтроллеру
Рис. 4
 
   Такой вариант подключения обычно используется для блоков из нескольких кнопок, которые объединены конструктивно и соединены электрически по матричной схеме. Но никто не запрещает использовать эту схему и для включения  обычных кнопок, однако реальную экономию она дает при количестве кнопок ? 9.
   Выводы PС0, PС1, PС2, PC3  – это строки матрицы, выводы PB0, PB1, PB2 – это столбцы матрицы. Кнопки можно опрашивать либо по строкам, либо по столбцам. Допустим, мы опрашиваем их по столбцам. Процедура опроса будет выглядеть следующим образом. Начальное состояние всех выводов – вход с включенным подтягивающим резистором. Устанавливаем вывод PB0 в режим выхода и выставляем ноль. Теперь нажатие кнопок S1, S2, S3, S4 будет замыкать выводы PС0, PС1, PС2, PC3 на 0 питания. Опрашиваем эти выводы и определям нажата ли какая-нибудь кнопка в данный момент. Устанавливаем вывод PB0 в режим выхода и включаем подтягивающий резистор. Устанавливаем вывод PB1 в режим выхода и выставляем ноль. Снова опрашиваем выводы PС0, PС1, PС2, PC3. Теперь нажатие кнопок S5, S6, S7, S8 будет замыкать выводы PС0, PС1, PС2, PC3. Последний столбец кнопок опрашиваем аналогично. 
 


   Строки матрицы можно завести через диоды на вывод внещнего прерывания. Тогда логику программы можно было бы построить так. Если клавиатура не используется в течении нескольких минут, микроконтроллер переходит в режим пониженного энергопотребления. При этом выводы PB0, PB1, PB2 – конфигурируются как выходы с нулевым логическим уровнем.  Когда одна из кнопок нажимается, вывод прерывания через диод замыкается на ноль. Это вызывает внешнее прерывание, микроконтроллер просыпается и запускает таймер по сигналам которого происходит сканирование клавиатуры. Параллельно запускается счетчик времени, который сбрасывается при нажатии любой из кнопок. Как только он переполняется, микроконтроллер опять переходит в режим пониженного энергопотребления. 
подключение матричной клавиатуры к микроконтроллеру

Четвертый способ – ацп в помощь

   Это, пожалуй, пограничный случай экономии выводов при подключении кнопок, поскольку задействован только один вывод микроконтроллера – вывод АЦП. Суть способа понятна из рисунка. У нас есть резистивный делитель  с известными уровнями напряжений на резисторах, с помощью кнопок эти напряжения мы коммутируем на вход АЦП. Контроллер оцифровывает напряжение на этом выводе  и, исходя из того, в какой диапазон попадает считанное напряжение, определяет номер нажатой кнопки.
  Когда ни одна кнопка не нажата, вход АЦП притянут к земле резистором R2. Оставлять вход АЦП плавающим нельзя, а то он будет ловить помехи. При замыкании кнопок резистор R2 оказывается включенным параллельно с резисторами делителя. Чтобы он не влиял на уровень напряжения на входе АЦП, его значение выбирают довольно большим. Резистор R1 предназначен для ограничения величины входного тока в случае если вывод контроллера окажется в режиме цифрового входа и будет нажата кнопка S5.
подключение нескольких кнопок к ацп микроконтроллера
Рис. 5


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

Продолжение следует...

 

Comments   

# alexandershahbazov 2009-12-08 21:58
Желательно все статьи ( там гне надо ! )
сопровождать схемами как здесь !

Понравилось !
# Guest 2010-01-04 19:14
О! Вот на тему входа в режиме выхода не задумывался. Круто! Буду ставить резюки, заодно помехозащищённо сть чуть выше будет!
# Guest 2010-01-26 02:53
Отличная статья для ликбеза!
Но почему бы не добавить еще "способов", например с использованием сдвиговых регистров с параллельной загрузкой (SN74HC165)?
# Guest 2010-01-26 03:03
По статье возник вопрос:
В варианте с "матричной клавиатурой" не совсем понятно почему вы рекомендуете неактивные выводы PB* переключать в режим входа с подтяжкой? чем чревата установка 1-цы в режиме выхода?
Спасибо.
# Pashgan 2010-01-26 06:48
Seych
Добавлю.. статья же не закрыта.

Просто режим "входа" безопаснее. Спалить вывод в таком режиме замыканием на + или 0 питания нельзя.
# Guest 2010-03-31 01:15
Хороший сайт. Творческих успехов автору
# Guest 2010-05-01 04:42
А как написать прогу для рисунка 2а.
Как выглядит код под CV.
# Pashgan 2010-05-03 13:59
Это на форум chipenable.ru/index.php/forum-chipenable.html. Сделай тему, а я накидаю код.
# Guest 2010-07-23 09:21
автор молодец! Спасибо за интересности. Жаль кодов нет, было бы очень наглядно!

А по поводу АЦП могу сказать так, я себе в одно время купил каждого номинала Е24 резисторов по 100 штук, получилось в пределах 250 грн по цене, и теперь никаких проблем с подбором резистора нужного сопротивления. Просто взял кулечек нашел номиналы, припаял и все.
# Guest 2010-10-03 09:17
Подскажите, пожалуйста, почему на рисунке 3 используются диоды? Нужно ли добавить резисторы, если при уровне "0" на любом выводе подтягивающий резистор отключается?
# Guest 2010-10-03 19:03
Схема логического И. Нажатие любой кнопки приводит к тому, что на выводе PD2 будет нулевой логический уровень.
Quote:
Нужно ли добавить резисторы, если при уровне "0" на любом выводе подтягивающий резистор отключается?
А как это происходит? Программно? Или у тебя какой-то МК особенный? Мне кажется, при 0 на входе отключение резистора ничего не меняет. Криминал будет только, если вход микроконтроллер а будет "болтаться в воздухе" при не нажатой кнопке
# n4nn31355 2010-10-24 02:54
а можно подробее в каки режимах можно будет обработать сразу все нажатые кнопки(т.е. чтобы не было такого что при нажатой А, кнопка В не орпеделится, пока А не отпустишь) и в каких случаях наоборот будет "висеть" только последнее нажатие и первое?
# Pashgan 2010-10-31 20:50
о какой схеме подключения идет речь? о схеме с диодами?
# Компилятор 2011-02-27 19:02
Кросава мольчишка !!!
Именно это я и искал =)
# Amator 2011-03-04 14:11
Хороший обзор. Теперь дело за кодом отработки нажатой клавиши для каждого варианта. :-)
# IRLML 2011-06-19 06:33
Подскажите, пожалуйста, на рисунке 3 нельзя обойтись перемычками вместо диодов?
# JoJo 2011-06-22 08:51
Нет, нельзя. Перемычки просто закоротят между собой все выводы мк.
# ДЕнис 2011-11-05 11:38
Хорошая статья СПАСИБО!!!!
# Андрей 2013-01-28 16:06
Привет Паша. Я тут опечатку у тебя обнаружил (или может сам недопонимаю) в обьяснение Рис.4;
"Устанавливаем вывод PB0 в режим выхода и выставляем ноль. Теперь нажатие кнопок S1, S2, S3, S4 будет замыкать выводы PС0, PС1, PС2, PC3 на 0 питания. Опрашиваем эти выводы и определям нажата ли какая-нибудь кнопка в данный момент. Устанавливаем вывод PB0 в режим выхода и включаем подтягивающий резистор. Устанавливаем вывод PB1 в режим входа (выхода?) и выставляем ноль."
# Pashgan 2013-01-28 18:17
Да, опечатка. Поправил.
# Fantiki007 2015-06-30 09:55
Еще одна опечатка. Написано "Устанавливаем вывод PB0 в режим выхода и включаем подтягивающий резистор. " Подтягивающий же только в режиме входа можно ставить :)
Правда, далее в таблице написано верно, и по ней становится понятно.
# Андрей 2013-01-28 16:09
Блин, чуть не забыл.. Спасибо за статью. Очень полезно и толково.
# Pashgan 2013-01-28 18:17
Пожалуйста.
# User11 2013-04-03 19:05
Очень доступно! Спасибо! :-)
# Calligraff 2016-06-21 04:17
Я так понимаю, что к схеме 2б тоже с помощью диодов можно организовать прерывание? Т.е. от каждой кнопки по диоду на порт прерывания добавить. Или нет?
# dgrett 2016-11-15 08:21
Смотрим схемы с диодами. Напр.2а. При нажатии S3 обе линии должны бы урониться в 0. Но на диодах упадет минимум 0,3В. Это надежно при питании 3В? Распознает АВРка как 0?
# Saniok 2018-05-20 14:31
а как добавить flash memory к этой схеме чтобы набранные число сохранились ))

У вас недостаточно прав для комментирования.