Изначально P1 = 11111111b.
Каждая клавиша кодируется двумя битами в P1 - один как бы обозначает ряд, другой - столбец. При нажатии кнопки соответствующие 2 бита сбрасываются в 0.
В этом случае определение нажатой кнопки - циклический перебор состояний P1.
Но появляются какие-то проблемы.
Стоит задача: при нажатии клавиши вывести сначала знак "*", потом - знак "#" каждую секунду, пока нажата клавиша, затем, когда клавиша отпущена - цифру, соответствующую клавише. Реализовать это надо с использованием прерываний.
Вот исходник:
Код
ORG 8000H
LJMP MAIN
ORG 8033H
LJMP P1HANDLE
ORG 803BH
LJMP P1HANDLE
ORG 8043H
LJMP P1HANDLE
ORG 804BH
LJMP P1HANDLE
MAIN:
TM2IR EQU 0C8h
CTCON EQU 0EBh
S0BUF EQU 099h
IEN1 EQU 0E8h
IEN0 EQU 0A8h
IP1 EQU 0F8h
TM2CON EQU 0EAh
MOV A, #00000000B
MOV R1, #11111111B
MOV R2, #11111111B
MOV R3, #00000000B
MOV P1, #00001111B
MOV TM2IR, #00000000B
MOV TM2CON, #00000011B
MOV CTCON, #10101010B
MOV IP1, #00000000B
MOV IEN1, #00001111B
MOV IEN0, #10000000B
SETB IE.7
LOOP:
NOP
JMP LOOP
P1HANDLE:
MOV R4, P1
MOV TM2IR, #00000000B
CLR TI
MOV S0BUF, #00101010B
JNB TI, $
CLR TI
CLR TI
MOV S0BUF, R4
JNB TI, $
CLR TI
CALL WAIT
CALL WAIT
PRINT23H:
CLR TI
MOV S0BUF, #00100011B
JNB TI, $
CLR TI
CALL WAIT
MOV A, P1
CJNE A, #00001111B, PRINT23H
<Определение нажатой клавиши и вывод соответствующего символа>
RETURN:
MOV A, #00000000B
MOV R1, #11111111B
MOV R2, #11111111B
MOV R3, #00000000B
MOV P1, #00001111B
MOV TM2IR, #00000000B
MOV TM2CON, #00000011B
MOV CTCON, #10101010B
MOV IP1, #00000000B
MOV IEN1, #00001111B
MOV IEN0, #10000000B
SETB IE.7
A1:
RETI
WAIT:
OUTER_CYCLE:
INNER_CYCLE:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R2, INNER_CYCLE
DJNZ R1, OUTER_CYCLE
RET
DELAY:
JNB TI, WAIT
RET
END
LJMP MAIN
ORG 8033H
LJMP P1HANDLE
ORG 803BH
LJMP P1HANDLE
ORG 8043H
LJMP P1HANDLE
ORG 804BH
LJMP P1HANDLE
MAIN:
TM2IR EQU 0C8h
CTCON EQU 0EBh
S0BUF EQU 099h
IEN1 EQU 0E8h
IEN0 EQU 0A8h
IP1 EQU 0F8h
TM2CON EQU 0EAh
MOV A, #00000000B
MOV R1, #11111111B
MOV R2, #11111111B
MOV R3, #00000000B
MOV P1, #00001111B
MOV TM2IR, #00000000B
MOV TM2CON, #00000011B
MOV CTCON, #10101010B
MOV IP1, #00000000B
MOV IEN1, #00001111B
MOV IEN0, #10000000B
SETB IE.7
LOOP:
NOP
JMP LOOP
P1HANDLE:
MOV R4, P1
MOV TM2IR, #00000000B
CLR TI
MOV S0BUF, #00101010B
JNB TI, $
CLR TI
CLR TI
MOV S0BUF, R4
JNB TI, $
CLR TI
CALL WAIT
CALL WAIT
PRINT23H:
CLR TI
MOV S0BUF, #00100011B
JNB TI, $
CLR TI
CALL WAIT
MOV A, P1
CJNE A, #00001111B, PRINT23H
<Определение нажатой клавиши и вывод соответствующего символа>
RETURN:
MOV A, #00000000B
MOV R1, #11111111B
MOV R2, #11111111B
MOV R3, #00000000B
MOV P1, #00001111B
MOV TM2IR, #00000000B
MOV TM2CON, #00000011B
MOV CTCON, #10101010B
MOV IP1, #00000000B
MOV IEN1, #00001111B
MOV IEN0, #10000000B
SETB IE.7
A1:
RETI
WAIT:
OUTER_CYCLE:
INNER_CYCLE:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R2, INNER_CYCLE
DJNZ R1, OUTER_CYCLE
RET
DELAY:
JNB TI, WAIT
RET
END
Это - гарантированно рабочий код, возможно не оптимальный. Определение клавиши сделано так, но это не работает:
Код
GET_NUMBER:
MOV P1, #11011111B
MOV A, P1
CJNE A, #11011111B, RECOGN0
MOV P1, #11101111B
MOV A, P1
CJNE A, #11101111B, RECOGN0
MOV P1, #01111111B
MOV A, P1
CJNE A, #01111111B, RECOGN0
MOV P1, #10111111B
MOV A, P1
CJNE A, #10111111B, RECOGN0
JMP GET_NUMBER
RECOGN0:
MOV A, #11010000B
ORL A, R4
CJNE A, #11011101B, RECOGN1
MOV R3, #00110001B
LJMP OUTPUT
RECOGN1:
CJNE A, #11011110B, RECOGN2
MOV R3, #00110010B
LJMP OUTPUT
RECOGN2:
CJNE A, #11010111B, RECOGN3
MOV R3, #00110011B
LJMP OUTPUT
RECOGN3:
CJNE A, #11011011B, RECOGN4
MOV R3, #00110100B
LJMP OUTPUT
RECOGN4:
MOV A, #11100000B
ORL A, R4
CJNE A, #11101101B, RECOGN5
MOV R3, #00110101B
LJMP OUTPUT
RECOGN5:
CJNE A, #11101110B, RECOGN6
MOV R3, #00110110B
LJMP OUTPUT
RECOGN6:
CJNE A, #11100111B, RECOGN7
MOV R3, #00110111B
LJMP OUTPUT
RECOGN7:
CJNE A, #11101011B, RECOGN8
MOV R3, #00111000B
LJMP OUTPUT
RECOGN8:
MOV A, #01110000B
ORL A, R4
CJNE A, #01111101B, RECOGN9
MOV R3, #00111001B
LJMP OUTPUT
RECOGN9:
CJNE A, #01111110B, RECOGN10
MOV R3, #00110000B
LJMP OUTPUT
RECOGN10:
CJNE A, #01110111B, RECOGN11
MOV R3, #01000001B
LJMP OUTPUT
RECOGN11:
CJNE A, #01111011B, RECOGN12
MOV R3, #01000010B
LJMP OUTPUT
RECOGN12:
MOV A, #10110000B
ORL A, R4
CJNE A, #10111101B, RECOGN13
MOV R3, #01000011B
LJMP OUTPUT
RECOGN13:
CJNE A, #10111110B, RECOGN14
MOV R3, #01000100B
LJMP OUTPUT
RECOGN14:
CJNE A, #10110111B, RECOGN15
MOV R3, #01000101B
LJMP OUTPUT
RECOGN15:
CJNE A, #10111011B, NOT_RECOGN
MOV R3, #01000110B
LJMP OUTPUT
NOT_RECOGN:
CJNE A, #10111011B, RETURN
OUTPUT:
CLR TI
MOV S0BUF, R3
JNB TI, $
CLR TI
MOV P1, #11011111B
MOV A, P1
CJNE A, #11011111B, RECOGN0
MOV P1, #11101111B
MOV A, P1
CJNE A, #11101111B, RECOGN0
MOV P1, #01111111B
MOV A, P1
CJNE A, #01111111B, RECOGN0
MOV P1, #10111111B
MOV A, P1
CJNE A, #10111111B, RECOGN0
JMP GET_NUMBER
RECOGN0:
MOV A, #11010000B
ORL A, R4
CJNE A, #11011101B, RECOGN1
MOV R3, #00110001B
LJMP OUTPUT
RECOGN1:
CJNE A, #11011110B, RECOGN2
MOV R3, #00110010B
LJMP OUTPUT
RECOGN2:
CJNE A, #11010111B, RECOGN3
MOV R3, #00110011B
LJMP OUTPUT
RECOGN3:
CJNE A, #11011011B, RECOGN4
MOV R3, #00110100B
LJMP OUTPUT
RECOGN4:
MOV A, #11100000B
ORL A, R4
CJNE A, #11101101B, RECOGN5
MOV R3, #00110101B
LJMP OUTPUT
RECOGN5:
CJNE A, #11101110B, RECOGN6
MOV R3, #00110110B
LJMP OUTPUT
RECOGN6:
CJNE A, #11100111B, RECOGN7
MOV R3, #00110111B
LJMP OUTPUT
RECOGN7:
CJNE A, #11101011B, RECOGN8
MOV R3, #00111000B
LJMP OUTPUT
RECOGN8:
MOV A, #01110000B
ORL A, R4
CJNE A, #01111101B, RECOGN9
MOV R3, #00111001B
LJMP OUTPUT
RECOGN9:
CJNE A, #01111110B, RECOGN10
MOV R3, #00110000B
LJMP OUTPUT
RECOGN10:
CJNE A, #01110111B, RECOGN11
MOV R3, #01000001B
LJMP OUTPUT
RECOGN11:
CJNE A, #01111011B, RECOGN12
MOV R3, #01000010B
LJMP OUTPUT
RECOGN12:
MOV A, #10110000B
ORL A, R4
CJNE A, #10111101B, RECOGN13
MOV R3, #01000011B
LJMP OUTPUT
RECOGN13:
CJNE A, #10111110B, RECOGN14
MOV R3, #01000100B
LJMP OUTPUT
RECOGN14:
CJNE A, #10110111B, RECOGN15
MOV R3, #01000101B
LJMP OUTPUT
RECOGN15:
CJNE A, #10111011B, NOT_RECOGN
MOV R3, #01000110B
LJMP OUTPUT
NOT_RECOGN:
CJNE A, #10111011B, RETURN
OUTPUT:
CLR TI
MOV S0BUF, R3
JNB TI, $
CLR TI
Этот код почему-то определяет только верхние 4 кнопки, выводя цифры 1-4, если нажимать остальные - то выводит тоже 1-4.