Как подключить к микроконтроллеру кнопки
28/09/2009 - 21:00
Pavel Bobkov
Почти ни одно изделие с микроконтроллером не обходится без кнопок. Тема эта уже избитая и во многом известная. Написанием этой статьи я не пытаюсь изобрести велосипед. Просто решил собрать всю инфу по схемотехнике воедино. Думаю, что материал будет полезен начинающим.Чтобы не сбивать вас с толку, на приведенных ниже рисунках не показаны схемы питания, сброса и тактирования микроконтроллеров.
рис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
сопровождать схемами как здесь !
Понравилось !
Но почему бы не добавить еще "способов", например с использованием сдвиговых регистров с параллельной загрузкой (SN74HC165)?
В варианте с "матричной клавиатурой" не совсем понятно почему вы рекомендуете неактивные выводы PB* переключать в режим входа с подтяжкой? чем чревата установка 1-цы в режиме выхода?
Спасибо.
Добавлю.. статья же не закрыта.
Просто режим "входа" безопаснее. Спалить вывод в таком режиме замыканием на + или 0 питания нельзя.
Как выглядит код под CV.
А по поводу АЦП могу сказать так, я себе в одно время купил каждого номинала Е24 резисторов по 100 штук, получилось в пределах 250 грн по цене, и теперь никаких проблем с подбором резистора нужного сопротивления. Просто взял кулечек нашел номиналы, припаял и все.
Quote: А как это происходит? Программно? Или у тебя какой-то МК особенный? Мне кажется, при 0 на входе отключение резистора ничего не меняет. Криминал будет только, если вход микроконтроллер а будет "болтаться в воздухе" при не нажатой кнопке
Именно это я и искал =)
"Устанавливаем вывод PB0 в режим выхода и выставляем ноль. Теперь нажатие кнопок S1, S2, S3, S4 будет замыкать выводы PС0, PС1, PС2, PC3 на 0 питания. Опрашиваем эти выводы и определям нажата ли какая-нибудь кнопка в данный момент. Устанавливаем вывод PB0 в режим выхода и включаем подтягивающий резистор. Устанавливаем вывод PB1 в режим входа (выхода?) и выставляем ноль."
Правда, далее в таблице написано верно, и по ней становится понятно.
RSS feed for comments to this post