;********************************************************************** ;* 8052.com Single Board Computer -- SBCMON Demonstration Program * ;* ---> KEYPAD DEMONSTRATION PROGRAM <--- * ;* For 8052.com SBC, hardware rev 1.3 * ;*--------------------------------------------------------------------* ;* This program is offered as-is with no warranty or guarantee of any * ;* kind. Its purpose is to serve as an educational aid in mastering * ;* the topics and concepts covered by the program. You are free to * ;* use this code for any purpose you see fit--including commercial-- * ;* but the exclusive responsibility for its use is the user of this * ;* code. This code is offered completely free of charge and VIS' and * ;* 8052.com's liability will be limited to the amount paid: zero. * ;*--------------------------------------------------------------------* ;* This program was coded to be compatible with the Pinnacle 52 IDE. * ;* Pinnacle 52 is available at http://www.vaultbbs.com/pinnacle. The * ;* program may require minor modifications in order to assemble with * ;* other assemblers. * ;*--------------------------------------------------------------------* ;* NOTE: This program was designed to be loaded into SBCMON's XRAM * ;* and executed as an SBCMON external program. It depends on one or * ;* more SBCMON library routines and, as such, will not work without * ;* SBCMON. This program is not intended to be loaded via in-system * ;* programming, only loaded within SBCMON. Should you wish to load * ;* this program via ISP as a stand-alone program, the SBCMON library * ;* entry point equates should be removed and the respective routines * ;* should be copied from SBCMON into this program. The source code * ;* for SBCMON may be found at http://www.8052.com/sbc/sbcmon. * ;*====================================================================* ;* Filename: KEYPAD.ASM * ;* Description: This is a 4x4 keypad demonstration program. When * ;* executed it will wait for input on the 4x4 keypad and echo it to * ;* the PC terminal program. The keypad input is debounced. The * ;* program may be exited by pressing any key in the PC terminal. * ;********************************************************************** ;========================================================== ; SBCMON LIBRARY ROUTINE ENTRY POINT EQUATES ; ;If you wish to make this a stand-alone program, remove ;these equates and copy the source code for the named ;routines from the SBCMON source code. SBCMON source code ;may be found at http://www.8052.com/sbc/sbcmon. ;=========================================================== SendSerialByte EQU 0047h ;========================================================== ; PROGRAM LOCATION ; ;The program is located at 8000h since this is where the ;8052.com SBC's XRAM/code memory is in the memory map. ;Programs loaded into this RAM area can be accessed as both ;data and executed as a program. If you are going to make ;this a stand-alone program the following ORG should be ;modified to 0000h rather than 8000h. ;=========================================================== ORG 8000h ;========================================================== ; PROGRAM CODE ; ;This is the actual guts of the demonstration code. ;=========================================================== CLR RI ;This was added to code to make sure ;serial input buffer is initially clear KP_Loop: JB RI,KP_End ;This was added to detect serial keypress MOV R3,#03h ;Start with row 3 of the keypad KP_Cycle: MOV A,R3 ;Get current row (0-3) in accumulator MOV DPTR,#KP_AddrTable ;Point to the address table MOVC A,@A+DPTR ;Get the DPTR high byte from the table MOV DPH,#50h ;Set high byte to 50h which is the address of keypad MOV DPL,A ;Move to DPL, DPH already set MOVX A,@DPTR ;Read the status of the keypad row ANL A,#0Fh ;Only interest in low 4 bits XRL A,#0Fh ;Invert bits, keypress=1, 0=No key JNZ KP_ProcessKey ;If the value is not zero, process it DEC R3 ;Decrement row counter CJNE R3,#0FFh,KP_Cycle ;If not FF, process next row SJMP KP_Loop ;After 4 rows, start with row 3 again KP_ProcessKey: MOV R1,A ;Hold the keypress in R1 MOV R6,#23 ;23*256=7680*8=approx. 46,080 cycles KP_DebounceLoop2: MOV R7,#00h ;Set R7 to 0 256 loops (00->FF->00) KP_DebounceLoop: MOVX A,@DPTR ;Re-read the same keypad row ANL A,#0Fh ;Only interest in low 4 bits XRL A,#0Fh ;Invert all the bits XRL A,R1 ;Exclusive OR with the original keypress JNZ KP_Loop ;If not same as last value, debounce it! DJNZ R7,KP_DebounceLoop ;Loop R7 times DJNZ R6,KP_DebounceLoop2;Loop R6 times MOV A,R1 ;Restore the original value read from keypad PUSH DPL ;Save low byte of keypad address KP_DebounceDone: CLR C ;Make sure carry starts clear MOV R0,#00h ;R0 starts at zero KP_FindKeyNum: RRC A ;Rotate the value right into the carry JC KP_KeyFound ;If set, we found the key so exit INC R0 ;Increment the key number indicator SJMP KP_FindKeyNum ;Keep searching until we find the key KP_KeyFound: MOV A,R3 ;Get row number RL A ;Multiply by 2 RL A ;Multiply by 4 ADD A,R0 ;Add the key offset MOV DPTR,#KP_KeyTable ;Get the start address of the key table MOVC A,@A+DPTR ;Get the keypress into accumulator LCALL SendSerialByte ;Echo keypress to the serial port POP DPL ;Restore DPTR to access keypad MOV DPH,#50h ;High byte of keypad address KP_Wait: MOVX A,@DPTR ;Read the keypad ANL A,#0Fh ;Only interested in low 4 bits CJNE A,#0Fh,KP_Wait ;If it's not 0Fh then keep waiting LJMP KP_Loop ;Wait for another keypad press KP_KeyTable: DB "ABCD" ;Decode for keys in row 0 DB "369#" ;Decode for keys in row 1 DB "2580" ;Decode for keys in row 2 DB "147*" ;Decode for keys in row 3 KP_AddrTable: DB 0Eh ;Address to access row 0 (500E) DB 0Dh ;Address to access row 1 (500D) DB 0Bh ;Address to access row 2 (500B) DB 07h ;Address to access row 3 (5007) KP_End: RET ;Return to SBCMON