This document describes a program that scans a 4x4 hex keypad connected to an ARM7 microcontroller and displays the key pressed on a serial port. It initializes the serial port and defines functions for key scanning, sending hex digits and delay. The key scanning function uses I/O pins to scan each row, incrementing the result value when a key is pressed. It then displays and delays before scanning again. Scanning starts from the third row and proceeds to the first row, checking each column in a row.
1. HEX KEYPAD SCANNING PROGRAM
LOGICAL APPROACH
By
Sudheera Rao Y
spn_rao@yahoo.com
1
2. Interfacing a 4x4 keyboard to the ARM7 LPC2148 Microcontroller
and
displaying the key code pressed by the user
C D E F
8 9 A B
4 5 6 7
0 1 2 3
2
3. Program:
#include <LPC214X.H>
#define CR 0x0d
/* ----------------------------------Initialization of Serial Port -------------------------------------------*/
void init_serial (void)
{ /* Initialize Serial Interface */
PINSEL0 = 0x00050000; /* Enable RxD1 and TxD1 */
U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
U1DLL = 97; /* 9600 Baud Rate @ 12 MHz VPB Clock */
U1LCR = 0x03; /* DLAB = 0 */
}
int putkey(int ch) /* Send the character to UART */
{
if(ch == 'n')
{
while(!(U1LSR & 0x20));
U1THR = CR;
}
while(!(U1LSR & 0x20));
return (U1THR = ch);
}
3
4. void sendhex (int hex)
{ /* Write Hex Digit to Serial Port */
if (hex > 9)
putkey('A' + (hex - 10));
else
putkey('0' + hex);
}
void sendstr(unsigned char *p) /* Send the string of characters to UART */
{
while(*p)
{
putkey(*p++);
}
}
void delay()
{
unsigned int i,j;
for(i = 0; i <= 32100; i ++)
{
for(j = 0; j <= 10; j ++);
}
}
4
5. unsigned long rows,columns,result;
void KeyScan() /* Scan Routine for the key pad */
{
unsigned long temp = 0x00;
again:
columns = 0x00040000;
rows = 0x00000004;
result = 0x0000000C;
next:
IOSET0 = columns;
delay();
temp = IOPIN1;
temp = (temp & 0x000F0000);
if(temp != 0x00000000)
{
rot:
temp = temp >> 1;
if ((temp&0x000f8000) == 0x00008000)
{
IOCLR0=columns; //
return;
}
else
{
result += 1;
goto rot;
}
}
5
6. else
{
result -= 0x04;
rows --;
if (rows == 0x00)
{
IOCLR0=columns;
goto again;
} //closing if ( ) statements
else
{
IOCLR0= columns;
columns >>=1;
if(columns == 0x00004000)
columns = (columns & 0x0040000);
goto next;
} // closing else
} // closing else
} // closing of Keyscan function
void Display()
{
sendhex(result);
}
int main()
{
IODIR1 = 0x00000000; //Port1 as Input
IODIR0 = 0x007F80F3; //Port0 as Output
init_serial ();
while(1)
{
KeyScan();
sendstr("nThe KEY pressed is : ");
Display();
delay();
}
}
6
7. SCANNING OF HEX KEYPAD
0th Col 1st Col 2nd Col 3rd Col
3rdrow
C
result=0x0000000C
(i.e 12)
=1100
11-3rd row . 00 – 0th Col
D
Result+=1
(i.e 13)
=1101
E
Result+=1
(i.e 14)
=1110
F
Result+=1
(i.e 15)
=1111
2ndrow
8
result -=0x04
(i.e 8)
=1000
10 - 2nd row. 00 – 0th col
9
result+=1
A
result+=1
B
result+=1
1strow
4
result -=0x04
5
result+=1
6
result+=1
7
result+=1
0throw
0
result - =0x04
1
result+=1
2
result+=1
3
result+=1
7
8. 0th Col 1st Col 2nd Col 3rd Col
3rdrow
C
result=0x0000000C
(i.e 12)
=1100
11-3rd row . 00 – 0th Col
D
Result+=1
(i.e 13)
=1101
E
Result+=1
(i.e 14)
=1110
F
Result+=1
(i.e 15)
=1111
2ndrow
8
result -=0x04
(i.e 8)
=1000
10 - 2nd row. 00 – 0th col
9
result+=1
A
result+=1
B
result+=1
1strow
4
result -=0x04
5
result+=1
6
result+=1
7
result+=1
0throw
0
result - =0x04
1
result+=1
2
result+=1
3
result+=1
SCANNING OF 3rd ROW done FIRST
SCANNING 2nd ROW done SECOND
SCANNING 1st ROW done THIRD
SCANNING 0th ROW done FOURTH
8
9. CONTROL SWITCH FOR SCANNING OF HEX KEYPAD COLUMNS
CONTROL SWITCH is defined in IOSET0 Register. The Control switch
for various series of Columns is as follows.
For SCANNING OF 3rd ROW -SET 18th BIT
Columns= 0x00040000
For SCANNING 2nd ROW -SET 17th BIT
Columns>>=1
For SCANNING 1st ROW -SET 16th BIT
Columns>>=1
For SCANNING 0th ROW -SET 15th BIT
Columns>>=1
19 18 17 16 15
IOSET0
In a row there will be 4 columns. From 2nd row onwards, At the Beginning
of row (i.e 0th col) ,the value of result will be result-=0x04. It keeps
increasing for every column in that row (result+=1). If the user has not
pressed any key in that row, then we go for next row by changing control
switch for the next row( Columns>>=1. When the control switch goes from
15th to 14th Bit, it ‘s value becomes 0x00004000. It means user has not
pressed any key. Hence we should start from top again by setting control
switch to 3rd row.
9
10. c D E F
19 18 17 16
PIN
Numbers
8 9 A B
19 18 17 16
PIN
Numbers
10
11. c D E F 0 0 0 1
19 18 17 16
PIN
Numbers
If the user chooses “C”
c D E F 0 0 0 0
19 18 17 16
“temp “ variable to store user selection. If the user does not selected any thing
PIN
Numbers
temp=IOPIN1
temp=
This is obtained
through IOPIN
Register
11
12. temp is not equal to zero. It means the user has pressed
some key and we have to find which key it is. It is the first
iteration. At this point the value of result is 0x0000000C. If
the user has pressed C then the value of temp will be 0001 0 0 0 1temp=
19 18 17 16If we do temp>>1, It shifts the set bit to 15th bit and value
becomes 0x00008000. . 15th bit is to exit from loop. 0x00008000
is to exit from keyscan function. If the condition (temp &
0x000f8000)==0x00008000 satisfies, The value of result is
returned to the main function. That will be “C”. (Note that I0SET
is set for 3rd row)
If the condition does not satiefies, it means user has pressed
some key, but it is not C. Then we should suspect for next
character in that row, i.e D. Hence we increase the value of result
(i.e. result+=1). Then again do rotation of “temp “ bits. If the user
has pressed D then value of temp will be 0010
0 0 1 0temp=
19 18 17 16
For the “D” to become true, 1st rotation temp>>1 becomes falls. Result value increases by 1 .
2nd rotation becomes true. The current value of result is returned. That will be “D”. (Note that I0SET is
set for 3rd row)
12
13. If the user has not pressed any key from 3rd row, scanning goes to the
next row (2nd row). When control was at 3rd row, value of result= 0x0000000C. It becomes
result-=0x04. i.e result=0x08. Number of rows decremented by 1. so rows--.
But rows number have not become zero. To scan the 2nd row, we should set the
17th bit of IOSET. This is done by columns >>=1
8
If the user has pressed this key
•temp=0001
•Row=2
•Result=8
•Temp>>1
•return
If user has not pressed this key
•Temp=0010 (If pressed key is 9)
•Row=2
•Result+=1
9
If the user has pressed this key
•temp=0010
•Row=2
•Result=9
•Temp>>1
•return
If user has not pressed this key
•Temp=0100 (If pressed key is A)
•Row=2
•Result+=1
13