keypad interfacing using 8051

Discussion in 'Embedded Systems and Microcontrollers' started by Parth786, Jul 10, 2017.

  1. Parth786

    Thread Starter Active Member

    Jun 19, 2017
    642
    45
    I am trying to write program for simple calculator. actually I wanted to understand interfacing of keypad with micro controller. so I decided to make small calculator I have keypad, 8051 and LCD. Previously I have been written C program for LCD Display. I am having problem to write code for keypad. This is hardware design
    upload_2017-7-10_15-28-38.png

    I have been gone throw some tutorials and visited on some web sites but I am having difficulty to write program. can any one tell me what I have to write in program to make calculator.
    Here is my small effort
    Program code:
    Code (C):
    1. #include<reg51.h>
    2.  
    3. /*LCD Module Connections */
    4. #define port P1          
    5. sbit RS = P0^0;        
    6. sbit RW = P0^1;          
    7. sbit EN = P0^2;          
    8.  
    9. /* Keypad Connections */
    10. sbit R1 = P1^0;
    11. sbit R2 = P1^1;
    12. sbit R3 = P1^2;
    13. sbit R4 = P1^3;
    14. sbit C1 = P1^4;
    15. sbit C2 = P1^5;
    16. sbit C3 = P1^6;
    17. sbit C4 = P1^7;
    18.  
    19. /* function for delay */
    20. void Delay(unsigned int time)
    21. {
    22.     unsigned i,j ;
    23.     for(i=0;i<time;i++)
    24.     for(j=0;j<1275;j++);
    25. }
    26. /* Function to send command to LCD */
    27. void LCD_Command(unsigned char cmd)
    28. {
    29.     port = cmd;
    30.     RS=0;
    31.     RW=0;
    32.     EN=1;
    33.     Delay(2);
    34.     EN=0;
    35. }
    36. /*Function to send message on  LCD */
    37. void LCD_Data(unsigned char Data)
    38. {
    39.     port = Data;
    40.     RS=1;
    41.     RW=0;
    42.     EN=1;
    43.     Delay(2);
    44.     EN=0;
    45. }
    46.  
    47. /* Function to prepare the LCD */
    48. void LCD_init()
    49. {
    50.     LCD_Command(0x38);
    51.     Delay(20);
    52.     LCD_Command(0x0f);
    53.     Delay(20);
    54.     LCD_Command(0x01);
    55.     Delay(20);
    56.     LCD_Command(0x81);
    57.     Delay(20);
    58. }
    59.  
    60. char Read_Keypad()
    61. {
    62.   C1=1;
    63.   C2=1;
    64.   C3=1;
    65.   C4=1;
    66.   R1=0;
    67.   R2=1;
    68.   R3=1;
    69.   R4=1;
    70.   if(C1==0){Delay(100);while(C1==0);return '7';}
    71.   if(C2==0){Delay(100);while(C2==0);return '8';}
    72.   if(C3==0){Delay(100);while(C3==0);return '9';}
    73.   if(C4==0){Delay(100);while(C4==0);return '/';}
    74.   R1=1;
    75.   R2=0;
    76.   R3=1;
    77.   R4=1;
    78.   if(C1==0){Delay(100);while(C1==0);return '4';}
    79.   if(C2==0){Delay(100);while(C2==0);return '5';}
    80.   if(C3==0){Delay(100);while(C3==0);return '6';}
    81.   if(C4==0){Delay(100);while(C4==0);return 'X';}
    82.   R1=1;
    83.   R2=1;
    84.   R3=0;
    85.   R4=1;
    86.   if(C1==0){Delay(100);while(C1==0);return '1';}
    87.   if(C2==0){Delay(100);while(C2==0);return '2';}
    88.   if(C3==0){Delay(100);while(C3==0);return '3';}
    89.   if(C4==0){Delay(100);while(C4==0);return '-';}
    90.   R1=1;
    91.   R2=1;
    92.   R3=1;
    93.   R4=0;
    94.   if(C1==0){Delay(100);while(C1==0);return 'C';}
    95.   if(C2==0){Delay(100);while(C2==0);return '0';}
    96.   if(C3==0){Delay(100);while(C3==0);return '=';}
    97.   if(C4==0){Delay(100);while(C4==0);return '+';}
    98.   return 0;
    99. }
    100.  
    101. void main()
    102. {
    103.   while(1)
    104.   {
    105.      
    106.   }
    107. }
    108.  
     
    Last edited by a moderator: Oct 30, 2017
  2. JohnInTX

    Moderator

    Jun 26, 2012
    3,768
    1,982
    Well, without going too deeply into it I do observe that you aren't calling your keyboard routine. That's going to make further discussion kind of moot.

    If you are going to be a stud about this, you might consider scanning the keyboard using a timer interrupt, keeping track of its state and emitting scan codes when you have qualified a key. At the very least, your main routine needs to call the keyboard routine until it returns a keypress code, process it and repeat.
     
  3. MrChips

    Moderator

    Oct 2, 2009
    19,129
    6,148
    My guess is Parth was hoping you would fill in the while(1) loop for him.
     
  4. JohnInTX

    Moderator

    Jun 26, 2012
    3,768
    1,982
    After today, way more effort than I could muster :rolleyes:
    EDIT: @Parth786 that's a little moderator humor... carry on.
     
    Last edited: Jul 10, 2017
  5. Parth786

    Thread Starter Active Member

    Jun 19, 2017
    642
    45
    No sir, I want to learn because my interest is in automatic project development. if you will do my work than how I will learn? have you read any line in my post where I demand to complete my work. I just look advice. my aim is to learn simple thing so after that I can try to attempt more difficult things
    I appreciate your work. I am just researching some information. the information that you provide is not sufficient for me at this level. this is my fault. I will come back with some preparations
     
    Last edited: Jul 11, 2017
    JohnInTX likes this.
  6. MrChips

    Moderator

    Oct 2, 2009
    19,129
    6,148
    As I said.
     
    Parth786 likes this.
  7. Papabravo

    Expert

    Feb 24, 2006
    12,284
    2,723
    The trick to a matrix keyboard on the 8051 is that all PORT Inputs have weak pullups on them. In the schematic you have four outputs which drive the rows and you start with all outputs high or '1'. The four inputs connected to the columns are all pulled high and if no switches are depressed then all four inputs are high. Now in a repetitive process you take one of the row outputs low. If no keys in that row are depressed the four inputs are still high. If any key in the row is depressed, the row output will pull the column input low. When you see that you determine which key is down and process it. Then you move on to the next row. You can do this in a loop, or with a timer interrupts or several other ways.

    In order to write algorithms you have to understand the mechanics and physics of your peripheral devices.
     
  8. Parth786

    Thread Starter Active Member

    Jun 19, 2017
    642
    45
    I am really happy with your reply. Yes I understand the working of matrix keypad. The main problem is implementing program
    This is main point where I am stuck. I want to use loop that's why a while loop is mention in my module.
    like this type
    Code (Text):
    1. main program start
    2. {
    3. start LCD
    4. read data from keypad
    5. identify which key is pressed
    6. if any key is pressed then display on LCD
    7. do arithmetic operation
    8. display result on LCD
    9. }
    I know this does not make any sense but for beginner its help me lot. I was not asking for complete code. just looking some small steps. I understand loop in c but I don't understand how to use loop in this program?
     
  9. MrChips

    Moderator

    Oct 2, 2009
    19,129
    6,148
    What is the purpose of a loop in a program?

    A loop is when you want to do something repeatedly.
    Decide what you want executed once and what you want execute many times (infinitely).

    Then your main program should look like this:

    Code (Text):
    1. main program
    2. {
    3.   startup
    4.   while (1)
    5.     {
    6.       do this infinitely, forever
    7.     }
    8. }
     
    Parth786 likes this.
  10. Papabravo

    Expert

    Feb 24, 2006
    12,284
    2,723
    Code (Text):
    1.  
    2.   P1.0 = 0 ;
    3.   key = P1 ;
    4.   key = key & 0xF0 ;
    5.   if (key == 0x70) char = DIVIDE) ;
    6.   else if (key == 0xB0) char = '9' ;
    7.   else if(key == 0xD0) char = '8' ;
    8.   else if(key == 0xE0) char = '7' ;
    9.   else
    10.   {
    11.      P1.0 = 1 : P1.1 = 0 ;
    12.      key = P1 ;
    13.      key = key & 0xF0 ;
    14.      if(key == 0x70) char = TIMES ;
    15.      else if (key == 0xB0) char = '6' ;
    16.      else if(key == 0xD0) char = '5' ;
    17.      else if(key == 0xE0) char = '4' ;
    18.      else
    19.     {
    20.         P1.1 = 1 ; P1.2= 0;
    21.         key = P1 ;
    22.         key = key & 0xF0 ;
    23.         if(key == 0x70) char = MINUS ;
    24.         else if (key == 0xB0) char = '3' ;
    25.         else if(key == 0xD0) char = '3' ;
    26.         else if(key == 0xE0) char = '1' ;
    27.        else
    28.       {
    29.          P1.2=1 ; P1.3 = 0;
    30.          key = P1 ;
    31.          key = key & 0xF0 ;
    32.          if(key == 0x70) char = PLUS ;
    33.          else if (key == 0xB0) char = '=' ;
    34.          else if(key == 0xD0) char = '0' ;
    35.         else if(key == 0xE0) char = CLEAR_ON ;
    36.         else ; // No keys pressed
    37.       }
    38.     }
    39. }
    40.  
    This is not the best code I've ever written, but at least it is explicit. The most obvious flaw is that the switch closures are not debounced.
     
  11. Parth786

    Thread Starter Active Member

    Jun 19, 2017
    642
    45
    I made the flow chart its does not exactly match with my requirement but it give some idea. still have lot of confusion on program site. there are many issues if possible can someone help to solve problem one by one. at least suggest some points so that I can try fix them
     
    Last edited: Jan 29, 2018
  12. MrChips

    Moderator

    Oct 2, 2009
    19,129
    6,148
    Your flow chart is incomplete.
    Every process box (rectangle box) has to continue to somewhere.
    Every decision box (diamond shaped box) has two and only two logical outcomes, TRUE or FALSE. There must be two and only two exit paths.
     
    Parth786 likes this.
  13. Parth786

    Thread Starter Active Member

    Jun 19, 2017
    642
    45
    I am just focusing to develop keypad scanning routine. I can make routine to scan four button's
    Code (C):
    1. /* check any button pressed and return key number */
    2.   unsigned char Button(void)
    3.   {
    4.      unsigned char Key_Number;
    5.  
    6.      Key_Number = 0;   // key number in case none are pressed!!
    7.        
    8.          if(!Button1) {     // check if button 1 is pressed
    9.  
    10.                Key_Number = '1';  //return key number '1'
    11.               }
    12.  
    13.          if(!Button2) {       // check if button 2 is pressed
    14.  
    15.               Key_Number = '2';   //return key number '2'
    16.               }
    17.  
    18.          if(!Button3) {       // check if button 3 is pressed
    19.  
    20.               Key_Number = '3';    //return key number '3'
    21.               }
    22.    
    23.          if(!Button4) {       // check if button 4 is pressed
    24.  
    25.               Key_Number = '4';     //return key number '4'
    26.     }
    27.  
    28.     Delay (19000);
    29.  
    30.     return Key_Number;  // 0 if no key pressed
    31.   }
    This is logic table of keypad
    upload_2018-1-29_11-51-24.png
    I understand the logic of keypad matrix but I am having problem to implement in programming. even I am unable to draw flow chart for program.

    I am just focusing to develop keypad reading function. I tried to make my own keypad reading routine. I know this routine is not complete, there I need to write some logic but I don't understand how to go for further steps
    Code (C):
    1. /* keypad reading function*/
    2.   unsigned char keypad_reading(void)
    3.   {
    4.      unsigned char row;
    5.  
    6.      unsigned char Key_Number = 0;   // key number in case none are pressed!!
    7.  
    8.      for(row = 0;row<4;row++)   // Loop for Four rows
    9.      {
    10.          if(!column1) {
    11.  
    12.              Key_Number = ' ';
    13.           }
    14.  
    15.          if(!column2) {
    16.  
    17.              Key_Number = ' ';
    18.           }
    19.  
    20.          if(!column3) {
    21.  
    22.              Key_Number = ' ';
    23.           }
    24.          if(!column4) {       //
    25.  
    26.              Key_Number = ' ';     //return key number
    27.           }
    28.  
    29.           Delay (19000);
    30.     return Key_Number;  // 0 if no key pressed
    31.   }
    32.  
     
    Last edited: Jan 29, 2018
  14. be80be

    AAC Fanatic!

    Jul 5, 2008
    1,900
    394
    Code (Text):
    1. /* Routine to scan the key pressed */
    2. unsigned char key_scan()
    3. {
    4.        unsigned char i, j, temp1, temp2;
    5.  
    6.         while( 1 ) /* keep waiting for a key to be pressed */
    7.  
    8.                 for(i=0; i<4; i++) {
    9.  
    10.                         /* Set each row to 0 */
    11.                         P1 = 0xff & ~(1<<i);
    12.  
    13.                         /* Scan each column to see which key was pressed */
    14.                         for (j=4; j<8; j++) {
    15.  
    16.                               /* Code to determine the position of the
    17.                                  key which was pressed */
    18.                               /* return(position) */
    19.                         }
    20.                 }
    21. }
    like that
     
  15. be80be

    AAC Fanatic!

    Jul 5, 2008
    1,900
    394
    Almost like yours
    Code (Text):
    1. #include<reg52.h> //including sfr registers for ports of the controller
    2. #include<lcd.h>
    3.  
    4. //LCD Module Connections
    5. sbit RS = P0^0;
    6. sbit EN = P0^1;
    7. sbit D0 = P2^0;
    8. sbit D1 = P2^1;
    9. sbit D2 = P2^2;
    10. sbit D3 = P2^3;
    11. sbit D4 = P2^4;
    12. sbit D5 = P2^5;
    13. sbit D6 = P2^6;
    14. sbit D7 = P2^7;
    15. //End LCD Module Connections
    16.  
    17. //Keypad Connections
    18. sbit R1 = P1^0;
    19. sbit R2 = P1^1;
    20. sbit R3 = P1^2;
    21. sbit R4 = P1^3;
    22. sbit C1 = P1^4;
    23. sbit C2 = P1^5;
    24. sbit C3 = P1^6;
    25. sbit C4 = P1^7;
    26. //End Keypad Connections
    27.  
    28. void Delay(int a)
    29. {
    30.   int j;
    31.   int i;
    32.   for(i=0;i<a;i++)
    33.   {
    34.     for(j=0;j<100;j++)
    35.     {
    36.     }
    37.   }
    38. }
    39.  
    40. char Read_Keypad()
    41. {
    42.   C1=1;
    43.   C2=1;
    44.   C3=1;
    45.   C4=1;
    46.   R1=0;
    47.   R2=1;
    48.   R3=1;
    49.   R4=1;
    50.   if(C1==0){Delay(100);while(C1==0);return '7';}
    51.   if(C2==0){Delay(100);while(C2==0);return '8';}
    52.   if(C3==0){Delay(100);while(C3==0);return '9';}
    53.   if(C4==0){Delay(100);while(C4==0);return '/';}
    54.   R1=1;
    55.   R2=0;
    56.   R3=1;
    57.   R4=1;
    58.   if(C1==0){Delay(100);while(C1==0);return '4';}
    59.   if(C2==0){Delay(100);while(C2==0);return '5';}
    60.   if(C3==0){Delay(100);while(C3==0);return '6';}
    61.   if(C4==0){Delay(100);while(C4==0);return 'X';}
    62.   R1=1;
    63.   R2=1;
    64.   R3=0;
    65.   R4=1;
    66.   if(C1==0){Delay(100);while(C1==0);return '1';}
    67.   if(C2==0){Delay(100);while(C2==0);return '2';}
    68.   if(C3==0){Delay(100);while(C3==0);return '3';}
    69.   if(C4==0){Delay(100);while(C4==0);return '-';}
    70.   R1=1;
    71.   R2=1;
    72.   R3=1;
    73.   R4=0;
    74.   if(C1==0){Delay(100);while(C1==0);return 'C';}
    75.   if(C2==0){Delay(100);while(C2==0);return '0';}
    76.   if(C3==0){Delay(100);while(C3==0);return '=';}
    77.   if(C4==0){Delay(100);while(C4==0);return '+';}
    78.   return 0;
    79. }
    80.  
    81. void main()
    82. {
    83.   int i=0;
    84.   char c,p;
    85.   Lcd8_Init();
    86.   while(1)
    87.   {
    88.     Lcd8_Set_Cursor(1,1);
    89.     Lcd8_Write_String("Keys Pressed:");
    90.     Lcd8_Set_Cursor(2,1);
    91.     Lcd8_Write_String("Times:");
    92.     while(!(c = Read_Keypad()));
    93.     p=c;
    94.     while(p==c)
    95.     {
    96.       i++;
    97.       Lcd8_Set_Cursor(1,14);
    98.       Lcd8_Write_Char(c);
    99.       Lcd8_Set_Cursor(2,7);
    100.       Lcd8_Write_Char(i+48);
    101.       Delay(100);
    102.       while(!(c = Read_Keypad()));
    103.     }
    104.     i=0;
    105.     Lcd8_Clear();
    106.   }
    107. }
    [​IMG]
     
  16. Parth786

    Thread Starter Active Member

    Jun 19, 2017
    642
    45
    Thanks for responding

    Code (C):
    1.  /* Scan each column to see which key was pressed */
    2.                         for (j=4; j<8; j++) {
    3.  
    4.                               /* Code to determine the position of the
    5.                                  key which was pressed */
    6.                               /* return(position) */
    7.                         }
    What are you storing in variables temp1, temp2; what's happening inside for loop

    I saw your code in post #15 expert suggeste me that this is not good way for keypad reading
     
  17. simozz

    Member

    Jul 23, 2017
    102
    27
    If this is the micro you are using, my suggestion is tu use a one that has more external interrupts on GPIOs. As I can see, this micro has only two GPIO interrupt sources.
    With at least 4 GPIO interrupts available, you don't need any for loop... Just a couple of bitwise ANDs in your ISR...
     
  18. Parth786

    Thread Starter Active Member

    Jun 19, 2017
    642
    45
    Thank's for your advice but I have only worked on this microcontroller. I don't want to use interrupt now, I will do it later.

    Now I just want to make routine for keypad reading.
     
  19. simozz

    Member

    Jul 23, 2017
    102
    27
    Well, polling inputs is not the way to work...
     
  20. be80be

    AAC Fanatic!

    Jul 5, 2008
    1,900
    394
    This is the problem today some uC that are used don't have interrupt. And i'm sure that's why Parth want's to learn how without them.

    Here is nothing wrong with good code.
     
    Parth786 likes this.
Loading...