;********************************************************* ; THIS PROGRAM SCANS THE KEYPAD AND RETURNS WITH ; THE KEY PRESS IN THE 'KEY_PRESSED' REGISTER FOR PORTABILITY! ; RUN SCAN_PAD_ON TO SET UP AN INTERUPT FOR THE PAD ; OR RUN SCAN_PAD_OFF TO DISABLE THE INTERUPT. ; IN YOUR INTERUP SERVICE ROUTINE, CHECK FOR A PORT ; CHANGE ON RB4-RB7 AND THEN CALL KEY_HIT_INT TO ; SEE WHICH KEY WAS HIT!! ;********************************************************* SCAN_PAD_ON: MOVLW B'11111111' ;MAKE PORTB TRIS PORTB ;ALL INPUTS BSF STATUS,RP0 ;SWITCH TO BANK 1 BCF OPTREG,RBPU ;ENABLE WEAK PULLUPS BCF STATUS,RP0 ;SWITCH TO BANK 0 BCF INTCON,RBIF ;CLEAR INTERUPT FLAG BSF INTCON,GIE ;ENABLE GLOBAL INTERUPTS BSF INTCON,RBIE ;AND THE ONE WE NEED RETURN SCAN_PAD_OFF: BSF STATUS,RP0 ;SWITCH TO BANK 1 BSF OPTREG,RBPU ;DISABLE WEAK PULLUPS BCF STATUS,RP0 ;SWITCH TO BANK 0 BCF INTCON,RBIE ;DISABLE INTERUPT RETURN ;******************************************************** ; IF A KEY IS HIT, YOUR PROGRAM GETS TO HERE ;******************************************************** ;******************************************************** ; RB4 RB5 RB6 RB7 ; COL1 COL2 COL3 COL4 ; B0 ROW1 1 2 3 < ; ; B1 ROW2 4 5 6 > ; ; B2 ROW3 7 8 9 Y ; ; B3 ROW4 * 0 # N ; ;******************************************************** KEY_HIT_INT: movfw cnt ;get the cnt value movwf temp_cnt ;save it movfw cnt2 ;get the cnt value movwf temp_cnt2 ;save it movfw cnt3 ;get the cnt value movwf temp_cnt3 ;save it movfw cnt4 ;get the cnt value movwf temp_cnt4 ;save it MOVFW PORTB ;MOVE PORTB VALUE TO W REG ;(THIS ENDS THE MISMATCH CONDITION) MOVLW .250 ;DEBOUNCE DELAY TIME CALL MDELAY ;DEBOUNCE DELAY call read_again ;check for a reasonable key press BTFSS TEMP_KEY2,4 ;WAS IT ON RB4? GOTO COLUMN1 ;IT WAS ON COLUMN 1 BTFSS TEMP_KEY2,5 ;WAS IT ON RB5? GOTO COLUMN2 ;IT WAS ON COLUMN 2 BTFSS TEMP_KEY2,6 ;WAS IT ON RB6? GOTO COLUMN3 ;IT WAS ON COLUMN 3 BTFSS TEMP_KEY2,7 ;WAS IT ON RB7? GOTO COLUMN4 ;IT WAS ON COLUMN 4 BCF INTCON,RBIF ;CLEAR THE INTERUPT FLAG call finnish_pad ; RETFIE ;RETURN FROM THE INTERUPT COLUMN1: CLRF TEMP_KEY ;SET KEY VALUE TO 0 MOVLW B'11101111' ;SET THE COLUMN VALUE (RB4) MOVWF COL ;INTO COL REGISTER CALL KEY_PRESS ;GO SEE WHICH ROW IT IS ON CALL KEY_DOWN? ;MAKE SURE THE KEY IS RELEASED MOVWF KEY_PRESSED ;MOVE THE KEY PRESSED TO FILE REG BCF INTCON,RBIF ;CLEAR THE INTERUPT FLAG call finnish_pad ; RETFIE COLUMN2: MOVLW .4 ;OFFSET VALUE FOR KEY MOVWF TEMP_KEY ;STORE IN TEMP_KEY MOVLW B'11011111' ;SET THE COLUMN VALUE (RB5) MOVWF COL ;INTO COL REGISTER CALL KEY_PRESS ;GO SEE WHICH ROW IT IS ON CALL KEY_DOWN? ;MAKE SURE THE KEY IS RELEASED MOVWF KEY_PRESSED ;MOVE THE KEY PRESSED TO FILE REG BCF INTCON,RBIF ;CLEAR THE INTERUPT FLAG call finnish_pad ; RETFIE COLUMN3: MOVLW .8 ;OFFSET VALUE FOR KEY MOVWF TEMP_KEY ;STORE IN TEMP_KEY MOVLW B'10111111' ;SET THE COLUMN VALUE (RB6) MOVWF COL ;INTO COL REGISTER CALL KEY_PRESS ;GO SEE WHICH ROW IT IS ON CALL KEY_DOWN? ;MAKE SURE THE KEY IS RELEASED MOVWF KEY_PRESSED ;MOVE THE KEY PRESSED TO FILE REG BCF INTCON,RBIF ;CLEAR THE INTERUPT FLAG call finnish_pad ; RETFIE COLUMN4: MOVLW .12 ;OFFSET VALUE FOR KEY MOVWF TEMP_KEY ;STORE IN TEMP_KEY MOVLW B'01111111' ;SET THE COLUMN VALUE (RB7) MOVWF COL ;INTO COL REGISTER CALL KEY_PRESS ;GO SEE WHICH ROW IT IS ON CALL KEY_DOWN? ;MAKE SURE THE KEY IS RELEASED MOVWF KEY_PRESSED ;MOVE THE KEY PRESSED TO FILE REG BCF INTCON,RBIF ;CLEAR THE INTERUPT FLAG call finnish_pad ; RETFIE KEY_PRESS: MOVFW COL ;GET THE CLOUMN VALUE TRIS PORTB ;MAKE THE COLUMN AN OUTPUT COMF COL,0 ;INVERT THE COL REGISTER MOVWF PORTB ;MAKE THE LINE HIGH ON YOUR COLUMN call read_again ;check the port for valid data BTFSC temp_key2,0 ;WAS IT ON ROW 1? GOTO KEY ;YEP INCF TEMP_KEY,1 ;INCREMENT KEY VALUE BTFSC temp_key2,1 ,1 ;WAS IT ON ROW 2? GOTO KEY ;YEP INCF TEMP_KEY,1 ;INCREMENT KEY VALUE BTFSC temp_key2,2 ;WAS IT ON ROW 3? GOTO KEY ;YEP INCF TEMP_KEY,1 ;INCREMENT KEY VALUE BTFSC temp_key2,3 ;WAS IT ON ROW 4? GOTO KEY ;YEP BCF INTCON,RBIF ;CLEAR THE INTERUPT FLAG call finnish_pad ; RETFIE ;RETURN FROM INTERUPT KEY: MOVFW TEMP_KEY ;CALL OUT THE VALUE OF THE KEY ADDWF PCL ;ADD IT TO THE PROGRAM COUNTER RETDATA "147*2580369#<>YN" ;RETURNS WITH THE KEY PRESSED ;************************************************************** ; THIS CHECKS FOR A KEY DOWN!! ;************************************************************** KEY_DOWN?: MOVWF TEMP_KEY ;STORE THE KEY PRESS CHECK_AGAIN: MOVLW B'11110000' ;CHECK IF BACK TO NORMAL SUBWF PORTB,W ; '' '' '' BTFSS STATUS,Z ;CHECK IF ZERO GOTO CHECK_AGAIN ;IF NOT THEN LOOP AGAIN MOVLW B'11111111' ;RESTORE THE KEYPAD TRIS REGISTER TRIS PORTB ; '' '' '' MOVFW TEMP_KEY ;RESTORE THE KEY PRESS RETURN ;************************************************************ ; This routine checks the pad for a valid key press ;************************************************************ read_AGAIN: MOVFW PORTB ;MOVE PORTB VALUE TO W REG MOVWF TEMP_KEY2 ;SAVE THE PORT READING MOVLW .250 ;DELAY TIME CALL MDELAY ;DELAY MOVLW .250 ;DELAY TIME CALL MDELAY ;DELAY MOVLW .250 ;DELAY TIME CALL MDELAY ;DELAY MOVFW PORTB ;READ PORT AGAIN SUBWF TEMP_KEY2,W ;SEE IF IT WAS THE SAME AS A MOMENT AGO SKPZ ;SKIP NEXT INSTRUCTION IF ZERO GOTO read_AGAIN ;LOOP UNTIL A BETTER READING IS PRESENT return ;***************************************************** ; this restores the counters ;****************************************************** finnish_pad: movfw temp_cnt ;get the cnt value movwf cnt ;resore it movfw temp_cnt2 ;get the cnt value movwf cnt2 ;resore it movfw temp_cnt3 ;get the cnt value movwf cnt3 ;resore it movfw temp_cnt4 ;get the cnt value movwf cnt4 ;resore it return ;return