logo
HCS12 с применением языка С - royallib

5.2.3. Клавиатуры

Во многих приложениях микропроцессорные системы требуют ввода цифровой и буквенной информации. Для таких случаев могут быть использованы блоки из нескольких кнопок, которые объединены конструктивно и соединены электрически по стандартной матричной схеме. Такие блоки называют клавиатурами. На рис. 5.5 показана клавиатура из 16 клавиш, которая позволяет вводить данные в микропроцессорную систему в шестнадцатеричном коде. Изучим представленную на рис. 5.5 схему соединения МК с клавиатурой подробно.

Рис. 5.5. Схема подключения матричной клавиатуры к МК 68HC12

Кнопки клавиатуры собраны в матричную схему. Первый ряд составляют кнопки 0, 1, 2 и 3. Второй ряд — кнопки 4, 5, 6, и 7. Следующие восемь кнопок составляют ряд 3 и ряд 4. Выводы левых контактов кнопок одного ряда соединены между собой и подключены к одному из выводов порта PORTx (x — имя порта МК, например, PORTA, PORTB и т.д.). В нашем примере для обслуживания четырех линий клавиатуры использованы четыре линии порта PORTx[0]…..PORTx[3]. Все эти линии работают в режиме вывода.

Выводы правых контактов кнопок также соединены между собой. Но при этом объединены каждые четыре кнопки по вертикали, которые зрительно составляют единый столбец. Приведенное соединение называют матричным. Из рис. 5.5. можно видеть, что блок клавиатуры из 16 клавиш имеет всего восемь линий связи для подключения к МК. А если бы мы использовали ранее рассмотренные схемы соединения, то для подключения 16 кнопок портебовалось бы 16 линий связи. Четыре вывода столбцов подключаются ко входам порта PORTx[4]…PORTx[7]. Эти линии порта работают в режиме ввода. Каждая линии PORTx[4]…PORTx[7] снабжена подтягивающим к напряжению питания резистором R = 10 кОм.

Если все клавиши, принадлежащие к одной колонке, отжаты, то на соответствующем входе порта PORTx[4]…PORTx[7] формируется логическая 1. МК использует специальную программу опроса клавиатуры, чтобы обнаружить, какая клавиша в данный момент времени нажата. Эта программа сначала выставляет на линию PORTx[0] логический 0. Тогда все левые выводы клавиш первого ряда оказываются под потенциалом логического 0. Если одну из клавиш этого ряда нажать, то уровень сигнала на одном из входов PORTx[4]…PORTx[7] изменится с 0 на 1. Например, если нажали клавишу «0», то на входе PORTx[4] установится низкий логический уровень, а все остальные входы PORTx[5]…PORTx[7] останутся в 1. Или, если нажать клавишу «2», то в 0 установится вывод PORTx[6], а линии PORTx[4], PORTx[5] и PORTx[7] будут в 1. Таки образом, программа, прочитав состояние линий PORTx[4]…PORTx[7] и обнаружив 0 в каком-либо разряде, сможет установить, какая клавиша нажата.

Программа опроса клавиатуры последовательно анализирует состояние клавиш каждого ряда, последовательно выставляя логический 0 на выводы PORTx[0]…PORTx[3]. На рис. 5.5 приведена таблица, в которой показаны коды, которые будут на линиях порта при нажатии каждой из клавиш. Эти коды должны быть использованы программой опроса для приведения кода нажатой клавиши к одному из стандартных представлений, например к коду ACSII.

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

Рис. 5.6. Блок-схема алгоритма опроса матричной клавиатуры

На рис. 5.6 приведена блок-схема алгоритма опроса матричной клавиатуры из 16 клавиш. Этот алгоритм состоит из четырех одинаковых блоков, в которых сначала устанавливается в 0 одна из линий PORTx[0]…PORTx[3], а затем контролируется состояние линий PORTx[4]…PORTx[7]. Если на входах линий PORTx[4]…PORTx[7] логические 1, то ни одна кнопка активизированного ряда не нажата, и следует перейти к опросу следующего ряда. Если на какой-либо из линий PORTx[4]…PORTx[7] обнаружен потенциал логического 0, то по номеру линии и по номеру активизированного ряда программа должна восстановить код нажатой клавиши. Для этого удобно использовать таблицу рис. 5.5. Мы привели лишь общую структуру алгоритма. Детальное ее рассмотрение последует после примера программного кода, и описания ЖК дисплея.

/*-----------------------------------------------------------*/

/* filename: keypad.c                                        */

/* МAIN PROGRAМ: Эта программа производит анализ             */

/*состояния матричной клавиатуры из 16 клавиш                */

/*Для подключения клавиатуры использован PORTB               */

/*Разряды PORTB[0]…PORTB[3] активизируют линии рядов         */

/*разряды PORTB[4]…PORTB[7]используются для считывания кодов */

/*колонок                                                    */

/*-----------------------------------------------------------*/

/*подключаемые файлы*/

#include <912b32.h>

#include <stdio.h>

#include <math.h>

/*используемые функции*/

char keypad(unsigned char keypress, unsigned char row);

char which_key(unsigned char keypress); /*Function to select key*/

void main{void) {

 unsigned char keypress;

 /*задание кодов активизации рядов клавиатуры*/

 unsigned char first = 0xFE; /*код активизации первого ряда*/

 unsigned char second = 0xFD; /*код активизации второго ряда*/

 unsigned char third = 0xFB; /*код активизации третьего ряда*/

 unsigned char fourth = 0xF7; /*код активизации четвертого ряда*/

 DDRB = 0x0f; /*линии 0…3 на вывод, линии 4…7 на ввод*/

 while(1) {

  PORTB = 0xFE;

  keypress = PORTB;

  key = keypad(keypress, first);

  PORTB = 0xFD;

  keypress = PORTB;

  key = keypad(keypress, second);

  PORTB = 0xFB;

  keypress = PORTB;

  key = keypad(keypress, third);

  PORTB = 0xF7;

  keypress = PORTB;

  key = keypad(keypress, fourth);

 }

}

/*------------------------------------------------------------------------*/

/*Функция keypad определяет, была ли нажата какая-либо клавиша.           */

/*Функция сравнивает прочитанное значение порта PORTB с тем значением,    */

/*которое было выдано на порт PORTB. Если они равны, то ни одна клавиша в */

/*ряду не нажата                                                          */

/*------------------------------------------------------------------------*/

char keypad(unsigned char keypress, unsigned char row) {

 char key1;

 if (keypress != row) { /*какая-то клавиша нажата*/

  key1 = which_key(keypress); /*определить клавишу*/

  putchars(key1); /*передать символ на дисплей*/

 } else if(keypress == row) { /*ни одна из клавиш не нажата*/

  key1 = 'Z';

 }

 return (key1);

}

/*------------------------------------------------------------------------*/

/* Функция char which_key определяет код нажатой клавиши методом перебора */

/*табличных значений                                                      */

/*------------------------------------------------------------------------*/

char witch_key(unsigned char keypress) {

 char key;

 switch(keypress) /*распознавание кода клавиши*/

 {

 case 0xEE:

  key = '0'; /*нажата клавиша "0"*/

  break;

 case 0xDE:

  key = '1'; /*нажата клавиша "1"*/

  break;

 case 0xBE:

  key = '2'; /*нажата клавиша "2"*/

  break;

 case 0x7E:

  key = '3'; /*нажата клавиша "3"*/

  break;

 case 0xED:

  key = '4'; /*нажата клавиша "4"*/

  break;

 case 0xDD:

  key = '5'; /*нажата клавиша "5"*/

  break;

 case 0xBD:

  key = '6'; /*нажата клавиша "6"*/

  break;

 case 0x7D:

  key = '7'; /*нажата клавиша "7"*/

  break;

 case 0xEB:

  key = '8'; /*нажата клавиша "8"*/

  break;

 case 0xDB:

  key = '9'; /*нажата клавиша "9"*/

  break;

 case 0xBB:

  key = 'A'; /*нажата клавиша "A"*/

  break;

 case 0x7B:

  key = 'B'; /*нажата клавиша "B"*/

  break;

 case 0xE7:

  key = 'C'; /*нажата клавиша "C"*/

  break;

 case 0xD7:

  key = 'D'; /*нажата клавиша "D"*/

  break;

 case 0xB7:

  key = 'E'; /*нажата клавиша "E"*/

  break;

 case 0x77:

  key = 'F'; /*нажата клавиша "F"*/

  break;

 default:

  key = 'Z';

 } /*конец распознавание кода клавиши*/

 return(key);

}

/*----------------------------------------------------------*/

Представленный программный код не является полностью завершенной рабочей программой, поскольку в нем отсутствуют элементы защиты от дребезга контактов, отсутствует текст функции вывода символов на ЖК дисплей. Мы исправим эти недостатки несколько позже, в разделе 5.6.