Автор: WildCat
Подключаем клавиатуру к МК
Большинству небольших приложений на микроконтроллерах требуется одна или несколько кнопок для осуществления ввода данных пользователем. Но когда ваши проекты становятся более сложными, им может потребоваться небольшая клавиатура. Обычно можно приобрести готовую клавиатуру, встречаются варианты 3x4 или 4x4 клавиши, и почти всегда клавиши в ней соединены по схеме матрицы:
Матрица применяется потому, что для её подключения необходимо минимальное число линий ввода-вывода. Например, для клавиатуры 4x4 из 16 выключателей нужно 16 линий ввода. Гораздо более разумным решением было бы организовать их в 4 строки по 4 выключателя, использовав тем самым всего 8 линий (один порт контроллера!)
Но как использовать такую клавиатуру? Существует много решений. Самое распространённое - подключить матрицу на один порт, подключив строки к старшим разрядам, а столбцы - к младшим. Но мы столкнёмся с небольшой проблемой - при нажатии любой клавиши должно возникать прерывание, и контроллер должен считывать состояние клавиатуры. PIC контроллер вполне справится с такой задачей, но наш AT90S2313 имеет на борту всего два внешних прерывания. Проблему можно устранить, добавив 4 диода и подтягивающие резисторы, чтоб сделать элемент "ИЛИ" на входе Int0:
470-омные резисторы защитят контроллер от короткого замыкания питания на землю. Это возможно в теории, но вы можете сделать макет и без них.
На входе Int0 висит подтягивающий резистор 10 кОм к плюсу питания. Мы назначим четыре старших бита в PortB на выход, установив на них низкий уровень. Младшие 4 бита будут работать как входы, на них сделаем высокий уровень. Теперь, если нажать клавишу, возникнет соединение между каким-либо столбцом и строкой. Теперь на линии строки появится низкий уровень. Также низкий уровень появится и на строке с диодами, сработает элемент "ИЛИ" и на входе Int0 также появится низкий уровень и вызовет прерывание.
В подпрограмме обработки прерывания мы опрашиваем состояние строк, чтобы узнать, на какой из них нажата клавиша. Теперь мы переназначаем старшие биты на вход, а младшие на выход и точно таким же образом определяем, на каком столбце нажата клавиша. После этого выжидаем время "антидребезга". Зная теперь строку и столбец, несложно догадаться, что клавиша нажата на их пересечении. Делаем необходимые выводы, устанавливаем нужные параметры, и возвращаем состояние пинов порта к начальным значениям.
Конечно, указанное расположение строк и столбцов сугубо условно, вы сами можете разместить их так, чтобы сократить число линий и упростить управление.
Приведем пример программы для работы с клавиатурой:
keyboard-int.bas
$regfile = "2313def.dat" $crystal = 4000000 $baud = 9600 Const Debouncetime = 150 Config Pind.6 = Output Config Pind.2 = Input Config Int0 = Falling Dim Wtime As Byte Dim Keycoderow As Byte Dim Keycodecol As Byte Dim Keycode As Byte Dim Keychar As String * 1 On Int0 Button 'старшая половина порта на выход, младшая - на вход Ddrb = &B11110000 Portb = &B00001111 Wtime = 255 Print "ready..." Enable Interrupts Enable Int0 Do Set Portd.6 Waitms Wtime Reset Portd.6 Waitms Wtime Loop Button: Waitms Debouncetime 'опросим ноги порта B и определим, на которой низкий уровень Keycoderow = Pinb 'поменяем назначение входов/выходов половин порта Ddrb = &B00001111 Portb = &B11110000 'выждем антидребезг Waitms 1 'определим, на каком столбце низкий уровень Keycodecol = Pinb 'вернем состояние порта к первоначальному Ddrb = &B11110000 Portb = &B00001111 'получим код клавиши исходя из полученных значений Select Case Keycoderow Case 7 : Keycode = 0 Case 11 : Keycode = 4 Case 13 : Keycode = 8 Case 14 : Keycode = 12 Case Else : Keycode = 99 End Select Shift Keycodecol , Right , 4 Select Case Keycodecol Case 7 : Keycode = Keycode + 0 Case 11 : Keycode = Keycode + 1 Case 13 : Keycode = Keycode + 2 Case 14 : Keycode = Keycode + 3 Case Else : Keycode = Keycode + 99 End Select 'неверный код клавиши из-за дребезга... If Keycode > 15 Then Keycode = 16 Print Keycoderow ; " " ; Keycodecol ; " " ; Keycode Keychar = Lookupstr(keycode , Keycodes) Print Keychar Gifr = 64 Return End Keycodes: Data "1" , "2" , "3" , "A" , "4" , "5" , "6" , "B" , Data "7" , "8" , "9" , "C" , "R" , "0" , "E" , "D" , "?"Преобразование кода клавиши в соответствующий символ находится в блоке данных Keycodes. Если в вашей клавиатуре иное расположение клавиш, достаточно изменить блок данных.
Программа отсылает полученный с клавиатуры символ в терминал ПК через интерфейс RS-232. Так как все линии порта B заняты клавиатурой, нам пришлось отключить ЖКИ.
Обратите внимание: в Bascom есть команда Getkbd, которая умеет самостоятельно опрашивать клавиатуры 3x4 или 4x4. Но она не работает внутри подпрограммы прерывания, её можно выполнять только внутри основного цикла.