keypad interfacing using 8051

Thread Starter

Parth786

Joined Jun 19, 2017
642
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:
C:
#include<reg51.h>

/*LCD Module Connections */
#define port P1          
sbit RS = P0^0;         
sbit RW = P0^1;           
sbit EN = P0^2;           

/* Keypad Connections */
sbit R1 = P1^0;
sbit R2 = P1^1;
sbit R3 = P1^2;
sbit R4 = P1^3;
sbit C1 = P1^4;
sbit C2 = P1^5;
sbit C3 = P1^6;
sbit C4 = P1^7;

/* function for delay */
void Delay(unsigned int time)
{
    unsigned i,j ;
    for(i=0;i<time;i++) 
    for(j=0;j<1275;j++);
}
/* Function to send command to LCD */
void LCD_Command(unsigned char cmd)
{
    port = cmd;
    RS=0;
    RW=0;
    EN=1;
    Delay(2);
    EN=0;
}
/*Function to send message on  LCD */
void LCD_Data(unsigned char Data)
{
    port = Data;
    RS=1;
    RW=0;
    EN=1;
    Delay(2);
    EN=0;
}

/* Function to prepare the LCD */
void LCD_init()
{
    LCD_Command(0x38);
    Delay(20);
    LCD_Command(0x0f);
    Delay(20);
    LCD_Command(0x01);
    Delay(20);
    LCD_Command(0x81);
    Delay(20);
}

char Read_Keypad()
{
  C1=1;
  C2=1;
  C3=1;
  C4=1;
  R1=0;
  R2=1;
  R3=1;
  R4=1;
  if(C1==0){Delay(100);while(C1==0);return '7';}
  if(C2==0){Delay(100);while(C2==0);return '8';}
  if(C3==0){Delay(100);while(C3==0);return '9';}
  if(C4==0){Delay(100);while(C4==0);return '/';}
  R1=1;
  R2=0;
  R3=1;
  R4=1;
  if(C1==0){Delay(100);while(C1==0);return '4';}
  if(C2==0){Delay(100);while(C2==0);return '5';}
  if(C3==0){Delay(100);while(C3==0);return '6';}
  if(C4==0){Delay(100);while(C4==0);return 'X';}
  R1=1;
  R2=1;
  R3=0;
  R4=1;
  if(C1==0){Delay(100);while(C1==0);return '1';}
  if(C2==0){Delay(100);while(C2==0);return '2';}
  if(C3==0){Delay(100);while(C3==0);return '3';}
  if(C4==0){Delay(100);while(C4==0);return '-';}
  R1=1;
  R2=1;
  R3=1;
  R4=0;
  if(C1==0){Delay(100);while(C1==0);return 'C';}
  if(C2==0){Delay(100);while(C2==0);return '0';}
  if(C3==0){Delay(100);while(C3==0);return '=';}
  if(C4==0){Delay(100);while(C4==0);return '+';}
  return 0;
}

void main()
{
  while(1)
  {
      
  }
}
 
Last edited by a moderator:

JohnInTX

Joined Jun 26, 2012
4,787
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.
 

Thread Starter

Parth786

Joined Jun 19, 2017
642
My guess is Parth was hoping you would fill in the while(1) loop for him.
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
After today, way more effort than I could muster :rolleyes:
EDIT: @Parth786 that's a little moderator humor... carry on.
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:

Papabravo

Joined Feb 24, 2006
21,159
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.
 

Thread Starter

Parth786

Joined Jun 19, 2017
642
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. .
I am really happy with your reply. Yes I understand the working of matrix keypad. The main problem is implementing program
. You can do this in a loop, or with a timer interrupts or several other ways.
.
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:
main program start
{
start LCD
read data from keypad
identify which key is pressed
if any key is pressed then display on LCD
do arithmetic operation
display result on LCD
}
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?
 

MrChips

Joined Oct 2, 2009
30,708
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:
main program
{
  startup
  while (1)
    {
      do this infinitely, forever
    }
}
 

Papabravo

Joined Feb 24, 2006
21,159
Code:
  P1.0 = 0 ;
  key = P1 ;
  key = key & 0xF0 ;
  if (key == 0x70) char = DIVIDE) ;
  else if (key == 0xB0) char = '9' ;
  else if(key == 0xD0) char = '8' ;
  else if(key == 0xE0) char = '7' ;
  else
  {
     P1.0 = 1 : P1.1 = 0 ;
     key = P1 ;
     key = key & 0xF0 ;
     if(key == 0x70) char = TIMES ;
     else if (key == 0xB0) char = '6' ;
     else if(key == 0xD0) char = '5' ;
     else if(key == 0xE0) char = '4' ;
     else
    {
        P1.1 = 1 ; P1.2= 0;
        key = P1 ;
        key = key & 0xF0 ;
        if(key == 0x70) char = MINUS ;
        else if (key == 0xB0) char = '3' ;
        else if(key == 0xD0) char = '3' ;
        else if(key == 0xE0) char = '1' ;
       else
      {
         P1.2=1 ; P1.3 = 0;
         key = P1 ;
         key = key & 0xF0 ;
         if(key == 0x70) char = PLUS ;
         else if (key == 0xB0) char = '=' ;
         else if(key == 0xD0) char = '0' ;
        else if(key == 0xE0) char = CLEAR_ON ;
        else ; // No keys pressed
      }
    }
}
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.
 

Thread Starter

Parth786

Joined Jun 19, 2017
642
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
 

Attachments

Last edited:

MrChips

Joined Oct 2, 2009
30,708
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.
 

Thread Starter

Parth786

Joined Jun 19, 2017
642
I am just focusing to develop keypad scanning routine. I can make routine to scan four button's
C:
/* check any button pressed and return key number */
  unsigned char Button(void)
  {
     unsigned char Key_Number;

     Key_Number = 0;   // key number in case none are pressed!!
        
         if(!Button1) {     // check if button 1 is pressed

               Key_Number = '1';  //return key number '1'
              }

         if(!Button2) {       // check if button 2 is pressed

              Key_Number = '2';   //return key number '2'
              }

         if(!Button3) {       // check if button 3 is pressed

              Key_Number = '3';    //return key number '3'
              }
   
         if(!Button4) {       // check if button 4 is pressed

              Key_Number = '4';     //return key number '4'
    }

    Delay (19000);

    return Key_Number;  // 0 if no key pressed
  }
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
C:
/* keypad reading function*/
  unsigned char keypad_reading(void)
  {
     unsigned char row;

     unsigned char Key_Number = 0;   // key number in case none are pressed!!

     for(row = 0;row<4;row++)   // Loop for Four rows
     {
         if(!column1) {

             Key_Number = ' ';
          }

         if(!column2) {

             Key_Number = ' ';
          }

         if(!column3) {

             Key_Number = ' ';
          }
         if(!column4) {       //

             Key_Number = ' ';     //return key number
          }

          Delay (19000);
    return Key_Number;  // 0 if no key pressed
  }
 
Last edited:

be80be

Joined Jul 5, 2008
2,072
Code:
/* Routine to scan the key pressed */
unsigned char key_scan()
{
       unsigned char i, j, temp1, temp2;

        while( 1 ) /* keep waiting for a key to be pressed */

                for(i=0; i<4; i++) {

                        /* Set each row to 0 */
                        P1 = 0xff & ~(1<<i);

                        /* Scan each column to see which key was pressed */
                        for (j=4; j<8; j++) {

                              /* Code to determine the position of the
                                 key which was pressed */
                              /* return(position) */
                        }
                }
}
like that
 

be80be

Joined Jul 5, 2008
2,072
Almost like yours
Code:
#include<reg52.h> //including sfr registers for ports of the controller
#include<lcd.h>

//LCD Module Connections
sbit RS = P0^0;
sbit EN = P0^1;
sbit D0 = P2^0;
sbit D1 = P2^1;
sbit D2 = P2^2;
sbit D3 = P2^3;
sbit D4 = P2^4;
sbit D5 = P2^5;
sbit D6 = P2^6;
sbit D7 = P2^7;
//End LCD Module Connections

//Keypad Connections
sbit R1 = P1^0;
sbit R2 = P1^1;
sbit R3 = P1^2;
sbit R4 = P1^3;
sbit C1 = P1^4;
sbit C2 = P1^5;
sbit C3 = P1^6;
sbit C4 = P1^7;
//End Keypad Connections

void Delay(int a)
{
  int j;
  int i;
  for(i=0;i<a;i++)
  {
    for(j=0;j<100;j++)
    {
    }
  }
}

char Read_Keypad()
{
  C1=1;
  C2=1;
  C3=1;
  C4=1;
  R1=0;
  R2=1;
  R3=1;
  R4=1;
  if(C1==0){Delay(100);while(C1==0);return '7';}
  if(C2==0){Delay(100);while(C2==0);return '8';}
  if(C3==0){Delay(100);while(C3==0);return '9';}
  if(C4==0){Delay(100);while(C4==0);return '/';}
  R1=1;
  R2=0;
  R3=1;
  R4=1;
  if(C1==0){Delay(100);while(C1==0);return '4';}
  if(C2==0){Delay(100);while(C2==0);return '5';}
  if(C3==0){Delay(100);while(C3==0);return '6';}
  if(C4==0){Delay(100);while(C4==0);return 'X';}
  R1=1;
  R2=1;
  R3=0;
  R4=1;
  if(C1==0){Delay(100);while(C1==0);return '1';}
  if(C2==0){Delay(100);while(C2==0);return '2';}
  if(C3==0){Delay(100);while(C3==0);return '3';}
  if(C4==0){Delay(100);while(C4==0);return '-';}
  R1=1;
  R2=1;
  R3=1;
  R4=0;
  if(C1==0){Delay(100);while(C1==0);return 'C';}
  if(C2==0){Delay(100);while(C2==0);return '0';}
  if(C3==0){Delay(100);while(C3==0);return '=';}
  if(C4==0){Delay(100);while(C4==0);return '+';}
  return 0;
}

void main()
{
  int i=0;
  char c,p;
  Lcd8_Init();
  while(1)
  {
    Lcd8_Set_Cursor(1,1);
    Lcd8_Write_String("Keys Pressed:");
    Lcd8_Set_Cursor(2,1);
    Lcd8_Write_String("Times:");
    while(!(c = Read_Keypad()));
    p=c;
    while(p==c)
    {
      i++;
      Lcd8_Set_Cursor(1,14);
      Lcd8_Write_Char(c);
      Lcd8_Set_Cursor(2,7);
      Lcd8_Write_Char(i+48);
      Delay(100);
      while(!(c = Read_Keypad()));
    }
    i=0;
    Lcd8_Clear();
  }
}
 

Thread Starter

Parth786

Joined Jun 19, 2017
642
Code:
/* Routine to scan the key pressed */
unsigned char key_scan()
{
       unsigned char i, j, temp1, temp2;

        while( 1 ) /* keep waiting for a key to be pressed */

                for(i=0; i<4; i++) {

                        /* Set each row to 0 */
                        P1 = 0xff & ~(1<<i);

                        /* Scan each column to see which key was pressed */
                        for (j=4; j<8; j++) {

                              /* Code to determine the position of the
                                 key which was pressed */
                              /* return(position) */
            }
like that
Thanks for responding

C:
 /* Scan each column to see which key was pressed */
                        for (j=4; j<8; j++) {

                              /* Code to determine the position of the
                                 key which was pressed */
                              /* return(position) */
                        }
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
 

simozz

Joined Jul 23, 2017
125
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...
 

Thread Starter

Parth786

Joined Jun 19, 2017
642
If this is the micro you are using, my suggestion is tu use a one that has more external interrupts on GPIOs.
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.
 

be80be

Joined Jul 5, 2008
2,072
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.
 
Top