Матричная клавиатура
Автор DI HALT
Опубликовано 08 Сен 2008
Рубрики: Начинающим
Метки: Алгоритм, Клавиатура, Начинающим, Программирование, Схемотехника
Клавиатурная матрица.
Я ее нарисовал тебе на первой картинке. Как видишь, там есть строки и столбцы. Кружочками обозначены кнопки. Включены они так, что при нажатии кнопка замыкает строку на столбец.
Считывающий порт включается в режиме Pull-up входа, то есть вход с подтягивающими резисторами. Если контроллер это не поддерживает, то эти резисторы надо повесить снаружи.
Сканирующий порт работает в режиме выхода, он подключен к столбцам. Столбцы должны быть подтянуты резисторами к питанию. Впрочем, если используется полноценный Push-Pull то подтяжка не нужна - выход сам поднимет ногу на нужный уровень.
| Матричная клавиатура |
| Расширение разрядности дешифратором |
| Используя счетчик |
В сканирующий порт выводится значение, состоящее из одного нуля и единицы на всех остальных выводах. Пусть, например, ноль будет на выводе А. Наличие нуля сразу же придавливает подтяжку и весь столбец ложится на землю.
Теперь считываем сразу все значение из читающего порта. Если на столбце А не нажата ни одна кнопка, то в порту будут все единички. Но стоит нажать любую кнопку из столбца А, так она сразу же замкнет линию А, на этот вывод порта. В линии А у нас в данный момент 0, это обеспечивает ноль на сканирующем выводе контроллера. Поэтому и на соответствующем выводе порта будет 0
Так что, если будет нажата кнопка, например, 6, то на линии Р1 будет 0.
Потом число в сканирующем порту сдвигается на один бит влево (или вправо) и сканируется второй столбец и так по кругу. В итоге, зная какой столбец мы сканируем, получив ноль на считывающем порту, мы, как по координатам, поймем какая кнопка из матрицы нажата.
Можно определить одновременные нажатия многих кнопок - надо просто делать проверку не по байту, а по конкретному биту.
Увеличение разрядности
Но что делать если у нас кнопок не просто много, а очень много. Что даже матрицирование не спасает от огромного расхода линий порта. Тут приходится либо жертвовать несколько портов, либо вводить дополнительную логику. Например дешифратор с инверсным выходом.
Дешифратор, это такая микросхема, принимающая на вход двоичный код, а на выходе выдает единицу в выбранный разряд. Т.е. подали число “101″ - получили “1″ на выводе номер 5. Ну, а у инверсного дешифратора будет 0.
Можно пойти еще дальше и поставить микросхему счетчик, который дергать импульсом с порта, значение со счетчика прогонять через дешифратор. Таким образом, можно влепить сколько угодно выводов, хватило бы разрядности дешифратора. Главное учитывать на каком такте счетчика у нас будет какой столбец.
Если сканируется обычная клавиатура, нажимаемая человеком, то можно не заморачиваться на скорость опроса и сделать его в качестве побочного продукта, повесив на какое-нибудь левое прерывание. Достаточно чтобы клава опрашивалась хотя бы 10-20 раз в секунду. Этого уже достаточно, для комфортной работы.
Дребезг контактов и борьба с ним.
При работе с механическими кнопками возникает одна проблема - дребезг контактов. Суть его в том, что при замыкании контакт срабатывает не один раз, а в момент замыкания и размыкания происходит несколько срабатываний. Происходит это от того, что идеальный контакт возникает не сразу, а через какое то время, искрит и скрежещет, хоть это и не видно. Вот и получается, что вместо одного перепада получаем вначале серию всплесков и только потом возникает устойчивое состояние.
Но микроконтроллер работает с такой скоростью, что успевает посчитать эти всплески как устойчивые состояния. Решить эту проблему можно аппаратно, с помощью RS триггера, так и программно — внеся небольшую задержку перед следующим опросом кнопки. Задержка подбирается такой, чтобы дребезг успел прекратиться к ее окончанию.
Комментарии
52 комментариев на «Матричная клавиатура»
Оставьте свой отзыв
Вы должны войти, чтобы оставлять комментарии.





Интересная тема. Про матрицу знаю. Про дешифратор тоже догадывался. А про счётчик - что-то новое. Ещё можно заметить, что таким же образом можно не только вводить данные, но и выводить их, например на светодиодную матрицу. Да?
В принципе можно. Тоже подключаешь нужный столбец к земле ножкой проца, а на строку даешь напругу. Только тут надо будет убрать подтяжки и оба выхода сделать на Push-Pull.
а если надо нажать одновременно несколько кнопок в одном ряду или вывести в этот ряд несколько светодиодов из матрицы?
А вы ещё не поняли, что матрица быстро-быстро сканируется по строка м столбцам, как двумерный массив?
“Потом число в сканирующем порту сдвигается на один бит влево (или вправо) и сканируется второй столбец и так по кругу. В итоге, зная какой столбец мы сканируем, получив ноль на считывающем порту, мы, как по координатам, поймем какая кнопка из матрицы нажата.”
При такой схеме будут проблемы с одновременным распознаванием при нажатии некоторых групп кнопок. Для точного определения нужно водить в схему диоды.
Ввел :)
Для тех, кто не сразу врубился, какие могут быть проблемы - при нажатии двух кнопок в одной строке, два сканирующих порта оказываются замкнутыми накоротко, причём один из портов ставит 0, а второй 1. Будет нехорошо.
Если диоды стоят, то ничо страшного не произойдет.
Ну так я собственно и объясняю для тех, кто не понял, зачем эти диоды нужны. :)
а если вместо диодов программно переключать порты на вход (кроме сканирующего в данный момент)?
Здравая мысль. А подтяжку сделает внутренний резистор. Можно и так.
Совсем прям одновременно нельзя. Но можно же это сделать по очереди. Если делать все быстро-быстро никто и не заметит подставы :)
Без диодов на сканирующем порту получим КЗ при замыкании двух кнопок в разных столбцах!
Угу, добавил. Совсем забыл про эту проблему. Т.к. всегда делал клаву только на АТ89С51 а у него квазидвунаправленные порты, поэтому там КЗ в принципе сделать низя.
С такой простейшей схемой надо выводить в сканирующий порт не “значение, состоящее из одного нуля и единицы на всех остальных выводах”, а “все выводы сканирующего порта переключаем на вход (обеспечивая Z-состояние), далее один из выводов порта переключаем на выход, и выдаем на него ноль”.
Сухая теория =) Хоть бы кодом разбавил. Щас буду кстати делать эту самую клавиатуру… мать ийо так =)
Будет ради этого отдельный пост. ТАм и UART на практике заюзаю.
Для использования счетчика надо задействовать его вход Reset, т.к. многие счетчики не гарантируют “нулевого” состояния при подаче питания.
Ну это такой, идеально обобщенный счетчик.
Да понятно, но даже для обобщенного счетчика можно дать понять, что 1 выводом микроконтроллера не обойтись :)
Почему? А кто мешает сбросить счетчик RC цепью? А циклический пересчет делать по последнему разряду или по переполнению?
Здравствуйте. Начал почтигать AVR с вашего сайта. Большое спасибо за различного рода инфу. Я даж на рабостях микроконтроллер приобрёл AT89C52 , бегущие огоньки хотел сделать.
С АТ89С52 ты погорячился. К нему спец программатор нужен. И вообще это не AVR а MSC-51 - совершенно другая система команд и архитектура.
Эт я уже догадался. Но руки чесались а душа требовала. В следующий раз буду внимательнее.
Я тоже в это вляпался. Зато выглядит солиднее атмеги))
ATmega16 в планаре. Всё, что было и выглядит солидно… развлекаюсь.
На первой схеме, с клавиатурой, кнопки странно пронумерованы.
Их всего вроде 25, а не 26.
Спасибо за статью.
Интересно еще было бы почитать про то, как правильно использовать RS триггер. У меня почему то не получилось и дребезг дальше проникает за триггер.
А как именно ты триггер использовал?
Мне нужно было сделать что бы можно было четко фиксировать состояние (включено/выключено). Сделал по типовой схеме найденой в интернете. В результате, малейшее случайное касание проводников меняло состояние триггера. Нажатие кнопки приводило к множественному изменению состояний и в результате неизвестно было, где он остановится.
Понимаю, что надо дополнительную обвеску делать, что бы избавится от этого влияния, но как именно - тут уже не хватает знаний.
сделай программную обработку. Нажатия и все. Или у тебя не используется контроллер?
berrymorr. kicks-ass. org /avrkbd.png
а так можно организовать клавиатуру (если не бояться нажатия нескольких кнопок)?
Без диодов нежелательно. А так можно. Какие проблемы? Разве что тебе придется заморочиться на сдвиг полупорта, но это не велика проблема - битовые маски тебе в помощь.
просто что у вас, что в атмеловских аппноутах подтяжка есть.
а куда тогда диоды втыкать, если без подтяжки?
А ты хочешь забить на возможный КЗ и сделать без резисторов. В таком случае подтяг не нужен - ты уровень жестко задаешь столбцом. Но нажал две разные кнопки и спалил порт. Оно тебе надо?
так вроде же диоды от КЗ спасали?
от КЗ защищена схема только с диодами и подтягом?
если нет, то какой может быть простейшая схема с защитой от КЗ?
Они спасут от КЗ, но они же не дадут ногу поднять вверх. Поэтому и нужен внешний подтяг.
Хотя не. Подтяжку дает регистр считывающего порта. Слабую но дает. Уровень задает столбец. Низкий уровень нам прокачает, а высокий нам не важен. Один фиг на низкий работает. Да, будет работать без подтяжки и с диодами.
Видел другой вариант клавы - цепочка резисторов одинакового номинала от VCC до GND, а все места соединения резисторов через кнопки подключены ко входу АЦП. собственно т.к. все резисторы одинакового номинала, то при нажатии на кнопку получаем на входе ацп напряжение VCC/число резисторов*порядковый номер кнопки, ну а на выходе ацп - уже сразу готовый байт. только в младших разрядах думаю будет мусор - поэтому можно сдвинуть байт вправо. ну и подобрат разницу напряжений на кнопках, чтобы лучше ложилась в разрядную сетку ацп.
Можно, но на это надо АЦП тратить, а не во всех МК он есть
1. DI HALT, а как, если не нажата клавиша, в считывающем порту будут единицы? На рисунке выводы этого порта как в воздухе висят, откуда на них идет плюс?
2. А зачем диоды в схеме?
Подтягивающие резисторы внутри МК. Можно внешние резисторы поставить, не помешает.
А чтобы при нажатии кнопок на одной строке не было кз между столбцами. На них ведь 0 и 1 будут.
Все равно не понял, так это же вроде входа у нас, как на них 1 тогда появилась? Мы не с Vcc берем?
Покури матчасть, а именно работу портов МК.
У АВР или ПИК (а у классического С51 только так и могут) порты могут работать на вход с подтяжкой. Т.е. он изнутри всегда на Vcc подцеплен через резистор и когда сигнала нет дает 1, а извне мы можем приложить его к земле.
Да, речь идет о защите от замыкании между собой ножек А В С Д на сканирующем порту.
извиняюсь конечно если фигню сморожу, но разве неможно принимающий порт выставить в высоко импедансное состояние и тупо слушать. тогда можно как на ВВ59 4 бита на строку и 4 на столб, имеем 16 кнопочков… или я чот недопонял очень?
А как ты отличишь на какой строке/столбце было нажатие? Только сканом!
эм… ну допустим… эм… блин, да. но зато можно не париться над козами и подтягами =)
Ещеб оно работало при этом. Хы. Можешь сам попробовать :)
или опять глубокое заблуждение?
Попробуй! Никто от этого не умрет, зато поймешь в чем ты заблуждаешься :)
в принципе это и есть самый прямой способ научиться и понять :)
в теории правда выглядит всё красиво… как я понял из комикса с упячко-мэном :) то скан можно делать внутренний (не знаю как правильно) и при этом имея нажатия допустим на 2х кнопках, получим что-то вида 1101 1001 ( нажаты будут клавиши 3го столбца 2ой и 3её строки) вот как-то так.
Вот только если у тебя и строка и столбец будут в hiz то откуда у тебя будут уровни то?