— код опроса первой колонки клавиатуры — 11110111b;
— код опроса второй колонки клавиатуры — 11111011b;
— код опроса третьей колонки клавиатуры — 11111101b;
— код опроса четвертой колонки клавиатуры — 11111110b.
То есть для опроса состояния кнопок клавиатуры потребуется выдача на порт Р1, по крайней мере, четырех кодов. При этом следует отметить, что скан-код, считанный с клавиатуры, содержит намного больше информации, чем просто номер замкнутого контакта. Например, при помощи скан-кода можно определить нажатие нескольких кнопок одновременно, поэтому лучше хранить во внутренней памяти контроллера непосредственно скан-код, а не готовый номер кнопки. Пример подпрограммы опроса клавиатуры приведен в листинге 7.23.
В результате работы этой подпрограммы нули появятся в битах, соответствующих цепям колонок и строк клавиатуры, к которым подключены нажатые кнопки. Использование операции побитового умножения
Эта же подпрограмма может быть реализована и на языке программирования ассемблер. При этом она практически не будет отличаться от подпрограммы, приведенной выше (см. листинг 7.23). Пример реализации опроса клавиатуры на языке программирования ASM-51 приведен в листинге 7.24.
Интересной особенностью приведенной подпрограммы является использование команды sjmp, позволяющее превратить команду перехода по неравенству кодов cjne в команду перехода по равенству кодов. Остальные действия подробно пояснены комментариями и поэтому в дополнительных пояснениях не нуждаются.
Следующая подпрограмма обработки данных может из скан-кодов сформировать последовательности (строки) кодов нажатых кнопок, которые могут быть использованы как управляющие команды. Для хранения этих последовательностей можно использовать массив символов (в языке программирования ассемблер это просто соседние ячейки памяти).
При написании программы до сих пор считалось, что мы работаем с идеальными кнопками. Однако это не так. Обычно при нажатии и отпускании кнопки возникает переходный процесс, который называется дребезгом контактов. Начинающие разработчики аппаратуры применяют различные методы борьбы с этим явлением — от применения специальных схемотехнических решений до повторного опроса кнопок в течение некоторого времени.
Рассмотрим подробнее механизм возникновения явления дребезга контактов. Его причиной является упругость самих контактов. При нажатии на кнопку или при срабатывании какого-либо датчика контакты испытывают механическое импульсное воздействие. Обладая некоторой упругостью и массой, они начинают совершать колебательное движение: один контакт ударяется о другой (замыкание) и снова отходит (размыкание). Колебательный процесс продолжается некоторое время. При этом количество замыканий и размыканий контактов случайно и зависит от механических свойств контактов и механической силы, воздействующей на эти контакты. Обычно этот процесс длится от одной до восьми миллисекунд.
Если мы будем опрашивать состояние контактов с периодом, превышающим максимальную длительность дребезга, то даже не заметим, что они несколько раз замыкались или размыкались в промежутке между опросами контактов. Для этого можно включить в основной цикл программу, которая будет обеспечивать выполнение цикла один раз за строго определенное время.
Пример временной диаграммы сигнала на контактах кнопки приведен на рис. 7.14. На временной оси этого рисунка моменты считывания сигналов показаны рисками. Внизу рисунка обозначены номера временных слотов. На приведенной временной диаграмме четко просматривается зона дребезга контактов.
Для иллюстрации эффекта подавления дребезга контактов за счет ввода информации в строго определенные моменты времени на этой временной диаграмме выбран наихудший случай момента взятия отсчета. Этот момент совпадает с зоной дребезга контактов. При этом на выводе порта микроконтроллера может быть считан сигнал логического нуля или логической единицы. Но даже в этом случае дополнительный импульс в считанном сигнале не возникает! В случае считывания в момент дребезга контактов логического нуля сигнал, введенный в микроконтроллер, будет выглядеть как показано на рис. 7.14 сплошной линией, а в случае считывания логической единицы — пунктиром. Однако вне зависимости от того, какое значение сигнала мы считаем — нулевое или единичное, переход будет только один.
Рис. 7.14.