Матричная клавиатураPrint This Post

Автор DI HALT
Опубликовано 08 Сен 2008 
Рубрики: Начинающим
Метки: , , , ,

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

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

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

Сканирующий порт работает в режиме выхода, он подключен к столбцам. Столбцы должны быть подтянуты резисторами к питанию. Впрочем, если используется полноценный Push-Pull то подтяжка не нужна - выход сам поднимет ногу на нужный уровень.

Работает следующим образом.
Матричная клавиатура
Матричная клавиатура
Расширение разрядности дешифратором
Расширение разрядности дешифратором
Используя счетчик
Используя счетчик

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

Теперь считываем сразу все значение из читающего порта. Если на столбце А не нажата ни одна кнопка, то в порту будут все единички. Но стоит нажать любую кнопку из столбца А, так она сразу же замкнет линию А, на этот вывод порта. В линии А у нас в данный момент 0, это обеспечивает ноль на сканирующем выводе контроллера. Поэтому и на соответствующем выводе порта будет 0
Так что, если будет нажата кнопка, например, 6, то на линии Р1 будет 0.

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

Можно определить одновременные нажатия многих кнопок - надо просто делать проверку не по байту, а по конкретному биту.

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

Дешифратор, это такая микросхема, принимающая на вход двоичный код, а на выходе выдает единицу в выбранный разряд. Т.е. подали число “101″ - получили “1″ на выводе номер 5. Ну, а у инверсного дешифратора будет 0.

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

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

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

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

Комментарии

52 комментариев на «Матричная клавиатура»


  1. foxweb 08 Сен 2008 3:15

    Интересная тема. Про матрицу знаю. Про дешифратор тоже догадывался. А про счётчик - что-то новое. Ещё можно заметить, что таким же образом можно не только вводить данные, но и выводить их, например на светодиодную матрицу. Да?

    DI HALT

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

    nwanomaly

    а если надо нажать одновременно несколько кнопок в одном ряду или вывести в этот ряд несколько светодиодов из матрицы?

    foxweb

    А вы ещё не поняли, что матрица быстро-быстро сканируется по строка м столбцам, как двумерный массив?

    “Потом число в сканирующем порту сдвигается на один бит влево (или вправо) и сканируется второй столбец и так по кругу. В итоге, зная какой столбец мы сканируем, получив ноль на считывающем порту, мы, как по координатам, поймем какая кнопка из матрицы нажата.”

    Mazayac

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

    DI HALT

    Ввел :)

    Stebanoid

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

    DI HALT

    Если диоды стоят, то ничо страшного не произойдет.

    Stebanoid

    Ну так я собственно и объясняю для тех, кто не понял, зачем эти диоды нужны. :)

    gleb

    а если вместо диодов программно переключать порты на вход (кроме сканирующего в данный момент)?

    DI HALT

    Здравая мысль. А подтяжку сделает внутренний резистор. Можно и так.

    DI HALT

    Совсем прям одновременно нельзя. Но можно же это сделать по очереди. Если делать все быстро-быстро никто и не заметит подставы :)


  2. Mazayac 08 Сен 2008 13:27

    Без диодов на сканирующем порту получим КЗ при замыкании двух кнопок в разных столбцах!

    DI HALT

    Угу, добавил. Совсем забыл про эту проблему. Т.к. всегда делал клаву только на АТ89С51 а у него квазидвунаправленные порты, поэтому там КЗ в принципе сделать низя.


  3. Mazayac 08 Сен 2008 13:33

    С такой простейшей схемой надо выводить в сканирующий порт не “значение, состоящее из одного нуля и единицы на всех остальных выводах”, а “все выводы сканирующего порта переключаем на вход (обеспечивая Z-состояние), далее один из выводов порта переключаем на выход, и выдаем на него ноль”.


  4. Fi5t 09 Сен 2008 0:57

    Сухая теория =) Хоть бы кодом разбавил. Щас буду кстати делать эту самую клавиатуру… мать ийо так =)

    DI HALT

    Будет ради этого отдельный пост. ТАм и UART на практике заюзаю.


  5. Mazayac 09 Сен 2008 14:29

    Для использования счетчика надо задействовать его вход Reset, т.к. многие счетчики не гарантируют “нулевого” состояния при подаче питания.

    DI HALT

    Ну это такой, идеально обобщенный счетчик.

    Mazayac

    Да понятно, но даже для обобщенного счетчика можно дать понять, что 1 выводом микроконтроллера не обойтись :)

    DI HALT

    Почему? А кто мешает сбросить счетчик RC цепью? А циклический пересчет делать по последнему разряду или по переполнению?


  6. Susanin 09 Сен 2008 19:43

    Здравствуйте. Начал почтигать AVR с вашего сайта. Большое спасибо за различного рода инфу. Я даж на рабостях микроконтроллер приобрёл AT89C52 , бегущие огоньки хотел сделать.

    DI HALT

    С АТ89С52 ты погорячился. К нему спец программатор нужен. И вообще это не AVR а MSC-51 - совершенно другая система команд и архитектура.

    Susanin

    Эт я уже догадался. Но руки чесались а душа требовала. В следующий раз буду внимательнее.

    IDOL 1234

    Я тоже в это вляпался. Зато выглядит солиднее атмеги))

    emmgold

    ATmega16 в планаре. Всё, что было и выглядит солидно… развлекаюсь.


  7. 'R Dee 05 Окт 2008 13:20

    На первой схеме, с клавиатурой, кнопки странно пронумерованы.
    Их всего вроде 25, а не 26.

    Спасибо за статью.

    Интересно еще было бы почитать про то, как правильно использовать RS триггер. У меня почему то не получилось и дребезг дальше проникает за триггер.

    Stebanoid

    А как именно ты триггер использовал?

    'R Dee

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

    DI HALT

    сделай программную обработку. Нажатия и все. Или у тебя не используется контроллер?


  8. berrymorr 06 Фев 2009 18:26

    berrymorr. kicks-ass. org /avrkbd.png
    а так можно организовать клавиатуру (если не бояться нажатия нескольких кнопок)?

    ldi r16,0xF0
    out DDRA,r16
    ldi r16,0x0F
    out PORTA,r16
    DI HALT

    Без диодов нежелательно. А так можно. Какие проблемы? Разве что тебе придется заморочиться на сдвиг полупорта, но это не велика проблема - битовые маски тебе в помощь.

    berrymorr

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

    DI HALT

    А ты хочешь забить на возможный КЗ и сделать без резисторов. В таком случае подтяг не нужен - ты уровень жестко задаешь столбцом. Но нажал две разные кнопки и спалил порт. Оно тебе надо?

    berrymorr

    так вроде же диоды от КЗ спасали?
    от КЗ защищена схема только с диодами и подтягом?
    если нет, то какой может быть простейшая схема с защитой от КЗ?

    DI HALT

    Они спасут от КЗ, но они же не дадут ногу поднять вверх. Поэтому и нужен внешний подтяг.

    DI HALT

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


  9. testicq 10 Фев 2009 2:50

    Видел другой вариант клавы - цепочка резисторов одинакового номинала от VCC до GND, а все места соединения резисторов через кнопки подключены ко входу АЦП. собственно т.к. все резисторы одинакового номинала, то при нажатии на кнопку получаем на входе ацп напряжение VCC/число резисторов*порядковый номер кнопки, ну а на выходе ацп - уже сразу готовый байт. только в младших разрядах думаю будет мусор - поэтому можно сдвинуть байт вправо. ну и подобрат разницу напряжений на кнопках, чтобы лучше ложилась в разрядную сетку ацп.

    DI HALT

    Можно, но на это надо АЦП тратить, а не во всех МК он есть


  10. denilson 31 марта 2009 18:17

    1. DI HALT, а как, если не нажата клавиша, в считывающем порту будут единицы? На рисунке выводы этого порта как в воздухе висят, откуда на них идет плюс?

    2. А зачем диоды в схеме?

    DI HALT

    Подтягивающие резисторы внутри МК. Можно внешние резисторы поставить, не помешает.

    А чтобы при нажатии кнопок на одной строке не было кз между столбцами. На них ведь 0 и 1 будут.

    denilson

    Все равно не понял, так это же вроде входа у нас, как на них 1 тогда появилась? Мы не с Vcc берем?

    DI HALT

    Покури матчасть, а именно работу портов МК.

    У АВР или ПИК (а у классического С51 только так и могут) порты могут работать на вход с подтяжкой. Т.е. он изнутри всегда на Vcc подцеплен через резистор и когда сигнала нет дает 1, а извне мы можем приложить его к земле.

    Да, речь идет о защите от замыкании между собой ножек А В С Д на сканирующем порту.


  11. kaktus37 06 мая 2010 0:41

    извиняюсь конечно если фигню сморожу, но разве неможно принимающий порт выставить в высоко импедансное состояние и тупо слушать. тогда можно как на ВВ59 4 бита на строку и 4 на столб, имеем 16 кнопочков… или я чот недопонял очень?

    DI HALT

    А как ты отличишь на какой строке/столбце было нажатие? Только сканом!

    kaktus37

    эм… ну допустим… эм… блин, да. но зато можно не париться над козами и подтягами =)

    DI HALT

    Ещеб оно работало при этом. Хы. Можешь сам попробовать :)

    kaktus37

    или опять глубокое заблуждение?

    DI HALT

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

    kaktus37

    в принципе это и есть самый прямой способ научиться и понять :)

    kaktus37

    в теории правда выглядит всё красиво… как я понял из комикса с упячко-мэном :) то скан можно делать внутренний (не знаю как правильно) и при этом имея нажатия допустим на 2х кнопках, получим что-то вида 1101 1001 ( нажаты будут клавиши 3го столбца 2ой и 3её строки) вот как-то так.

    DI HALT

    Вот только если у тебя и строка и столбец будут в hiz то откуда у тебя будут уровни то?

Оставьте свой отзыв

Вы должны войти, чтобы оставлять комментарии.


Материалы сайта являются авторскими. Копирование и публикация материалов без активной ссылки на первоисточник запрещено.

Реклама: