Let's look at interfacing a Hex keypad, the one with 16 switches; arranged in 4 columns and 4 rows. The interesting challenge is to interface 16 switches on 8 pins. So how does this work? The simple answer is the MCU is faster than the your fingers.

Basics

Hook Up

Code

  1. #include "keypad.h"
  2. #include "lcd.h"
  3. int main()
  4. {
  5. uint8_t key;
  6.  
  7. /*Connect RS->PB0, RW->PB1, EN->PB2 and data bus PORTB.4 to PORTB.7*/
  8. LCD_SetUp(PB_0,PB_1,PB_2,P_NC,P_NC,P_NC,P_NC,PB_4,PB_5,PB_6,PB_7);
  9. LCD_Init(2,16);
  10.  
  11. /*Connect R1->PD0, R2->PD1, R3->PD2 R4->PD3, C1->PD4, C2->PD5 C3->PD6, C4->PD7 */
  12. KEYPAD_Init(PD_0,PD_1,PD_2,PD_3,PD_4,PD_5,PD_6,PD_7);
  13.  
  14. LCD_Printf("Key Pressed:");
  15. while (1)
  16. {
  17. key = KEYPAD_GetKey();
  18. LCD_GoToLine(1);
  19. LCD_DisplayChar(key);
  20.  
  21. }
  22.  
  23. return (0);
  24. }

Let's look at the most important function in the code in a little more details

  1. key = KEYPAD_GetKey();

As you can guess, the function return the ASCII value of the key being pressed. It follows the following sequences to decode the key pressed:

  1. Wait till the previous key is released.
  2. Wait for the new key press.
  3. Scan all the rows one at a time for the pressed key.
  4. Decodes the key pressed depending on ROW-COL combination and returns its ASCII value.


  1. It is defined in keypad.c as below:
  1. uint8_t KEYPAD_GetKey(void)
  2. {
  3. uint8_t i,j,v_KeyPressed_u8 = 0;
  4.  
  5.  
  6. keypad_WaitForKeyRelease();
  7. keypad_WaitForKeyPress();
  8.  
  9. for (i=0;i<C_MaxRows_U8;i++)
  10. {
  11. GPIO_PinWrite(A_RowsPins_U8[i],HIGH);
  12. }
  13.  
  14. for (i=0;(i<C_MaxRows_U8);i++)
  15. {
  16. GPIO_PinWrite(A_RowsPins_U8[i],LOW);
  17.  
  18. for(j=0; (j<C_MaxCols_U8); j++)
  19. {
  20. if(GPIO_PinRead(A_ColsPins_U8[j]) == 0)
  21. {
  22. v_KeyPressed_u8 = 1;
  23. break;
  24. }
  25. }
  26.  
  27. if(v_KeyPressed_u8 ==1)
  28. {
  29. break;
  30. }
  31.  
  32. GPIO_PinWrite(A_RowsPins_U8[i],HIGH);
  33. }
  34.  
  35. if(i<C_MaxRows_U8)
  36. v_KeyPressed_u8 = A_KeyLookUptable_U8[i][j];
  37. else
  38. v_KeyPressed_u8 = C_DefaultKey_U8;
  39.  
  40.  
  41. return v_KeyPressed_u8;
  42. }