Assembly Language Programming

Course Index 
Dr. Margush's page 

Programming Assignment

Reading from a Keypad

You will write a test application and a procedure to allow input from a data entry keypad connected to port A of the STK-500. You should run the processor at 1MHz using the internal oscillator for this application.

You will be writing a function that will be used in this program, so be sure to initialize the stack. The test application will call your keypad_read procedure and display the results on the LED's. This procedure is expected to be called frequently by any application, otherwise keypresses will be missed.

The keypad_read procedure will not alter any registers (it may use them, but must restore them before exiting) other than R0, in which it will return a coded value representing the real-time status of the keypad, and will also flag the occurrence of keyup events. Applications can easily ignore the real-time status and respond only to keyup events if desired. The keycode is as follows:

The keypad_read must remember the most recently released number key and shift key (# and *). When keypad_read returns a keyup event, this memory is cleared. A keyup event is returned only when keypad_read is called and it notices all keys are released, but on the previous call to the procedure one or more keys were down. When returning a keyup event, bit 6 is 0. 

Notes:

Pressing more than 2 keys can produce ambiguous results. Your program need only work for a max of 2 keys held down simultaneously. Please note that the keypad_read procedure always returns with a value in a very short time. It examines the current state of the keypad, using up just enough time to do this, and either returns a keyup event code or the real-time status of the pad. It never waits for a key up or key down to occur.

Application:

Your application will display information on the LED's. It will function in two modes in two modes. Realtime-mode is the default mode that is entered when the processor is reset. Simply poll the keypad and display the realtime data, ignoring keyup events. Display the returned key code on the LED's (1's should show as ON). LED7 should be always off in this mode.

The application is switched to event mode by pressing any of the buttons (0-7) on the STK-500 board (connected on PORTD). In event mode, LED7 is always on, as the LED's will display keyup events as reported by the kepad_read procedure. The LED's do not directly display keyup event codes however, as LED6 continues to display realtime information  provided by bit 6 of the real-time keycode; LED6 will be illuminated if a key is depressed. The other 7 LED's should display the value of bits 7, 5-0 of the most recent keyup event.

Hardware

The ribbon cable on the keypad should have the red wire closest to the 1 key. When you connect the keypad to the PORTA header, be sure that the red wire is next to the PORTA label (at VTG and GND end of the header). If you reverse it, some row/column combinations cannot be scanned. Luckily, the header wiring is such that pressing keys will not result in a short circuit even if connected backwards.

The keypad has 3 columns (labeled X1, X2, and X3) and 4 rows (labeled Y1, Y2, Y3, and Y4). Keys 1, 2, and 3 are in row Y1. Keys 1, 4, 7, and * are in column X1. Assuming you connect the keypad correctly, the following connections should be true

PA0 X3
PA1 X2
PA2 X1
PA3 Y4
PA4

Y3

PA5 Y2
PA6 Y1
PA7 unused

You should never configure X's and Y's as outputs at the same time - doing so will create a conflict if certain keys are pressed.

You will want to do something like

Output a 0 on Xi and read the values on Y1-Y4, repeating for i=1, 2, and 3. Configure the unused columns as inputs with pull-ups to prevent interference of buttons in inactive columns. Note that you will need to output 0's and look for a 0 as input to detect a pressed key. Keys that are not pressed will result in an input value of 1 (due to the pullup resistors). Remember to read the inputs on PINA, not PORTA. For this to work reliably, you must be careful when you switch a column from output to input. Enabling a pin as input, and enabling the pullup resistor, does not mean the data on that pin will immediately go to 1 when this pin was previously outputting a 0. You need to wait a bit for the input to stabalize. Let me recommend the following sequence:

Suppose we want to 0 column 1 and see what we read on the rows:

;be sure all pins are inputs to start
ldi r17, 0
out DDRA, r17
;We need pullups on X2, X3, and all 4 Y's.
ldi r17,0b01111011 ;pullups for all but X1 (PA2), 0 to be asserted on PA2
out PORTA, r17
sbi DDRA, PA2 ;switch pin to output
;delay - test for a suitable delay
in r1, PINA ;read rows into PA3-6

Don't forget to debounce! The keypad specs indicate that the switches have a bounce of less than 10 msec. Do not call keypad_read more frequently than once every 10 msec.

The hardware is available from www.kanda.com. The part is simply called Data Entry Keypad. It comes with a 10-pin cable that plugs directly into one of the IO ports on the STK-500. You can check them out from Dr. Margush's office or get one in class.

Return to Dr. Margush's page