Одновременное подключение кловиатуры и цифрового индикатора к одному порту
4х2.2кпП9
0- jO 0*1-0 of Ю с>-
Qrio [51 (jF
Oj-O Dif-O OtrO о*
о- j-O о -0 Oj-0 о
1°
определить номер нажатой клавхшги. Описанный алгоритм реализует программа, приведенная в листинге 3.9. При включении устройствана его индикаторе отображаются четыре нуля. Затем в правой позиции индикатора будет отображаться номер последней нажатой клавиши в ше-стнадцатеричном представлении. При каждом новом нажатии клавиши индикация будет сдвигаться влево на один разряд.
Листинг З.у
Эта программа показывает, как посредством одних и тех же портов можно управлять 4-разрядным семисегментным светодиодным индикатором и матричной клавиатурой на 16 клавиш.
Главная программа сначала отображает 0000,а затем номер очередной нажатой клавиши в шестнадцатеричном коде в правой позиции индикатора, с автоматическим смещением номеров предыдущих клавиш в левую сторону индикатора, [индикация обновляется каждые 20 мс, клавиатура сканируется в том же темпе, уаймер использован для генерации прерываний через каждые 5 мс.
Программа соответствует инструкции по применению AN557 фирмы Microchip.
LIST Р=16С71, F=INHX8M include picreg-equ
TefflpC
OxOc
Временные регистры общего применения.
Tempo
OxOd
TenpE
OxOe
PABuf
0x20
PBBuf
0x21
Count
OxOf
Счетчик.
MsdTime
0x10
Старший байт.
LsdTime
0x11
Младший байт.
KeyFlag
0x12
Флаг клавиатуры.
keyhit
Бит 0 - значит, клавиша нажата.
OebnceOn
noentry
Нет клавиши = 0.
ServKey
Бит 3 - значит, обработка клавиши.
Debnce
0x13
NewKey
0x14
WBuffer
0x2f
StatBuffer
0x2e
OptionReg
; Накрооперация сохранения байта состояния и содержимого рабочего регистра
push
macro
movwf swapf swapf movwf endm
WBuffer WBuffer STATUS, w StatBuffer
Макрооперация считывания байта состояния и содержимого рабочего регистра из буфера. macro
swapf StatBuffer,w
movwf STATUS
swapf WBuffer, w
endm
org О goto Start org 4
; Старт.
clrf PORTJ bsf P0RT A,3 return
Обнуление порта В. Установка бита 3 порта А. Возврат.
Сохраняем рабочий регистр и регистр состояния в момент прерывания. Push
с предварительным делителем на 32 осуществляет инкрементацию RTCC ка)кдье 31,25 мсек.
Нойуль счета таймера - 96, поэтому прерывание будет происходить каадые 5 мс. InitTimers
ServiceKey
InitPorts
call
InitPorts
call
InitTimers
btfsc
KeyFlag,ServKey
; Проверка флага нажатия.
call
ServiceKey
Да, тогда обработка.
goto
loop
ia обработки нажатия клавиши. Msd - старшая цифра, Lsd - младшая цифра,
movf
NewKey.w ;
Считывание регистра NewKey.
movwf
TempE ;
Сохранение в TempE.
swapf
MsdTime,w ;
Считывание Msd и перестановка полубайтов,
andlw
B11110000- ;
Обнуление младшего полубайта.
movwf
MsdTime ;
Сохранение.
swapf
LsdTime,w ;
Считывание Lsd и перестановка полубайтов.
andlw
BOOOOIIir ;
Обнуление старшего полубайта.
iorwf
MsdTime ;
Логическое сложение с Msd.
swapf
LsdTime,w ;
Считывание Lsd и перестановка полубайтов.
andlw
B-11110000-
Обнуление младшего полубайта.
iorwf
TempE, w ;
Логическое сложение с TempE.
movwf
LsdTime ;
Сохранение.
KeyFlag,ServKey
; Сброс флага нажатия.
return
Возврат.
STATUS, RPO ;
Банк 1.
movlw
3 ;
RAO - RA3 - цифровые порты.
movwf
A0C0N1
clrf
TRISA ;
RAO - RA4 - выходы.
clrf
TRISB ;
ПВО - RB7 - выходы.
STATUS.RPO ;
Банк 0.
clrf
PORT A
Обнуление порта А.
clrf
MsdTime
; Сброс MsdTime
clrf
LsdTime
; и LsdTime.
clrf
KeyFlag
; Сброс флагов.
STATUS,RPO
; Банк 1.
movlw
В10000100-
; Предварительное деление на 32.
movwf
OptionReg
STATUS, RPO
; Банк 0.
movlw
B-00100000-
; Разрешение прерывания таймера.
movwf
INTCON
movlw
; Предзагрузка таймера.
movwf
RTCC
; Начало счета.
retfie
; Выход из прерывания.
Servicelnterrupts btfsc goto clrf bsf
return
ServiceRTCC
INTCON, RTIF ServiceRTCC INTCON INTCON,RTIE
Прерывание таймера?
Да, обработка.
Нет. сброс INTCON.
Разрешение прерывания от таймера.
movlw
Инициализация таймера.
movwf
RTCC
INTCON,RTIF
Сброс флага прерываний таймера.
btfsc
PORT A,0
Если бит 0 порта А равен единице.
call
ScanKeys
быстрое сканирование клавиатуры.
call
UpdateDisplay
Обновление индикации.
return
Сканируем клавиатуру 4x4 и выдаем номер клавиши в NewKey, если клавиша была нажата. Если нет. обнуляем указатель keyhit. Подпрограмма устраняет дребезг контактов . Клавиатура сканируется каждые 20 мс.
ScanKeys
Coll
Col2 Col3
Col4
btfss
KeyFlag,DebnceOn
Задержка окончена?
(RB3)
(RB2) (RB1)
(RBO)
goto
Scani
Нет, тогда сканирование
decfsz
клавиатуры.
Ran1(RB4)
1 2
Debnce
Да, тогда уменьшаем счетчик
задержки.
Ran2(RB5)
5 6
return
Возвращаемся, если не 0.
KeyFlag,DebnceOn
Сброс флага
Ran3(RB6)
9 A
return
и возврат.
Scani
Ran4(RB7)
D E
call
SavePorts
Сохранение портов.
ITOVlW
B111011ir
Загрузка ТетрО.
3etKeyValue
movwf
TempD
clrf
TempC
ScanNext
movf
P0RT B,w
btfss
goto
TempD,3 RowValEnd
; Первый столбец.
INTCON,RBIF
Сброс флага прерывания от порта В.
incf btfss
TempC TempD.2
; Второй столбец.
TempD
Правый сдвиг TempD.
goto
RowValEnd
btfss
STATUS,С
Перенос = 1?
incf
TempC
goto
NoKey
Нет, тогда окончание
btfss
TempD.1
; Третий столбец.
movf
TempD, w
ИЛИ TempD и w
goto
RowValEnd
movwf
PORTJ
и выдача в PORTJ.
incf
TempC
; Последний столбец.
RoWValEnd
btfss
INTCON,RBIF
Значение флага прерывания от порта В равно 1?
btfss
TempE,0
; Первая строка?
goto
ScanNext
Нет, тогда продолжаем.
goto
GetValCom
; Да, считывание клавишей 0,1,2,3.
btfsc
KeyFlag,keyhit
Последняя клавиша отпущена?
btfss
TempE, 1
; Вторая строка?
goto
SKreturn
Нет, тогда выход.
goto
Get4567
; Да, считывание 4,5,6,7.
KeyFlag,keyhit
Устанавливаем флаг нажатия
btfss
TempE, 2
; Третья строка?
новой клавиши.
goto
Get89ab
; Да, считывание 8.9.а.Ь.
swapf
PORTJ, w
Считывание порта В.
Getcdef
movwf
TempE
Сохранение в TempE.
TempC,2
call
GetKeyValue
Считывание значения клавиши от 0 до F.
Get89ab
TempC,3
movwf
N3wKey
Сохранение в NewKey.
goto
GetValCom
KeyFlag, ServKey
Установка флага обработки клавиш.
6et4567
KeyFlag,DebnceOn
TempC,2
movlw
GetValCom
movwf
Debnce
Изменение времени задержки.
movf
TempC, w
; Таблица номеров клавиш.
SKreturn
addwf
call
RestorePorts
Возмещение портов.
retlw retlw
return
NoKey
retlw
KeyFlag,keyhit
Сброс флага.
retlw
goto
Skretum
retlw retlw
; Соответствие номеров клавиш, строк, столбцов и портов.