
В этой статье описан вариант подключения 9-и кнопочной матричной клавиатуры к 6-и линиям микроконтроллера (МК) AVR. Вообще способов подключения классических матричных клавиатур к любому типу МК бесчисленное множество, и способ, описанный здесь не нов. Целью же этой статьи было ознакомление новичков с написанием простых программ для МК AVR на языке Си. Схема подключения клавиатуры к МК представлена на рисунке.
Ниже представлен исходный код для, так называемого, быстрого способа сканирования.
Способ отличителен тем, что сначала устанавливаются в состояние логического нуля все линии строк МК, и считывается состояние линий столбцов.
После этого устанавливаются в состояние логического нуля все линии столбцов, и считывается состояние линий строк.
Возвращенные значения состояний линий столбцов и строк впоследствии объединяются в код, идентифицирующий нажатую кнопку.
Недостатком такого способа сканирования является возможность выявлять только одиночные нажатия.
Достоинством является малый программный код, быстрая обработка клавиатуры, а так же отсутствие дополнительных ограничительных резисторов на линиях МК.
#define NOP() asm("nop")
/* команда ассемблера "nop" */
/* определения портов клавиатуры */
/* порты строк */
#define KB_PORT_ROW PORTB
#define KB_PIN_ROW PINB
#define KB_DDR_ROW DDRB
/* порты столбцов */
#define KB_PORT_COL PORTD
#define KB_PIN_COL PIND
#define KB_DDR_COL DDRD
/* определения для линий матричной клавиатуры */
/* линии строк */
#define KB_ROW_WIRE_1 ((char)(1 << PB4))
#define KB_ROW_WIRE_2 ((char)1 << PB3))
#define KB_ROW_WIRE_3 ((char)1 << PB2))
#define KB_ROW_WIRES ((char)(KB_ROW_WIRE_1 | KB_ROW_WIRE_2 | KB_ROW_WIRE_3))
#define KB_ROW_SHIFT PB2 /* количество сдвигов вправо кода строк при формировании кода кнопки */
/* линии столбцов */
#define KB_COL_WIRE_1 ((char)(1 << PD6))
#define KB_COL_WIRE_2 ((char)(1 << PD5))
#define KB_COL_WIRE_3 ((char)(1 << PD4))
#define KB_COL_WIRES ((char)(KB_COL_WIRE_1 | KB_COL_WIRE_2 | KB_COL_WIRE_3))
/******************************************************************************
Опрос клавиатуры. Возвращает код нажатой кнопки.
В старшей тетраде – состояние линий строк, в младшей тетраде – состояние линий столбцов
Если в одной из тетрад кода кнопки более одного нуля, код не действительный
******************************************************************************/
char KB_Read_3x3(void)
{
char code1, code2;
KB_DDR_ROW &= ~KB_ROW_WIRES; /* порт строк на ввод */
KB_PORT_ROW |= KB_ROW_WIRES; /* к выводам порта строк подключаем pull-up резисторы */
KB_DDR_COL |= KB_COL_WIRES; /* порт столбцов на вывод */
KB_PORT_COL &= ~KB_COL_WIRES; /* на всех выводах порта столбцов лог "0" */
NOP(); /* задержка на один такт, для установления сигналов на выводах порта */
code1 = (KB_PIN_ROW >> KB_ROW_SHIFT) &
0x07; /* считываем состояние линий строк и преобразуем в код */
KB_DDR_COL &= ~KB_COL_WIRES; /* порт столбцов на ввод */
KB_PORT_COL |= KB_COL_WIRES; /* к выводам порта столбцов подключаем pull-up резисторы */
KB_DDR_ROW |= KB_ROW_WIRES; /* устанавливаем направление порта строк на вывод */
KB_PORT_ROW &= ~KB_ROW_WIRES; /* на всех линиях порта строк лог "0" */
NOP(); /* задержка на один такт, для установления сигналов на выводах порта */
code2 = (KB_PIN_COL & 0x70); /* считываем состояние линий столбцов и преобразуем в код */
return (code1 + code2); /* возвращаем полученные коды состояний столбцов и строк */
}
Вот такой вот неказистый код...