; keypad2_dd.asm ; This source code provides a device driver for the AK-1607 keypad. It allows the user to read all 16 ; keys and provide appropriate input. In order to use this device driver, the main program must define the following ; parameters: ; ; KEYPAD_PORT This is the port for the keypad, typically either PORTA or PORTB. ; KEYPAD_DDR This is the data direction register for the keypad. ; KEYPAD_PINS This is the input pins for the keypad. ; ; CONFIGURATION ; ; Course: CE2800 Winter 2010-2011 ; Author: schilling@msoe.edu ; Date: 1-11-2011 ; Modified by mlh on 1/17/2012 - now uses KEYPAD_PORT, KEYPAD_DDR, and KEYPAD_PINS as ; documented above (was hardcoded to use PORTA before). Note that to use these subroutines, ; you must .include "m32def.inc" in your main program that .includes "keypad2_dd.asm", as the ; code here presumes that PORTA and other IO registers are predefined to addresses in the ; IO address space, and thus IN and OUT instructions are used accordingly. ;##################################################################################################### ; Define and equal directives go here. ;##################################################################################################### ;##################################################################################################### ; DATA SEGMENT DEFINITION ;##################################################################################################### .dseg ; Begin the data segment ; No variables declared. ;##################################################################################################### ; CODE SEGMENT DEFINITION ;##################################################################################################### .cseg ;##################################################################################################### ; Subroutine keypad_init ; This is the keypad init routine. It will initialize the keypad port appropriately. ; ; Return Values: ; None ;##################################################################################################### keypad_init: push R16 LDI R16, 0x74 ; Set keypad cols as output, rows as input. OUT KEYPAD_DDR, R16 out KEYPAD_PORT, R16 LDI R16, 0x8B ; Enable pull-up resistors on the row pins. OUT KEYPAD_PORT, R16 pop R16 ret ;##################################################################################################### ; Subroutine keypad_read ; This function will return in R25:R24 the keys which are pressed on the keypad. One bit will be set ; per pressed key. ; ; Parameters ; None ; ; Return Values: ; R25:R24 will return a bitmapped representation of the keys which are depressed. ;##################################################################################################### ; ROW, COLUMN .equ COL1=0b00000100 .equ COL2=0b00010000 .equ COL3=0b00100000 .equ COL4=0b01000000 .equ ROW1=0b10000000 .equ ROW2=0b00000001 .equ ROW3=0b00000010 .equ ROW4=0b00001000 keypadBtnTable: .db COL2, ROW4, COL1, ROW1, COL2, ROW1, COL3, ROW1, COL1, ROW2, COL2, ROW2, COL3, ROW2, COL1, ROW3, COL2, ROW3, COL3, ROW3, COL4, ROW1, COL4, ROW2, COL4, ROW3, COL4, ROW4, COL1, ROW4, COL3, ROW4 keypad_read: push ZH push ZL push R16 push R17 push R18 clr R25 clr R24 ; Load the table into Z. This table will map bits into buttons. ldi ZH, high(keypadBtnTable<<1) ldi ZL, low(keypadBtnTable<<1) ldi R16, 0x01 keypadReadLoop0: ; Loop through buttons 0 - 7, setting bits if the button is pressed. cpi R16, 0x00 breq exitkeypadReadLoop0 lpm R17, Z+ com R17 out KEYPAD_PORT, R17 ; Set the output ports to drive the appropriate pins. NOP ; Wait 10 cycles for the electrical bus to stabolize. NOP NOP NOP NOP NOP NOP NOP NOP NOP in R17, KEYPAD_PINS com R17 LPM R18, Z+ and R17, R18 breq keypadReadLoop0Shift OR R24, R16 keypadReadLoop0Shift: lsl R16 rjmp keypadReadLoop0 exitkeypadReadLoop0: ldi R16, 0x01 keypadReadLoop1: ; Perform the same logic for buttons 8-15. cpi R16, 0x00 breq exitkeypadReadLoop1 lpm R17, Z+ com R17 out KEYPAD_PORT, R17 NOP ; Wait for the bus to stabolize. NOP NOP NOP NOP NOP NOP NOP NOP NOP in R17, KEYPAD_PINS com R17 LPM R18, Z+ and R17, R18 breq keypadReadLoop1Shift OR R25, R16 keypadReadLoop1Shift: lsl R16 rjmp keypadReadLoop1 exitkeypadReadLoop1: pop R18 pop R17 pop R16 pop ZL pop ZH ret