Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Basic concept of keypad

Status
Not open for further replies.

vead

Full Member level 5
Joined
Nov 27, 2011
Messages
285
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,298
Location
india
Activity points
3,815
Hello

I am looking help in programming to interface keypad. I have seen many example on internet. I can't understand. I want that when I press any button on keypad. it should be display on LCD. let's suppose I have matrix keypad 16x2 LCD display and 8051

This is routine to read keypad
Code:
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;
}

Now I want to make routine that will store the number of keypad. Ho to routine that will store the numbers of keypad?
 

The keypad is arranged with the keys in a matrix or rows and columns. Each key is a switch that joins the row to the column where they intersect when it is pressed.

It scans the keypad by outputting one of the rows = 0 while the other three are high and then moves to the next row. So the row signals are:
0111
1011
1101
1110 <- note the '0' changes position each time.

So if one of the keys is pressed, the '0' will be connected to the column 'C' input where if gets found by the 'if(....' statement.
The delay is a crude way of de-bouncing the key by checking it is held down for at least 100mS, after then the 'while(...' statement loops until the key is released.
Depending on which row was '0' and which column detected it, the key can be identified and it's ASCII value returned. If no key is pressed it returns value zero.

Note that it isn't a particularly good way to do it for several reasons:
1. It doesn't return a key value until the key is released, normally you want it when it is pressed.
2. It is a blocking routine, it holds the program when a key is down.
3. Assigning a value to C1,C2, C3 and C4 is meaningless as they need to be inputs from the keypad. (pull-up resistors needed on the C inputs!)
4. It has no way of checking if more than one key is down and unless externally protected it could damage the row output drivers.
5. It can be written more efficiently using an array of look-up values.

Brian.
 
  • Like
Reactions: Garyl and vead

    vead

    Points: 2
    Helpful Answer Positive Rating

    Garyl

    Points: 2
    Helpful Answer Positive Rating
Note that it isn't a particularly good way to do it for several reasons:

Brian.

Thanks for your response. I don't have idea How to do it in best way? It will be appropriate if you can guide me. I am not asking for whole program. My main purpose is to understand keypad reading and storing. I want to understand keypad interfacing program.

array

Code:
unsigned char array [] = {key1, key2, key3,  key4, key5, key6,  key7, key8, key9, key10,  key11, key12, key13, key14, key15, key16};
How to make routine that will read the keypad?
How to make routine that will get number from keypad ?
 
Last edited:

My main purpose is to understand keypad reading and storing. I want to understand keypad interfacing program.
Long story short, the best way is using bitmasking, I mean, operate directly on bits. You know how a single byte (8 bits) descirbes the state of the PORT? You can use that words directly to check the inputs.

Anyway, I'd suggest you reading a tutorial, for instance: https://www.8051projects.net/keypad-interfacing/introduction.php
They have both ASM and C code:
https://www.8051projects.net/keypad-interfacing/avr-programming.php

Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
.include "8515def.inc"
 
.equ col1 = PINA0
.equ col2 = PINA1
.equ col3 = PINA2
.equ col4 = PINA3
 
.def keyval = r16
.def temp = r17
.def flags = r18
 
.equ keyport = PORTA
.equ pressed = 0
 
key_init:
        ldi keyval,$F0          ;Make Cols as i/p
        out DDRA, keyval        ;and Rows as o/p
        ldi keyval,$0F          ;Enable pullups
        out keyport, keyval     ;on columns
        ret
 
get_key:
        ldi keyval,$0           ;Scanning Row1
        ldi temp,$7F            ;Make Row1 low
        out keyport,temp        ;Send to keyport
        rcall read_col          ;Read Columns
 
        sbrc flags,pressed      ;If key pressed
        rjmp done               ;Exit the routine
 
        ldi keyval,$4           ;Scanning Row2
        ldi temp,$BF            ;Make Row2 Low
        out keyport,temp        ;Send to keyport
        rcall read_col          ;Read Columns
 
        sbrc flags,pressed      ;If key pressed
        rjmp done               ;Exit from routine
 
        ldi keyval,$8           ;Scanning Row3
        ldi temp,$DF            ;Make Row3 Low
        out keyport,temp        ;Send to keyport
        rcall read_col          ;Read columns
 
        sbrc flags,pressed      ;If key pressed
        rjmp done               ;Exit the routine
 
        ldi keyval,$C           ;Scanning Row4
        ldi temp,$EF            ;Make Row4 Low
        out keyport,temp        ;send to keyport
        rcall read_col          ;Read columns
 
done:
        ret
 
read_col:
        cbr flags, (1<<pressed) ;Clear status flag
 
        sbic PINA, col1         ;Check COL1
        rjmp nextcol            ;Go to COL2 if not low
 
hold:
        sbis PINA, col1         ;Wait for key release
        rjmp hold
        sbr flags, (1<<pressed) ;Set status flag
        ret                     ;key 1 pressed
nextcol:
        sbic PINA,col2          ;Check COL2
        rjmp nextcol1           ;Goto COL3 if not low
 
hold1:
        sbis PINA, col2         ;Wait for key release
        rjmp hold1
        inc keyval              ;Key 2 pressed
        sbr flags,(1<<pressed)  ;Set status flag
        ret
nextcol1:
        sbic PINA,col3          ;Check COL3
        rjmp nextcol2           ;Goto COL4 if no pressed
 
hold2:
        sbis PINA, col3         ;Wait for key release
        rjmp hold2
        inc keyval              ;Key 3 pressed
        inc keyval
        sbr flags, (1<<pressed) ;Set status flag
        ret
nextcol2:
        sbic PINA,col4          ;Check COL4
        rjmp exit               ;Exit if not low
 
hold3:
        sbis PINA, col4         ;Wait for key release
        rjmp hold3
        inc keyval              ;Key 4 Pressed
        inc keyval
        inc keyval
        sbr flags, (1<<pressed) ;Set status flag
        ret
exit:
        clr keyval              ;reset keyval
        cbr flags, (1<<pressed) ;No Key Pressed
        ret



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <avr/io.h>
        // Include file for AVR
#define keyport PORTA       //Keypad Port
#define keyportddr DDRA     //Data Direction Register
#define keyportpin PINA     //Keypad Port Pins
 
#define col1 PA0        //Column1 PortA.0
#define col2 PA1        //Column2 PortA.1
#define col3 PA2        //Column3 PortA.2
#define col4 PA3        //Column4 PortA.3
 
#define TRUE 1
#define FALSE 0
 
unsigned char keyval;   //A variable
 
/*
+---------------------------------------+
| Prototype: void key_init(void);       |
| Return Type: void                     |
| Arguments: None                       |
| Description: Initialize ports and     |
|              Keypad.                  |
+---------------------------------------+
*/
void key_init(){
    keyportddr = 0xF0;
    keyport = 0x0F;
}
 
/*
+-----------------------------------------------+
| Prototype: unsigned char get_key(void);       |
| Return Type: unsigned char                    |
| Arguments: None                               |
| Description: To read key from the keypad      |
+-----------------------------------------------+
*/
unsigned char get_key(){
    unsigned char i,key=1;
    for(i=0;i<4;i++){       //Loop for 4 rows
        keyport &=~(0x80>
>
i); //Make rows low one by one
            if(!(keyportpin & (1<<col1))){
             //check COL1
                while(!(keyportpin & (1<<col1)));
                //wait for release
                return key;
                //return pressed key value
            }
            if(!(keyportpin & (1<<col2))){
             //Check COL2
                key += 1;
                //Second key pressed
                while(!(keyportpin & (1<<col2)));
                //wait for release
                return key;
                //return key value
            }
            if(!(keyportpin & (1<<col3))){
             //Check COL3
                key += 2;
                //Third key pressed
                while(!(keyportpin & (1<<col3)));
                //Wait for release
                return key;
                //Return value
            }
            if(!(keyportpin & (1<<col4))){
             //check COL4
                key += 3;
                //Fourth key pressed
                while(!(keyportpin & (1<<col4)));
                //Wait for release
                return key;
                //Return key value
            }
        key +=4;    //Next row
        keyport |= 0x80>
>
i;
        //make read row high again
    }
    return FALSE;   //return false if no key pressed
}




Still, at first you must understand how bitwise operators works in C. You must know what &, |=, << are doing. If you don't know thoes operators, you should first read about them and then proceed to keyboard stuff.

PS: I really admire the betwixt's patience to explain stuff to newbies!
 
  • Like
Reactions: vead

    vead

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top