Prof. B.M.
DAXINI
Instrumentation & Control Dept
AITS Rajkot
Advanced Microcontroller 1st sem
Introduction
Keyboards are organized in a matrix of rows and
columns.
The CPU accesses both rows and columns through
ports
Therefore, with two 8-bit ports, an 8 x 8 matrix of
keys can be connected to a microprocessor
When a key is pressed, a row and a column make a
contact Otherwise, there is no connection between
rows and columns
Prof. B.M.DAXINI (ICD) 2
Scanning & Identifying the Key
A 4x4 matrix connected to two ports
The rows are connected to an output port and the columns are connected
to an input port
Prof. B.M.DAXINI (ICD) 3
Prof. B.M.DAXINI (ICD) 4
Grounding Rows and Reading Columns
It is the function of the microcontroller to scan the
keyboard continuously to detect and identify the key pressed
To detect a pressed key, the microcontroller grounds all
rows by providing 0 to the output latch, then it reads the
columns
If the data read from columns is D3 D0 = 1111, no key
has been pressed and the process continues till key press is
detected.
If one of the column bits has a zero, this means that a key
press has occurred.
For example, if D3 D0 = 1101, this means that a key in the
D1 column has been pressed.
After detecting a key press, microcontroller will go through
the process of identifying the key
Prof. B.M.DAXINI (ICD) 5
Grounding Rows and Reading Columns
Starting with the top row, the microcontroller grounds it by
providing a low to row D0 only
It reads the columns, if the data read is all 1s, no key in that
row is activated and the process is moved to the next row
It grounds the next row, reads the columns, and checks for
any zero
This process continues until the row is identified
After identification of the row in which the key has been
pressed, find out which column the pressed key belongs to.
E.g.
(a) D3 D0 = 1110 for the row, D3 D0 = 1011 for the
column (key 2 is pressed)
(b) D3 D0 = 1101 for the row, D3 D0 = 0111 for the
column (key 7 is pressed)
Prof. B.M.DAXINI (ICD) 6
Detection and identification of key
activation goes through the following
stages
1) To make sure that the preceding key has been released, 0s
are output to all rows at once, and the columns are read
and checked repeatedly until all the columns are high
When all columns are found to be high, the program
waits for a short amount of time before it goes to the next
stage of waiting for a key to be pressed.
2) To see if any key is pressed, the columns are scanned
over and over in an infinite loop until one of them has a 0
on it.
The output latches connected to rows still have their
initial zeros (provided in stage 1), making them grounded
Prof. B.M.DAXINI (ICD) 7
After the key press detection, it waits 20 ms for the bounce
and then scans the columns again
(a) it ensures that the first key press detection was not an
erroneous one due a spike noise
(b) the key press. If after the 20-ms delay the key is still
pressed, it goes back into the loop to detect a real key press
3) To detect which row key press belongs to, it grounds one
row at a time, reading the columns each time.
If it finds that all columns are high, this means that the key
press cannot belong to that row.
Therefore, it grounds the next row and continues until it
finds the row the key press belongs to.
Upon finding the row that the key press belongs to, it sets
up the starting address for the look-up table holding the
scan codes (or ASCII) for that row
Prof. B.M.DAXINI (ICD) 8
4) To identify the key press, it rotates the column bits, one
bit at a time, into the carry flag and checks to see if it is
low
Upon finding the zero, it pulls out the ASCII code for
that key from the look-up table
otherwise, it increments the pointer to point to the next
element of the look-up table
Prof. B.M.DAXINI (ICD) 9
Prof. B.M.DAXINI (ICD) 10
Prof. B.M.DAXINI (ICD) 11
Keyboard Program
It checks a key closure ; debounce multiple
key contacts and encodes the key in binary
digit
KYSOPEN EQU OX00 ; Define data registers used
COUNTER EQU 0X01
L1REG EQU 0X10 ; Registers for delay
L2REG EQU 0X11
ORG 0X20
KEYPAD:
SETUP: MOVLW 0X0F
MOVWF TRISB ;Enable RB7-RB4 as output and
RB3-RB0 as input
BCF INTCON2,7,0 ;Enable pull-up resistors
MOVLW 0XFF ;Reading when all keys are open
MOVWF KYSOPEN
Prof. B.M.DAXINI (ICD) 12
KEYCHECK:
MOVF PORTB,0,0 ;read Port B
CPFSGT KYSOPEN ;are all keys open
RETURN ;If yes, go back check again
MOVLW D40 ;Load 40 multiplier in L2REG
to multiply
MOVWF L2REG ;500us delay in loop1
CALL DELAY_20ms ;wait 20ms to debounce the
key
KEYCODE: ;to identify key position
COLRB4: MOVLW 0XFF ;Scan column RB4
IORWF PORTB,F ;All other keys should be 1s
GNDB4: BCF PORTB,4 ;Ground column RB4
KEYB40: BTFSC PORTB,0 ;Check RB0, if = 0,find code
BRA KEYB41 ;If RB0=1, check next key
MOVLW 0X0C ;code for key C
RETURN
Prof. B.M.DAXINI (ICD) 13
KEYB41: BTFSC PORTB,1 ;Check RB1, if = 0,find code
BRA KEYB42 ;If RB1=1, check next key
MOVLW 0X08 ;code for key 8
RETURN
KEYB42: BTFSC PORTB,2 ;Check RB2, if = 0,find code
BRA KEYB43 ;If RB2=1, check next key
MOVLW 0X04 ;code for key 4
RETURN
KEYB43: BTFSC PORTB,3 ;Check RB3, if = 0,find code
BRA COLRB5 ;If RB3=1, go to next col.
MOVLW 0X0 ;code for key 0
RETURN
COLRB5: MOVLW 0XFF ;Scan column RB5
IORWF PORTB,F ;All other column should be 1
GNDB5: BCF PORTB,5 ;Ground column RB5
BTFSC PORTB,0 ;Check RB0, if = 0, find code
BRA KEYB51
MOVLW 0X0D
RETURN
Prof. B.M.DAXINI (ICD) 14
KEYB51: BTFSC PORTB,1
BRA KEYB52
MOVLW 0X09
RETURN
KEYB52: BTFSC PORTB,2
BRA KEYB53
MOVLW 0X05
RETURN
KEYB53: BTFSC PORTB,3
BRA COLRB6
MOVLW 0X1
RETURN
COLRB6: MOVLW 0XFF
IORWF PORTB,F
GNDB6: BCF PORTB,6
BTFSC PORTB,0
BRA KEYB61
MOVLW 0X0E
RETURN
Prof. B.M.DAXINI (ICD) 15
KEYB61: BTFSC PORTB,1
BRA KEYB62
MOVLW 0X0A
RETURN
KEYB62: BTFSC PORTB,2
BRA KEYB63
MOVLW 0X06
RETURN
KEYB63: BTFSC PORTB,3
BRA COLRB7
MOVLW 0X2
RETURN
COLRB7: MOVLW 0XFF
IORWF PORTB,F
GNDB7: BCF PORTB,7
BTFSC PORTB,0
BRA KEYB71
MOVLW 0X0F
RETURN
Prof. B.M.DAXINI (ICD) 16
KEYB71: BTFSC PORTB,1
BRA KEYB72
MOVLW 0X0B
RETURN
KEYB72: BTFSC PORTB,2
BRA KEYB73
MOVLW 0X07
RETURN
KEYB73: BTFSC PORTB,3
RETURN
MOVLW 0X3
RETURN
DELAY_20ms:
LOOP2: MOVLW D250
MOVWF L1REG
LOOP1: DECF L1REG,1
BNZ LOOP1
DECF L2REG,1
BNZ LOOP2
RETURN
END
Prof. B.M.DAXINI (ICD) 17
Interrupt based programming for the Matrix keyboard
Prof. B.M.DAXINI (ICD) 18
D15mH EQU D100 ;15 ms delay high byte
D15mL EQU D255 ;low byte
COL EQU 0X08 ; holds the column found
DR15mH EQU 0X09 ; registers for 15 ms
DR15mL EQU 0X0A
ORG 0X0
RESET_ISR GOTO MAIN ;Jump over interrupt table
ORG 0X08
HI_ISR BTFSC INTCON,RBIF ; was it a PORTB change
BRA RBIF_ISR ; yes than go to ISR
RETFIE ; else return
Main CLRF TRISD ; make PORTD as output
BCF INTCON2,RBPU ; enable PORTB pull up resistor
MOVLW 0XF0 ; make PORTB high i/p port
MOVWF TRISB ; make PORTB low o/p port
MOVWF PORTB ; ground all rows
Prof. B.M.DAXINI (ICD) 19
KEYOPEN
CPFSEQ PORTB ; are all keys open
GOTO KEYOPEN ; wait until keypad ready
MOVLW UPPER
MOVWF TBLPTRU ; load upper byte of TBLPTR
MOVLW HIGH
MOVWF TBLPTRH ; load high byte of TBLPTR
BSF INTCON,RBIE ; enable PORTB change interrupt
BSF INTCON,GIE ; enable all interrupts globally
LOOP GOTO LOOP ; wait for key press
RBIF_ISR CALL DELAY ; wait for debounce
MOVFF PORTB,COL ; get the column of key press
MOVLW 0XFE
MOVWF PORTB ; ground row 0
CPFSEQ PORTB ; Did PORTB change?
BRA ROW0 ; yes then row 0
MOVLW 0XFC
MOVWF PORTB ; ground row 1
CPFSEQ PORTB ; Did PORTB change?
BRA ROW1 ; yes then row 1
Prof. B.M.DAXINI (ICD) 20
MOVLW 0XFB
MOVWF PORTB ; ground row 2
CPFSEQ PORTB ; Did PORTB change?
BRA ROW2 ; yes then row 2
MOVLW 0XF7
MOVWF PORTB ; ground row 3
CPFSEQ PORTB ; Did PORTB change?
BRA ROW3 ; yes then row 3
GOTO BAD_RBIF ; no then key press too short
ROW0 MOVLW low(KCODE0) ; set TBLPTR = start of row 0
BRA FIND ; find the column
ROW1 MOVLW low(KCODE1) ; set TBLPTR = start of row 1
BRA FIND ; find the column
ROW2 MOVLW low(KCODE2) ; set TBLPTR = start of row 2
BRA FIND ; find the column
ROW3 MOVLW low(KCODE3) ; set TBLPTR = start of row 3
FIND MOVWF TBLPTRL ; load low byte of TBLPTR
MOVLW 0XF0
XORWF COL ; invert high nibble
Prof. B.M.DAXINI (ICD) 21
SWAPF COL,F ; bring to low nibble
AGAIN RRCF COL ; rotate to find the column
BC MATCH ; column found, get the ASCII code
INCF TBLPTRL ; else point to next col. Address
BRA AGAIN ; keep searching
MATCH TBLRD*+ ; get ASCII code from table
MOVFF TABLAT,PORTD ; display pressed key on PORTD
WAIT MOVLW 0XF0
MOVWF PORTB ; reset PORTB
CPFSEQ PORTB ; Did PORTB change?
BRA WAIT ; yes then wait for key release
BCF INTCON,RBIF ; clear PORTB, change flag
RETFIE ; return & wait for key press
BAD_RBIF MOVLW 0X00 ; return null
GOTO WAIT ; wait for key release
Prof. B.M.DAXINI (ICD) 22
DELAY MOVLW DR15mH ; high byte of delay
MOVWF DR15mH ; store in register
D2 MOVLW DR15mL ; low byte of delay
MOVWF DR15mL ; store in register
D1 DECF DR15mL,F ; stay until DR15mL becomes 0
BNZ D1
DECF DR15mH,F ; loop until all DR1m=0
BNZ D2
RETURN
ORG 300H
KCODE0 DB 0,1,2,3 ; ROW 0
KCODE1 DB 4,5,6,7 ; ROW 1
KCODE2 DB 8,9,A,B ; ROW 2
KCODE3 DB C,D,E,F ; ROW 3
Prof. B.M.DAXINI (ICD) 23
Prof. B.M.DAXINI (ICD) 24