Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное_пособие.doc
Скачиваний:
70
Добавлен:
10.11.2019
Размер:
8.13 Mб
Скачать

5.9 Обработка клавиатуры

Во многих применениях микроконтроллер работает автономно по заданной программе. Однако в интерактивных системах осуществляется ввод значений некоторых параметров (пределов регулирования, граничных значений и др.) с контролем ввода, а также вывод значений параметров системы. В качестве устройств ввода-вывода применяются цифровые и символьно-знаковые клавиатуры.

Различают два типа клавиатур: кодирующую и некодирующую. В клавиатурах первого типа схемным путем на выходе формируется код, соответствующий нажатой клавише. Реализация кодирующей клавиатуры требует значительных аппаратных затрат. В микропроцессорных системах используются клавиатуры некодирующего матричного типа, которые представляют собой матрицу контактов, включенных на пересечении строк и колонок. Идентификация нажатой клавиши и формирование соответствующего ей двоичного кода выполняется программно. В составе клавиатуры могут быть цифровые и функциональные клавиши. Цифровые клавиши предназначены для ввода численных значений параметров, а функциональные - для вызова процедур. Обычно численные значения вводятся в десятичной и системе, поэтому клавиатура содержит клавиши с символами 0,1,2, ... ,9. Символика остальных клавиш отображает их функции, например '└−┘'- пробел, 'СТ' - старт, 't’- время и т.д. Очевидно, что любой функциональной клавише также как и цифровой соответствует двоичный код, определяемый её положением в матрице. На рисунке 66 представлена схема клавиатуры формата 4х4.

Выходы дешифратора 0,1,2,3 используются для сканирования, а разряды РА.4…РА.7 - для опроса матрицы клавиш. Разряды опроса микроконтроллера настраиваются на режим ввода. Обработчиком клавиатуры в разряды РС.0-РС.1 (РС.6 должен быть равен нулю) микроконтроллера загружаются последовательно двоичные коды сканирования, поступающие на входы дешифратора. Сигналы на выходах дешифратора имеют вид «бегущего» нуля. После выдачи каждого кода сканирования производится анализ состояния линий опроса (возврата) РА.4…РА.7.

Рисунок 66

Значение исходного кода, загружаемого в разряды РС0 и РС1 00, т.е. код сканирования на выходах дешифратора равен 0111. После этого производится последовательный опрос состояния разрядов РА.4 -РА.7. Если замкнуты контакты S1 (клавиша с символом «0» нажата ), то низкий уровень с нулевого выхода дешифратора через диод VD1 и замкнутый контакт поступает на линию опроса РА.4. Если замкнут контакт S2 , то нулевой уровень будет в разряде РА.5 и т.д. При разомкнутых контактах на все разряды РА.4-РА.7 подается высокий уровень, поступающий через резисторы R1-R4. Далее производится проверка состояния контактов клавиш второй строки матрицы выдачей в разряды МК РС.0 и РС1. кода 10, снова производится тестирование разрядов опроса (опрос состояния контактов клавиш S4-S8) и т.д.

После каждого тестирования производится инкрементирование программного счетчика SCANCODE, исходное состояние которого равно 0. Выход из процедуры сканирования происходит при наличии низкого уровня на линии опроса и содержимое счетчика SCANCODE является двоичным эквивалентом позиции клавиши.

При обнаружении уровня логического нуля (замкнуты контакты клавиши), производится ожидание отпускания клавиши, после чего код этой клавиши из счетчика SCANCODE помещается в младшую ячейку памяти дисплея со сдвигом влево имеющихся значений в ячейках.

Опрос состояния клавиш в строке производится циклическим сдвигом кода возврата и проверкой бита переноса С. Если бит С установлен, то клавиша не нажата и формируется код следующей клавиши добавлением единицы в счетчик SCANCODE. Если бит С сброшен, то клавиша нажата, а в счетчике SCANCODE уже имеется код этой клавиши.

Если в системе имеется клавиатура, то обязательно в ней должен быть и дисплей, предназначенный для контроля вводимых значений. Схемы клавиатуры и дисплея частично объединены: сигналы выбора разрядов дисплея и выбора строк матрицы клавиатуры объединены. Обработчики их также частично объединены. Принцип объединения процедур состоит в следующем. Нулевым уровнем с нулевого выхода дешифратора включается первый разряд динамического дисплея и в это время производится проверка состояния клавиш в первой строке матрицы клавиатуры. Если ни одна клавиша не нажаты, то по истечении времени свечения разряда, выдается значение для второго разряда дисплея и проверяется состояние клавиш второй строки и т.д. . В результате, за время полного цикла дисплея будет произведен опрос состояния всех клавиш.

В приведенной ниже программе команды обработки клавиатуры выделены большим шрифтом.

.include "m16def.inc"

.org 0

;***********Definition********************************

.equ Set_razr = 0b11000011

.def adr_cnt = r20

.def Num_segments = r22

Start:

ldi r16,low(RAMEND) ;установка указателя стека на

out SPL,r16 ;максимальный адрес SRAM ATmega16

ldi r16,high(RAMEND)

out SPH,r16

sbi PORTC,6 ;Выключение индикатора (см. схему)

ldi r16,Set_razr ;Линии 0,1,6,7 PORTC на вывод(см. схему)

out DDRC,r16 ;входы D и С регистра,входы дешифратора

Cikl: ldi adr_cnt,0 ; двоичный адрес разряда индикатора,и

;счетчик числа разрядов индикатора

ldi XH,$00 ;адрес первой ячейки области ОЗУ, в которой

;хранятся данные (ячейки $60-$63)

ldi XL,$60

LDI R19,0 ;Счетчик кода клавиши SCANCODE

Nxt_razr:

Ldi r31,High(Tab_code*2);загрузка старшей и младшей

ldi r30,Low(Tab_code*2) ;половин адреса начала таблицы

;кодов символов

ld r16,x+ ;загрузить в R16 первый байт данных из ячейки

;памяти, адрес которой находится в Х

add r30,r16 ;сложить содержимое регистров R30 и R16 для

;получения адреса ячейки таблицы

;перекодировки, в которой находится

;семисегментный код символа соответствующий ;содержимому отображаемой в данный момент ;ячейки дисплея

ldi r16,0

adc r31,r16;если адрес таблицы больше чем 255, то учтем

;перенос в регистр R31

lpm ;загрузить в R0 семисегментный код из таблицы ;перекодировки

ldi Num_segments, 8; Количество сегментов и

;одновременно счетчик загрузки

;семисегментного кода в регистр DD4

;****Процедура последовательной загрузки регистра DD2(см. схему)

Load_regist:MOV R16,R0 ;сохранить копию сегм. кода в R16

;будем загружать R16 в порт, (а на вход D регистра поступит через РС0

;только младший разряд кода из младшего разряда регистра R16). Перед

;выгрузкой R16 надо установить шестой разряд байта в R16(он через РС6

;микроконтроллера выключит индикатор, так как нулевой уровень

;сместится на один из неиспользуемых выходов дешифратора) и сбросить

;седьмой разряд в R16, чтобы на входе С регистра установился нуль.

SBR R16,$40 ;установить 1 на входе дешифратора для выкл.

;текущего разряда перед загрузкой регистра

;семисегментным кодом для след. разряда

CBR R16,$80 ;ноль на входе С регистра

out PORTC,r16 ;выключается индикатор и один разряд ;семисегментного кода через РС0 ;поступает на вход ;D регистра

sbi PORTC,Sinhr ;Запись разряда в регистр - посылаем ;синхроимпульс

cbi PORTC,Sinhr

roR r0 ;следующий разряд семисегментного кода ;в младшем разряде r0

dec Num_segments ;отсчет в сторону вычитания счетчика

;числа импульсов при последовательной

;записи семисегм. кода в регистр

brne Load_regist ;Пока не загрузятся все 8 разрядов

out portc,adr_cnt ;включить разряд индикатора

in r16, PINA ; Принимаем разряды опроса

swap r16 ; Размещение их в младших разрядах регистра

ldi r17, 4 ; Цикл для опроса состояния 4-х клавиш,

Rotat: ror r16

brcc Press ; Если клавиша нажата то Press

inc R19 ;код следующей клавиши

dec r17

brne Rotat ;Повторять опрос

rjmp Displ_ work

press: rcall Time_light;Ждать окончания дребезга при замык.

in r16, PINA

ori r16,$0f ; БУДЕТ ОПРОС ТОЛЬКО СТАРШИХ РАЗРЯДОВ

cpi r16, $ff

brne press ; Кнопка отжата? Если нет, то Press

rcall Time_light;Ждать окончания дребезга при размык.

lds r16,$62 ;

sts $63,r16 ;

lds r16,$61 ; Сдвиг содержимого дисплея влево

sts $62,r16 ;

lds r16,$60 ;

sts $61,r16 ;

sts $60,R19 ; код клавиши в первую ячейку дисплея

Displ_work:

rcall Time_light ;Задержка свечения разряда индикатора

inc adr_cnt ;Переход на следующее знач. счетчика

;циклов дисплея

cpi adr_cnt,4 ;Он - последний?

brne Nxt_razr ;След. разряд индикатора

rjmp Cikl

Time_light: ;*** Задержка 3,75 мс

ldi r16,2

m3: ldi r17,100

m2: ldi r18,100

m1: dec r18

brne m1

dec r17

brne m2

dec r16

brne m3

ret

Tab_code:

.Db 3,$9f,$25,$d,$99,$49,$41,$1f,1,9,$11,$c1,$63,$85,$61,$71

Если в системе имеются функциональные клавиши, то производится определение к какой группе принадлежит нажатая клавиша: к цифровым или функциональным. Если клавиша цифровая, то ее код помещается в младшую ячейку памяти дисплея, а если клавиша функциональная, то производится ее конкретное определение и вызывается процедура, соответствующая клавише.

Принцип идентификации клавиш заключается в вычитании из значения счетчика SCANCODE числа 10. Если клавиша функциональная, то при вычитании бит переноса не устанавливается. Для цифровой клавиши (ее код меньше 10) устанавливается бит переноса (заема). Для определения конкретного значения кода нажатой клавиши, производится последовательное сравнение значения счетчика SCANCODE со значениями 10,11,12,… . При равенстве счетчика SCANCODE какому-либо значению вызывается соответствующая клавише подпрограмма, иначе производится сравнение SCANCODE со следующим значением. После выполнения функциональных процедур управление необходимо передавать на текущий цикл дисплея (на метку Displ_work:).