There are various methods to provide an input for the GPIO pins of a microcontroller which can be software controlled or hardware controlled. We have seen a hardware controlled method by taking an input from a switch or a press button. Push Button Interfacing with LPC1768
The keypad is another external input device which is hardware controlled but is used for a specific purpose.
In this tutorial, we take a look at how a 4×4 matrix keypad is interfaced with the LPC1768 microcontroller. The input taken from the matrix keypad will be displayed on a serial monitor via UART communication. UART communication protocol using ARM LPC 1768
NOTE: Please read this section carefully as it is important to understand the hardware connection before writing a software for this application.
- As we are using a 4×4 matrix keypad, a total of 8 input-output pins of the micro-controller will be required for interfacing.
- One-half of the 8 pins will be hardware controlled and the other half will be software controlled.
- From the fig., the blue lines are the columns and the red lines are the rows. Therefore, the columns can be pulled up or pulled down. The rows are the four LSBs of the 8-bit pins and the columns are the MSBs of the 8-bit pins.
(GENERAL CONVENTION: ROWS: Horizontal & COLUMNS: Vertical)
- In our program, the MSBs (columns) will be set in the input mode and the LSB (rows) will be set in the output mode. The default state of the MSB can be HIGH or LOW based on the hardware connection. Based on this we have two modes of operation for the keypad, i.e. Pull Up mode or Pull Down mode (refer the fig.). In the pull-up mode, MSBs (columns) by default will be high and in the pull-down mode, MSBs by default will be low. We will be operating in the Pull Up Mode.
- When a key is pressed, the output and input line or in other words, rows, and columns common to the pressed key will be connected to each other and hence the value on the output line will be reflected on the corresponding input line.
- Without any software change, the columns, which we will be configuring as input pins in the software, will continue to be in the pulled up state. Therefore, when any key is pressed our aim is to cause a deviation from this default state. This change is performed in the software.
- When a software change occurs and a value is written on the output pins (rows), the four rows will reflect the value from the controller. This value gets passed to the corresponding column when the key common to the row and column is pressed. As we are operating in pull upstate, we will continuously send a LOW state to each of the four output pins (rows) keeping all other pins HIGH.
- For every LOW state to each row, we scan for a key press by checking for a LOW state at any of the column pins. This is because, when the rows and columns get connected, the circuit takes the path of least resistance (internal pull up when configured in the input mode is weak) and the LOW state on the row is reflected on the corresponding column, thus deviating from the default state. Based on this change in the state of the signal on the respective input line (column), we can determine the identity of the pressed key.
- These are the definitions that will be used for the keypad programming.
#define KEYPAD_DATA_SET LPC_GPIO1->FIOSET #define KEYPAD_DATA_CLR LPC_GPIO1->FIOCLR #define KEYPAD_DATA_PIN LPC_GPIO1->FIOPIN #define KEYPAD_DATA_DIR LPC_GPIO1->FIODIR #define KEYPAD_D0 24 #define KEYPAD_D1 25 #define KEYPAD_D2 26 #define KEYPAD_D3 27 #define KEYPAD_D4 28 #define KEYPAD_D5 29 #define KEYPAD_D6 30 #define KEYPAD_D7 31 #define KEYPAD_DATA_MASK ((1<<KEYPAD_D0)|(1<<KEYPAD_D1)|(1<<KEYPAD_D2)|(1<<KEYPAD_D3)) //LSBs O/P & MSBs I/P
- Next, we must set the direction of the hardware pins according to its software functionality. As discussed, the LSB (rows) is set in the output mode and the MSB (columns) will be set in the input mode. The KEYPAD_DATA_MASK definition is used to set the pin direction.
- We will be using the UART0 built-in module to display the output of the keypad press. Therefore we must initialize the UART0 communication protocol as well.
- The GetKey() performs a continuous scan and checks for a key press. The design logic is based on the following figure of the keypad connection and the functioning is as follows.
- The ROWS are the LSB pins and the COLUMNS are the MSB pins.
- Since the MSB is hardware controlled (pull up or pull down), these bits on the keypad will only take the logic value set in the hardware (LOGIC HIGH in our case).
- When a key is pressed, the corresponding row and column will be connected.
- We will be writing and shifting LOGIC 0 continuously to row ‘n’ keeping all the other row pins at LOGIC 1. (n: 1-4)
- When a key is pressed and LOGIC 0 appears on the corresponding row pin, LOGIC 0 from the row will be reflected the corresponding column.
- Since the columns are set as input pins in the microcontroller, while reading the values of the rows, if any of the pins are at LOGIC 0, then it is an indication that a key has been pressed. The reading operation is done by readbite() function.
- The readbite() uses a switch to identify the row corresponding to the pressed key. If any of the switch cases is satisfied, then it checks for the column corresponding to the pressed key. If the column reflects a LOGIC 0, then we can determine the value of the pressed key.
- Now, using a while loop, we will wait till the LOGIC 0 disappears so that the software waits till the current state in the hardware is changed. This is done to avoid a hardware debouncing.
- A small delay is also provided in between each column write so that the reading operation does not get skipped.
- Once we have the value of the pressed key, this is displayed on the UART and the software moves onto scan the next key press.
We have designed a program to interface a 4×4 matrix keypad with the LPC1768 microcontroller. The sample code based on this tutorial is available in the Code Library under the ARM.