Designing a keypad for an AVR Microcontroller

by using the upper four bits as outputs and the lower four bits as inputs, a simple 4×4, 16 button keypad can be connected to a microcontroller.

the first picture shows the state after the “0″ key has been pressed.
the 0×24 corresponds to the “scancode”, the first digit being the column and the second being the row.
to be exact, in binary 0×24 equals 0b00101000, this shows that during the scan, the key in the second column and the fourth row was pressed.

the bracketed values under that are the contents of the key buffer.

HPIM0056-e.JPG mainboard-top.png mainboard-bot.png
mainboard-sch.png mainboard-brd-e.png mainboard-brd-silk.png

 
 
a simple code example for this:

//high bits are columns, low bits are rows
volatile uint8_t scancode = 0x00;
uint8_t i, j;

// set data direction on PORTD
//   pins 8,7,6,5 as output, pins 4,3,2,1 as input
outb(DDRD,  0b11110000);

//loop over pins
for( i=4; i<8; i++ ) {

	// sets outputs low one pin at a time
	//   also enables internal pull-ups on inputs
	outb( PORTD, ~(1<<i) );

	//debounce delay and settling time
	timerPause(5);

	//loop over port positions
	for( j=0; j<4; j++ ) {
		if( bit_is_clear(PIND,j) ) {
			//set scancode
			scancode = (1<<i)|(1<<j);
		}
	}

}

 
 
the “~(1<<n)” is an example of bitshifting, in this case it means “bitshift 1 left “n” times, then invert the result” or if we take n as 3, it would be:
~(1<<3)
after 0 shifts:
~(0b00000001)
after 1 shift:
~(0b00000010)
after 2 shifts:
~(0b00000100)
after 3 shifts:
~(0b00001000)
then inverted:
0b11110111

a slightly more complicated looking example of this is used in the inner loop:
(1<<n)|(1<<m)
or if we take n as 6 and m as 2 it would be:
(0b01000000)|(0b00000100)
and that would resolve to:
0b01000100

Leave a comment

  • Tags

  • Categories

  • Need Code Written?

  • Need a Coding Job?

  • Archives