DELAY_HIGH EQU 003H
DELAY_LOW EQU 018H
FLAG_0 EQU 031H
FLAG_1 EQU 032H
FLAG_2 EQU 033H
FLAG_3 EQU 034H
FLAG_4 EQU 035H
FLAG_5 EQU 036H
FLAG_6 EQU 037H
FLAG_7 EQU 038H
FLAG_INVALIDKEY EQU 039H
FLAG_PUSH EQU 040H
NEWKEY EQU 041H
ORG 000H
MOV SP,#050H
LJMP START
ORG 000BH
ACALL INTERRUPT_0
RETI
ORG 001BH
INTERRUPT_1:
PUSH ACC
PUSH PSW
CLR TR1
MOV PSW,#00H
ACALL KEYPRESSED; to check whether any key is pressed or not
JNZ CALCULATE; if key is pressed then jump to calculate to check is the key pressed is valid key or the previous key is kept pressed till now
JMP ALTER; If no key is pressed then clear the flag which check whether the previous key is kept pressed till now
CALCULATE:
ACALL KEYPRESSED; again check whether key is pressed or not
JZ ALTER; if no key is pressed then jump tp clear the flags and start the TIMER 1 again
ACALL CONVERT; if the key is pressed then check the key pressed is a valid key or not depending on the flag FLAG_INVALIDKEY
JBC FLAG_INVALIDKEY,ALTER; if this flag is set then the key is invalid and go to ALTER
ACALL TIMER_0; if the key pressed is valid then jump to TIMER 0 for the debounce delay
POP ACC
POP PSW
RETI
ALTER:
CLR FLAG_PUSH
; clear this flag indicating that the previous key is not being kept pressed and the key which is pressed is now released
AGAIN:
ACALL TIMER_1; call to timer 1 for again scanning the keys
POP PSW
POP ACC
RETI
INTERRUPT_0:
PUSH ACC
PUSH PSW
MOV PSW,#00H
CLR TR0
ACALL KEYPRESSED; chekh whhether the key is pressed or not again
JZ ALTER_1; if not pressed then jump to ALTER 1 for clearing the flags and call to TIMER 1 agan for scanning the key's
ACALL CONVERT ; if key is pressed check it is valid or not
JBC FLAG_INVALIDKEY,ALTER_1; invalid key indication if this flag is set
JB FLAG_PUSH,COMPARE ; if this flag is found set then it means that the key found to be pressed is the same key previously kept pressed
SETB FLAG_PUSH; if FLAG_PUSH is not found to be set then it means that the valid key is a new key
MOV NEWKEY,A; move this newkey value to the flag NEWKEY
JMP HOME; jump to home
COMPARE:
CJNE A,NEWKEY,CLEAR; if the FLAG_PUSH is found to be set then control comes to this statement for checking whether the key kept pressed for a long time is the previous one or not
JMP AGAIN_1; if it is the same key kept pressed then do nothing and again call to TIMER 1 so that scanning of keys can be done again but dont clear the FLAG_PUSH flag this time because the key kept pressed has not indicated to be released till now
HOME:
JB ACC.0,COOL_0; if these bits are ON then it means
JB ACC.1,COOL_1; which key is pressed at this moment
JB ACC.2,COOL_2; and accordingly jump to that
JB ACC.3,COOL_3; subroutine
JB ACC.4,COOL_4
JB ACC.5,COOL_5
JB ACC.6,COOL_6
JB ACC.7,COOL_7
CLEAR:
CLR FLAG_PUSH; If the key being kept pressed is not the same previous key then it means that the previous key kept pressed has been released and this is the new key which is pressed and it is valid ... so jump to HOME
JMP HOME
WORLD:
MOV R0,A; if the key is pressed second time then
MOV A,P2; make the corresponding LED OFF while all
ORL A,R0; other LED's are not been effected at all
XRL A,R0
MOV P2,A
JMP STATUS; jump to status to CLEAR the flag which indicated the key is being pressed for the 1st time or 2nd time
UNIVERSE:
ORL A,P2; If the control comes here then it means that the key being pressed is pressed for the first time and so the corresponding LED is maked ON
MOV P2,A
JMP AGAIN_1
ALTER_1:
CLR FLAG_PUSH
AGAIN_1:
ACALL TIMER_1
POP PSW
POP ACC
RET
COOL_0:
JB FLAG_0,WORLD; if this flag is found to be set then it means the key is being pressed previously and so jump to WORLD for making OFF LED that is corresponding to this key
SETB FLAG_0; set this flag coz the key is pressed fot the 1st time
JMP UNIVERSE; jump to universe to make the corrersponding LED ON
COOL_1:
JB FLAG_1,WORLD
SETB FLAG_1
JMP UNIVERSE
COOL_2:
JB FLAG_2,WORLD
SETB FLAG_2
JMP UNIVERSE
COOL_3:
JB FLAG_3,WORLD
SETB FLAG_3
JMP UNIVERSE
COOL_4:
JB FLAG_4,WORLD
SETB FLAG_4
JMP UNIVERSE
COOL_5:
JB FLAG_5,WORLD
SETB FLAG_5
JMP UNIVERSE
COOL_6:
JB FLAG_6,WORLD
SETB FLAG_6
JMP UNIVERSE
COOL_7:
JB FLAG_7,WORLD
SETB FLAG_7
JMP UNIVERSE
STATUS:
JBC FLAG_0,AGAIN_1; flag is cleared to make it fresh key
JBC FLAG_1,AGAIN_1
JBC FLAG_2,AGAIN_1
JBC FLAG_3,AGAIN_1
JBC FLAG_4,AGAIN_1
JBC FLAG_5,AGAIN_1
JBC FLAG_6,AGAIN_1
JBC FLAG_7,AGAIN_1
KEYPRESSED:
MOV A,P1; as the PORT 1 is made as an input PORT so all the bits are high ... the key pressed bit will be low so the value is transfered to ACCUMULATOR for further processing
CPL A; the value in ACC is complimented coz all the bits in PORT 1 are high as it is an input port
RET
START:
MOV IE,#08AH
MOV TMOD,#011H
MOV P1,#0FFH; make PORT 1 as an input port
MOV P2,#00H
MOV R0,#00H
MOV R7,#00H
CLR FLAG_0
CLR FLAG_1
CLR FLAG_2
CLR FLAG_3
CLR FLAG_4
CLR FLAG_5
CLR FLAG_6
CLR FLAG_7
ACALL TIMER_1
KEY:
MOV A,P1
CPL A
JMP KEY
TIMER_0:
MOV TL0,#DELAY_LOW
MOV TH0,#DELAY_HIGH
SETB TR0
RET
TIMER_1:
MOV TL1,#0E0H
MOV TH1,#0B1H
SETB TR1
RET
CONVERT:
CLR FLAG_INVALIDKEY; this subrountine check the validity of the key that is pressed ... and indicates it by the flag FLAG_INALIDKEY
CJNE A,#01H,SECOND
RET
SECOND:
CJNE A,#02H,THIRD
RET
THIRD:
CJNE A,#04H,FOURTH
RET
FOURTH:
CJNE A,#08H,FIVE
RET
FIVE:
CJNE A,#010H,SIX
RET
SIX:
CJNE A,#020H,SEVEN
RET
SEVEN:
CJNE A,#040H,EIGHT
RET
EIGHT:
CJNE A,#080H,BAD
RET
BAD:
SETB FLAG_INVALIDKEY
RET
;**************************************************************************************************
END