Статья №5
В этой статье мне бы хотелось познакомить читателей с подключением к микроконтроллерам клавиатуры. Дело в том, что обычно большинству схем на микроконтроллерах для ввода данных требуется одна или несколько кнопок. Но, когда проекты становятся сложнее, может возникнуть потребность в применении небольшой клавиатуры. Встречаются варианты клавиатур 3х4 или 4х4, и почти всегда клавиши в них соединены по схеме матрицы. Применение матрицы необходимо из –за того, что для её подключения нужно минимальное число линий ввода – вывода. Например, для клавиатуры 4х4 необходимо, состоящей из 16 кнопок необходимо 16 линий ввода, поэтому рациональнее организовать её в виде матрицы, т.е. расположить 4 кнопки в 4 строки, использовав 8 линий ввода – вывода (один порт микроконтроллера). Самое распространённое решение подключения матрицы на один порт – это подключить строки к старшим разрядам, а столбцы к младшим. Однако, здесь возникает проблема – считывание состояния клавиатуры происходит при возникновении прерывания, но в микроконтроллере ATtiny2313 мы можем использовать два внешних прерывания (остальные выводы заняты). Эта проблема решается подключением четырёх диодов, образующих с подтягивающим резистором на входе INT0 элемент «ИЛИ».
Схема подключения клавиатуры 4х4 матричного типа к микроконтроллеру приведена на Рис.1. Она имеет разъём DB-9F, преобразователь уровней MAX3232, которые необходимы для взаимодействия UART микроконтроллера с RS-232, и работа которых была описана в предыдущей статье. Резисторы R3 – R6 защищают микроконтроллер от короткого замыкания питания на землю. На входе INT0 имеется подтягивающий резистор R7 . Четыре диода VD1 – VD4 подключены к линиям ввода- вывода клавиатуры (катодами) и к выводу INT0 (анодами). Теперь при нажатии любой кнопки, если на столбцы подать нули, на входе INT0 появится низкий уровень.
Как показано на Рис.1 клавиатура подключена к порту В микроконтроллера. Её схема представлена на Рис.2.
Предположим, что весь порт В настроен на вход, и все входа имеют подтяжку:
DDRB = &B00000000
PORTB = &B11111111
Пусть кнопки (Рис.2) каким –то образом соединены ещё и «землёй» (GND), тогда при нажатии, например, кнопки «1» на контактах порта В РВ3 и РВ4 будет низкий уровень, т.е. порт примет значение PORTB = &B11100111, которое и является кодом кнопки «1». Аналогично и в отношении остальных кнопок (код кнопки «В» - 01111011, «5» - 11011011 и т.д.). Но, поскольку кнопки не соединены с GND, необходимо ввести раздельное определение строк и столбцов с последующим суммированием и идентификацией результата с названием кнопки.
Сделаем строки РВ0 – РВ3 входами и включим их подтяжку, а столбцы РВ3 – РВ7 – выходами:
DDRB = &B11110000
PORTB = &B00001111
При нажатии кнопки определённая строка будет иметь низкий уровень. Например, при нажатии кнопки «1» порт В примет значение 00000111, которое является кодом строки. Одновременно с этим включится прерывание, при обработке которого необходимо считать данный код в переменную Stro:
Stro = PORTB
Инвертируем настройки порта – сделаем столбцы РВ3 – РВ7 входами и включим их подтяжку, а строки РВ0 – РВ3 – выходами:
DDRB = &B00001111
PORTB = &B11110000
Теперь при нажатой кнопке «1» порт будет иметь значение 11100000, которое является кодом столбца. Считаем этот код в переменную Col:
Col = PORTB
Сумма переменных Stro и Col даст нам код кнопки:
Code = Stro + Col ‘ 11100111 – код кнопки «1»
Далее необходимо создать два блока данных:
В первом располагаются коды кнопок клавиатуры (метка – Codbytes). Во втором блоке (метка – Keycodes) находятся названия кнопок, которые должны располагаться в соответствии с кодами кнопок первого блока (в том же порядке).
Полученный код (Сode) в цикле сравнивается с кодами кнопок первого блока данных и при их равенстве определяется индекс кода и, следовательно , индекс названия кнопки: I1 = I +1
Название нажатой кнопки определяется с помощью функции Lookup:
Keycode = Lookupstr (Index1, Keycodes)
Вывод в терминал названия нажатой кнопки происходит с помощью уже описанной прцедуры:
Print “Keycode=”; Keycode
Далее, после выхода из цикла, осуществляется начальная установка состояния порта В и выход из подпрограммы.
Блок – схема программ приведены на Рис.4. и Рис.5.
Текст программы приводится ниже.
$regfile = "attiny2313a.dat" 'настройки$crystal = 4000000$hwstack = 40$swstack = 16$framesize = 32$sim
Config Debounce = 75 'задержка входного сигналаConfig Pind.6 = Output 'конфигурирование выводовConfig Pind.2 = InputConfig Pind.3 = Output
Config Int0 = Falling 'внешнее прерывание по спаду импульса
Dim Wtime As Byte 'объявление переменныхDim Stro As ByteDim Col As ByteDim Code As ByteDim Codbyte(16) As ByteDim Keycode As String * 4Dim Index As IntegerDim Index1 As Integer
On Int0 Button 'подпрограмма прерывания
Ddrb = &B11110000 'PB0...PB3 -входы,остальные - выходыPortb = &B00001111 'подтяжка PB0...PB3Wtime = 100 'величина задержки
Print "ready..." 'вывод слова на RS-232
Enable Interrupts 'разрешение прерыванийEnable Int0
DoSet Portd.6 'включение светодиодаWaitms Wtime 'задержкаReset Portd.6 'выключение светодиодаWaitms WtimeLoop
Button: 'подпрограмма обработки прерыванияWaitms WtimeStro = Portb 'считывание значий строк (младшие биты порта В)Ddrb = &B00001111 'инвертирование значений полубайтов порта ВPortb = &B11110000Col = Portb 'считывание значений столбцов (старшие биты порта В)Code = Stro + Col 'определение кода нажатой кнопкиRestore CodbytesFor Index = 1 To 16Index1 = Index - 1Read Codbyte(index) 'считывание кодов кнопок из блока данныхIf Code = Codbyte(index) Then 'сравнение полученного кода с кодами блока данныхPrint "Codbyte:" ; Codbyte(index) 'передача в терминал кода нажатой кнопкиKeycode = Lookupstr(index1 , Keycodes) 'определение названия нажатой кнопкиPrint "Keycod=" ; Keycode 'передача в терминал названия нажатой кнопкиEnd IfNext IndexDdrb = &B11110000 'установка начальнго состояния портаВPortb = &B00001111
Return 'возврат из подпрограммы прерывания
End 'end program
Codbytes:Data &B11100111 , &B11010111 , &B10110111 , &B01110111 , &B11101011 , &B11011011 , &B10111011 , &B01111011 , &B11101101 , &B11011101 , &B10111101 , &B01111101 , &B01111110 , &B11101110 , &B11011110 , &B10111110 , &B01111110Keycodes:Data "1" , "2" , "3" , "A" , "4" , "5" , "6" , "B" , "7" , "8" , "9" , "C" , "*" , "0" , "#" , "D"
Результаты симуляции программы приведены на Рис.6. Более подробно о процессе симуляции будет рассказано в следующей статье.
Сама программа находится в приложении 1 настоящей статьи.