Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Matrix keypad programming

Status
Not open for further replies.
Like this should work
I don't think you have compiled this code because there are some errors. I have removed some errors
C:
#include <reg51.h>

#include <stdio.h>
sbit row1port = P1^0;
sbit row2port = P1^1;
sbit row3port = P1^2;
sbit  row4port = P1^3;
sbit col1port = P1^4;
sbit col2port = P1^5;
sbit col3port = P1^6;
sbit col4port = P1^7;   // a 4x4 keypad is used
char const keyPadMatrix[] =
{
    '1','2','3','4',
    '5','6','7','8',
    '9','0','A','B',
    'C','D','E','F',
    0xFF
};
void ScanKeyMatrixInit()
{
    // we scan the keypad by turning on the row outputs and
    // reading the columns
   row1port = 0;
   row2port = 0;
   row3port = 0;
   row4port = 0;
   col1port = 1;
   col2port = 1;
   col3port = 1;
   col4port = 1;
}
char ScanKeyMatrix()
{
    // This routine returns the first key found to be
    // pressed during the scan.
    char key = 0, row;
    for( row = 0b00000001; row < 0b00010000; row <<= 1 )
    {     
        {   // turn on row output
            row1port = (row & 0x0001)>>0;
            row2port = (row & 0x0002)>>1;
            row3port = (row & 0x0004)>>2;
            row4port = (row & 0x0008)>>3;
            __delay_ms(1);
        }
     
        // read colums - break when key press detected
        if( col1port )
            break;
        key++;
        if( col2port )
            break;
        key++;
        if( col3port )
            break;
        key++;
        if( col4port )
            break;
        key++;
    }
    row1port = 0;
    row2port = 0;
    row3port = 0;
    row4port = 0;
     
    return keyPadMatrix[ key ];
}
compiling code.c...
code.c(38): error C251: illegal octal digit
code.c(38): error C251: illegal octal digit
code.c - 2 Error(s), 0 Warning(s).
 
Here's my rendition!!!

I have compiled your code there are some errors. I have removed some errors
AT89C51 and keil compiler
C:
#include <reg51.h>
#include <stdio.h>
#define LCDport P1   /* Data pins connected to port P1 */

sbit RS = P3^5;           /* RS pin connected to pin 0 of port P2 */
sbit RW = P3^6;           /* RW pin connected to pin 1 of port P2 */
sbit EN = P3^7;           /* EN pin connected to pin 2 of port P2 */

#define KEYport P0 /* Key pad connected to port P0*/
#define C1  P0^0  /* Col 0 pin connected to pin 0 of port P0*/
#define C2  P0^1  /* Col 1 pin connected to pin 1 of port P0 */
#define C3  P0^2  /* Col 2 pin connected to pin 2 of port P0 */
#define C4  P0^3  /* Col 3 pin connected to pin 3 of port P0 */


 void delayUs(unsigned int wait);
 void delayMs(unsigned int wait);
 void LCD_Command(unsigned char cmd);
 void  putchar(char tx_data);
 /* functions for delay */
 void delayUs(unsigned int wait)
   {
     wait >>= 3;
      while(wait--);
   }
   
 void delayMs(unsigned int wait)
   {
      while(wait--)
      delayUs(1000);
   }
/* Function to send command to LCD */
void LCD_Command(unsigned char cmd)
   {
    LCDport = cmd;
    RS = 0;
    RW = 0;
    EN = 1;
    delayMs(5);
    EN = 0;
   }
   
/*Function to send data to LCD */
void LCD_Data(unsigned char Data)
   {
    LCDport = Data;
    RS = 1;
    RW = 0;
    EN = 1;
    delayMs(5);
    EN = 0;
   }
/* Function to prepare the LCD */
void LCD_init(void)
   {
    delayMs(20);
    LCD_Command(0x33);  // Init 8 it
    delayMs(15);
    LCD_Command(0x38);  // Function set
    delayMs(15);
    LCD_Command(0x0C);  // display on
    delayMs(10);
    LCD_Command(0x06);  // direction
    delayMs(5);
    LCD_Command(0x01);  // home...
    delayMs(5);
   }
   
  /* Function to position cursor on the LCD */
void LCD_goto(int x, int y)
   {
      unsigned char addr = 0x80;      // default line
       if (y ==2 ) addr = 0xC0;  // 2nd line
      if (y ==3 ) addr = 0x90;     // 3rd line
      if (y ==4 ) addr = 0xD0;  // 4th line
      addr+=x;     // Column required
      LCD_Command(addr);
    }
   
  /* Function to print on the LCD */  
 void LCD_print(int x, int y, char* str)
      {
  LCD_goto(x,y);
  while(*str!=0)      // this is a ponter  This means...
     LCD_Data(*str++); // While the character pointed to isn't 0 print to LCD then increment..
      }
   
  /* Function to pset up Uart */     
void UART_Init()
   {
    TMOD = 0x20; /* Timer 1, 8-bit auto reload mode */
    TH1 = 0xFD; /* Load value for 9600 baud rate */
    SCON = 0x50; /* Mode 1, reception enable */
    TR1 = 1;  /* Start timer 1 */
   }
   
  /* Function to send a character */  
void  putchar(char tx_data)
   {
    SBUF = tx_data;  /* Load char in SBUF register */
    while (TI == 0); /* Wait until stop bit transmit */
    TI = 0;    /* Clear TI flag */
   }
   /* Function to fetch a character */  
char getchar(void)
   {
    while(!RI);        // Wait here until SBUF clear
    RI = 0;
    return SBUF;     
    }
   
  /* Function to send a line of characters untill a null*/  
   
char keypad(void)
    {
    unsigned char keymask = 0xEF;
    char key = 0, row;
     char act_key[]  = {0,1,4,7,11,2,5,8,10,3,6,9,12} ;
    for(row=0;row < 4; row++)   
        {
          KEYport = keymask;
          if(!C1) key = 1;
          if(!C2) key = 2;
          if(!C3) key = 3;
          if(!C4) key = 4;
                   if(key)
            {  
              key += (row*4);
              return act_key[key];
            }
                keymask <<= 1;
         keymask ++;   
       }       
    return key;
    }
   
void main(void)
   {
    char  key;  // receive variable
      char buff[20];
    int pos = 0;  // where we are on screen
    UART_Init();        /* UART initialize function */
    LCD_init();  // set up LCD
    puts("Press some keys\n\r");        /* Transmit 'test' */
    while(1)
      {
  key = keypad();
  if (key)
     {
      sprintf(buff,"Key Pressed %d ", key) ;
     LCD_print(0,0,buff);
     }
 }
   }
compiling keypad.c...
keypad.c(19): error C231: '_putchar': redefinition
keypad.c(100): error C231: '_putchar': redefinition
keypad.c(104): error C231: '_putchar': redefinition
keypad.c - 3 Error(s), 0 Warning(s).

How to make this code workable for my chip
 
I've dug out some code from a few years ago that reads a 4x4 keypad and returns the key code. It has key rollover, keydelay before repeating and autorepeat.
It should be called between 20 and 50 times per second - this is important for debounce purposes.
Code:
//assuming the rows are on port bits 4 to 7
//and columns are on 0 to 3 with WPUs on

uint16_t keys,prev,edges;

char ReadKeyPad(){
char i;
rom char KeyPad[16]="580247*169#3ABCD";    //swap around until right depends how keypad is wired
    prev=keys;                        //make a copy of previous value
    for(i=0x80;i>0x08;i>>=1){        //this will loop with i equal to 0x80, 0x40, 0x20 & 0x10.
        keys<<=4;                    //make room for next four keys
        TRISA=255-i;                //make row output
        porta=255-i;                //and make it low
        keys|=(porta&0x0f);            //get the lower 4 bits and move into keys variable
    }
    if(keys==0)                        //if no key pressed
        return(0);                    //return zero
    if(((keys^prev)&prev)==0){        //if it's not a new keypress
        if(--KeyCount!=0)            //must be repeating key
            return(0);                //if keycount <> 0 then return no key
        KeyCount=KeyRepeat;            //else reset repeat and fall through to return key.
    }else{                            //must be new key
        KeyCount=KeyDelay;            //set repeat delay
        edges=((keys^prev)&prev);    //set variable edges to the new key value
    }                                //edges will contain the repeated key pattern or the new one.
    i=0;                            //convert bit pattern to key code.
    while((edges&(1<<i))==0){        //count until first bit set
        i++;
    }
    i=KeyPad[i];                    //convert position to key value
    return i;                        //and return it
}

Mike.
 
Last edited:
Parth86 I don't know witch of us going to learn C me or you LOL The code I posted was the keypress part not a whole code but, My lord
You should look at and see how it works I was from the same compiler you using I got it working on a pic16f15376 .
I just ordered
AT89C51 Got find a compiler for linux LOL

Screenshot from 2018-02-06 00-00-07.png


Going to try Mikes code in post #23 Looks nice


 
I've added comments to the above code to make it easier to follow.

Mike.
 
Parth!! delete all these definitions.... The are conflicting.

void delayUs(unsigned int wait);
void delayMs(unsigned int wait);
void LCD_Command(unsigned char cmd);
void putchar(char tx_data);

if "main" is place last you do not use definitions... ( It's just the way I write C )..

putchar() is already defined elsewhere... It must not be redefined..
 
Parth!! delete all these definitions.... The are conflicting.
I have removed prototype function deceleration
program show only two errors
compiling keypad.c...
keypad.c(96): error C231: '_putchar': redefinition
keypad.c(100): error C231: '_putchar': redefinition
keypad.c - 2 Error(s), 0 Warning(s).

putchar() is already defined elsewhere... It must not be redefined..
I think it's predefine in #include <stdio.h> here
I have notice in main function. you are using puts("Press some keys\n\r"); but you have not declared this outside the main function
 
Have you tested this code. Is it working for you?
Of course... I don't like posting untested code..

Why don't you download SDCC... If you have proteus 8 it integrates with VSM... Seamlessly!! It has auto wizzard to set up simple projects...
 
Of course... I don't like posting untested code..

Why don't you download SDCC... If you have proteus 8 it integrates with VSM... Seamlessly!! It has auto wizzard to set up simple projects...
I have test your code on sdcc it's work fine

you ware using uart but I don't want to use it. I just wrote simple program on kiel and I think it should be work but it's not working
so can you tell me what's the wrong in my program. why it's not working
C:
#include<reg51.h>

#define LCDport P3

sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;

#define KEYport P1
#define C1  P1^0
#define C2  P1^1
#define C3  P1^2
#define C4  P1^3

/* functions for delay */
 void delayUs(unsigned int wait)
   {
     wait >>= 3;
      while(wait--);
   }
 
 void delayMs(unsigned int wait)
   {
      while(wait--)
  delayUs(1000);
   }
/* Function to send command to LCD */
void LCD_Command(unsigned char cmd)
   {
    LCDport = cmd;
    RS = 0;
    RW = 0;
    EN = 1;
    delayMs(5);
    EN = 0;
   }
 
/*Function to send data to LCD */

    void LCD_Data(unsigned char dat)
   {
    LCDport = dat;
    RS = 1;
    RW = 0;
    EN = 1;
    delayMs(5);
    EN = 0;
   }
/* Function to prepare the LCD */
void LCD_init(void)
   {
    delayMs(20);
    LCD_Command(0x33);  // Init 8 it
    delayMs(15);
    LCD_Command(0x38);  // Function set
    delayMs(15);
    LCD_Command(0x0C);  // display on
    delayMs(10);
    LCD_Command(0x06);  // direction
    delayMs(5);
    LCD_Command(0x01);  // home...
    delayMs(5);
   }
 
    void LCD_goto( char x, char y)
   {
   int addr = 0x80;   // start address
   if(y==2) addr+=0x40;  // are we on second row
   addr += x;    // add in the columns
   LCD_Command(addr);   // send to display.
   }
 
    char keypad(void)
    {
       unsigned char keymask = 0xEF;
       char key = 0, row;
       char act_key[]  = {0,1,4,7,11,2,5,8,10,3,6,9,12} ;
       for(row=0;row < 4; row++)
        {
          KEYport = keymask;
          if(!C1) key = 1;
          if(!C2) key = 2;
          if(!C3) key = 3;
          if(!C4) key = 4;
                   if(key)
            {
              key += (row*4);
              return act_key[key];
            }
                keymask <<= 1;
         keymask ++;
       }   
    return key;
    }
   
void main(void)
   {
    char  ke;
    LCD_init();  // set up LCD
 
    while(1)
      {
           key = keypad();
     
            LCD_goto(3,1);
           LCD_Data(key);       
      }
   }
I am just trying to display only one key
get the key
set cursor position
print the key
 
Last edited:
It will not compile as key is not defined... you missed the 'y' of the definition..
My bad I have corrected it. but still program doesn't show key on screen, Do I need to make any other function.

I just want to see one key on screen and I think program should be work because I am following all the basic thing that I know so what's the missing here
 
I am also getting same result with same code

Now I am thinking to use sdcc . I think its time for programming.
Yes.... key is a number 0 ~ 12... to see it you need to convert to ascii... ie add 48 to key..

LCD_Data(key+48);
but this function return char
C:
char keypad(void)
    {
        return key;
    }

How to print the key shown into keypad
 

Attachments

  • keypad.jpg
    keypad.jpg
    238.9 KB · Views: 183
Last edited:
'-' ,'=' ,'+', so on. Don't something like that work after all he is using C
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top