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.

keypad interfacing with 8051?

Status
Not open for further replies.

jidan

Member
I want write assembly code to display letters or number with keypad Keypad is use to take input like letters or number , and LCD is used to output to display the letters or number
how to write code?
this code is LCD display
Code:
     ORG 0H
MOV A,#38H ;INIT. LCD 2 LINES, 5X7 MATRIX
ACALL COMNWRT ;call command subroutine
ACALL DELAY ;give LCD some time
MOV A,#0EH ;display on, cursor on
ACALL COMNWRT ;call command subroutine
ACALL DELAY ;give LCD some time
MOV A,#01 ;clear LCD
ACALL COMNWRT ;call command subroutine
ACALL DELAY ;give LCD some time
MOV A,#06H ;shift cursor right
ACALL COMNWRT ;call command subroutine
ACALL DELAY ;give LCD some time
MOV A,#84H ;cursor at line 1, pos. 4
ACALL COMNWRT ;call command subroutine
ACALL DELAY
MOV A,#18H
ACALL COMNWRT
ACALL DELAY ;give LCD some time
MOV A,#'J' ;display letter J
ACALL DATAWRT ;call display subroutine
ACALL DELAY ;give LCD some time
MOV A,#'D' ;display letter D
ACALL DATAWRT ;call display subroutine
AGAIN: SJMP AGAIN ;stay here
COMNWRT: ;send command to LCD
MOV P1,A ;copy reg A to port 1
CLR P2.0 ;RS=0 for command
CLR P2.1 ;R/W=0 for write
SETB P2.2 ;E=1 for high pulse
ACALL DELAY ;give LCD some time
CLR P2.2 ;E=0 for H-to-L pulse
RET
DATAWRT: ;write data to LCD
MOV P1,A ;copy reg A to port 1
SETB P2.0 ;RS=1 for data
CLR P2.1 ;R/W=0 for write
SETB P2.2 ;E=1 for high pulse
ACALL DELAY ;give LCD some time
CLR P2.2 ;E=0 for H-to-L pulse
RET
DELAY: MOV R3,#50 ;50 or higher for fast CPUs
HERE2: MOV R4,#255 ;R4 = 255
HERE: DJNZ R4,HERE ;stay until R4 becomes 0
DJNZ R3,HERE2
RET
END
 
You first read the pins to see if a key has been pressed
Allow a debounce time (100mS+)

Convert the number of the keypress to ascii to display it.
you mean this type
Code:
ORG 00H
MOV DPTR,#LUT // moves starting address of LUT to DPTR
MOV A,#11111111B // loads A with all 1's
MOV P0,#00000000B // initializes P0 as output port

BACK:MOV P1,#11111111B // loads P1 with all 1's
     CLR P1.0  // makes row 1 low
     JB P1.4,NEXT1  // checks whether column 1 is low and jumps to NEXT1 if not low
     MOV A,#0D   // loads a with 0D if column is low (that means key 1 is pressed)
     ACALL DISPLAY  // calls DISPLAY subroutine
NEXT1:JB P1.5,NEXT2 // checks whether column 2 is low and so on...
      MOV A,#1D
      ACALL DISPLAY
NEXT2:JB P1.6,NEXT3
      MOV A,#2D
      ACALL DISPLAY
NEXT3:JB P1.7,NEXT4
      MOV A,#3D
      ACALL DISPLAY
NEXT4:SETB P1.0
      CLR P1.1
      JB P1.4,NEXT5
      MOV A,#4D
      ACALL DISPLAY
NEXT5:JB P1.5,NEXT6
      MOV A,#5D
      ACALL DISPLAY
NEXT6:JB P1.6,NEXT7
      MOV A,#6D
      ACALL DISPLAY
NEXT7:JB P1.7,NEXT8
      MOV A,#7D
      ACALL DISPLAY
NEXT8:SETB P1.1
      CLR P1.2
      JB P1.4,NEXT9
      MOV A,#8D
      ACALL DISPLAY
NEXT9:JB P1.5,NEXT10
      MOV A,#9D
      ACALL DISPLAY
NEXT10:JB P1.6,NEXT11
       MOV A,#10D
       ACALL DISPLAY
NEXT11:JB P1.7,NEXT12
       MOV A,#11D
       ACALL DISPLAY
NEXT12:SETB P1.2
       CLR P1.3
       JB P1.4,NEXT13
       MOV A,#12D
       ACALL DISPLAY
NEXT13:JB P1.5,NEXT14
       MOV A,#13D
       ACALL DISPLAY
NEXT14:JB P1.6,NEXT15
       MOV A,#14D
       ACALL DISPLAY
NEXT15:JB P1.7,BACK
       MOV A,#15D
       ACALL DISPLAY
       LJMP BACK

DISPLAY:MOVC A,@A+DPTR // gets digit drive pattern for the current key from LUT
        MOV P0,A       // puts corresponding digit drive pattern into P0
        RET

LUT: DB 01100000B // Look up table starts here
     DB 11011010B
     DB 11110010B
     DB 11101110B
     DB 01100110B
     DB 10110110B
     DB 10111110B
     DB 00111110B
     DB 11100000B
     DB 11111110B
     DB 11110110B
     DB 10011100B
     DB 10011110B
     DB 11111100B
     DB 10001110B
     DB 01111010B
     END
 
That lookup table is for a 7 segment LED?

To display a number you just add 0x30 to it and send to the LCD display!!
you mean this type
ORG 300H
KCODE0: DB ‘0’,’1’,’2’,’3’ ;ROW 0
KCODE1: DB ‘4’,’5’,’6’,’7’ ;ROW 1
KCODE2: DB ‘8’,’9’,’A’,’B’ ;ROW 2
KCODE3: DB ‘C’,’D’,’E’,’F’ ;ROW 3
END
 
I have made this code
Code:
   ORG 0H
MOV A,#38H ;INIT. LCD 2 LINES, 5X7 MATRIX
ACALL COMNWRT ;call command subroutine
ACALL DELAY ;give LCD some time
MOV A,#0EH ;display on, cursor on
ACALL COMNWRT ;call command subroutine
ACALL DELAY ;give LCD some time
MOV A,#01 ;clear LCD
ACALL COMNWRT ;call command subroutine
ACALL DELAY ;give LCD some time
MOV A,#06H ;shift cursor right
ACALL COMNWRT ;call command subroutine
ACALL DELAY ;give LCD some time
MOV A,#84H ;cursor at line 1, pos. 4
ACALL COMNWRT ;call command subroutine
ACALL DELAY
MOV A,#18H
ACALL COMNWRT
ACALL DELAY ;give LCD some time
MOV A,#'A' ;display letter J
ACALL DATAWRT ;call display subroutine
ACALL DELAY ;give LCD some time
MOV A,#'B' ;display letter D
ACALL DATAWRT ;call display subroutine
AGAIN: SJMP AGAIN ;stay here
COMNWRT: ;send command to LCD
MOV P1,A ;copy reg A to port 1
CLR P2.0 ;RS=0 for command
CLR P2.1 ;R/W=0 for write
SETB P2.2 ;E=1 for high pulse
ACALL DELAY ;give LCD some time
CLR P2.2 ;E=0 for H-to-L pulse
RET
DATAWRT: ;write data to LCD
MOV P1,A ;copy reg A to port 1
SETB P2.0 ;RS=1 for data
CLR P2.1 ;R/W=0 for write
SETB P2.2 ;E=1 for high pulse
ACALL DELAY ;give LCD some time
CLR P2.2 ;E=0 for H-to-L pulse
DELAY: MOV R3,#50 ;50 or higher for fast CPUs
HERE2: MOV R4,#255 ;R4 = 255
HERE: DJNZ R4,HERE ;stay until R4 becomes 0
DJNZ R3,HERE2
RET

         
MOV DPTR,#LUT // moves starting address of LUT to DPTR
MOV A,#11111111B // loads A with all 1's
MOV P0,#00000000B // initializes P0 as output port

BACK:MOV P1,#11111111B // loads P1 with all 1's
     CLR P1.0  // makes row 1 low
     JB P1.4,NEXT1  // checks whether column 1 is low and jumps to NEXT1 if not low
     MOV A,#0D   // loads a with 0D if column is low (that means key 1 is pressed)
     ACALL DISPLAY  // calls DISPLAY subroutine
NEXT1:JB P1.5,NEXT2 // checks whether column 2 is low and so on...
      MOV A,#1D
      ACALL DISPLAY
NEXT2:JB P1.6,NEXT3
      MOV A,#2D
      ACALL DISPLAY
NEXT3:JB P1.7,NEXT4
      MOV A,#3D
      ACALL DISPLAY
NEXT4:SETB P1.0
      CLR P1.1
      JB P1.4,NEXT5
      MOV A,#4D
      ACALL DISPLAY
NEXT5:JB P1.5,NEXT6
      MOV A,#5D
      ACALL DISPLAY
NEXT6:JB P1.6,NEXT7
      MOV A,#6D
      ACALL DISPLAY
NEXT7:JB P1.7,NEXT8
      MOV A,#7D
      ACALL DISPLAY
NEXT8:SETB P1.1
      CLR P1.2
      JB P1.4,NEXT9
      MOV A,#8D
      ACALL DISPLAY
NEXT9:JB P1.5,NEXT10
      MOV A,#9D
      ACALL DISPLAY
NEXT10:JB P1.6,NEXT11
       MOV A,#10D
       ACALL DISPLAY
NEXT11:JB P1.7,NEXT12
       MOV A,#11D
       ACALL DISPLAY
NEXT12:SETB P1.2
       CLR P1.3
       JB P1.4,NEXT13
       MOV A,#12D
       ACALL DISPLAY
NEXT13:JB P1.5,NEXT14
       MOV A,#13D
       ACALL DISPLAY
NEXT14:JB P1.6,NEXT15
       MOV A,#14D
       ACALL DISPLAY
NEXT15:JB P1.7,BACK
       MOV A,#15D
       ACALL DISPLAY
       LJMP BACK

DISPLAY:MOVC A,@A+DPTR // gets digit drive pattern for the current key from LUT
        MOV P0,A       // puts corresponding digit drive pattern into P0
        RET

LUT: DB 01100000B // Look up table starts here
     DB 11011010B
     DB 11110010B
     DB 11101110B
     DB 01100110B
     DB 10110110B
     DB 10111110B
     DB 00111110B
     DB 11100000B
     DB 11111110B
     DB 11110110B
     DB 10011100B
     DB 10011110B
     DB 11111100B
     DB 10001110B
     DB 01111010B
     END
tell me ,where did I make mistake I will study more
 
I have done a simple 3x4 keypad and display on LCD

Look through my code and see if you can follow it..
I use different port pins to control the display, so remember to swap them out!!
Code:
    ORG 020H

    MOV    A,#38H        ;INIT. LCD 2 LINES, 5X7 MATRIX
    ACALL    COMNWRT     ;call command subroutine
    ACALL    DELAY         ;give LCD some time
    MOV    A,#0CH         ;display on, cursor on
    ACALL    COMNWRT     ;call command subroutine
    ACALL    DELAY         ;give LCD some time
    MOV    A,#01         ;clear LCD
    ACALL    COMNWRT     ;call command subroutine
    ACALL    DELAY         ;give LCD some time
    MOV    A,#06H        ;shift cursor right
    ACALL    COMNWRT     ;call command subroutine
    ACALL    DELAY         ;give LCD some time

AGAIN:
    ACALL    DATAHOME    ;Goto home position
    ACALL    PRINT        ;Print Message
    ACALL    KEY        ;Read keypad
    ADD    A,#030h        ;Add ascii
    ACALL    DATAWRT        ;and display
    SJMP    AGAIN         ;Forever loop


PRINT:
    MOV     DPTR,#STRING    ;Point DPTR to string
    MOV    R2,#0Dh        ;11 characters

LOOP:    MOV    A,#0h
    MOVC    A,@A+DPTR    ;Add offset
    ACALL    DATAWRT        ;send to screen
    INC    DPTR
    DJNZ    R2,LOOP        ;Done?
    RET

STRING:
    db    "Enter a Key: "    ;String to display

KEY:
    MOV    B,#0h        ;B holds key..
    MOV    R1,#0Ch        ;This will be column select!!
COL:    MOV    A,R1
    SWAP    A        ;Stick colum select in high nibble
    ORL    A,#0Fh        ;Set all  rows high
    MOV    P2,A
    JB    P2.0,ROW2
    INC    B        ;If Row1 low inc B
    SJMP    FIN
ROW2:    JB    P2.1,ROW3
    INC    B        ;If Row2 low add 2 to B
    INC    B
    SJMP    FIN
ROW3:    JB    P2.2,ROW4
    INC    B        ;If Row3 low add 3 to B
    INC    B
    INC    B
    SJMP    FIN
ROW4:    JB    P2.3,NEXT
    INC    B        ;If Row4 low add 4 to B
    INC    B
    INC    B
    INC    B
    SJMP    FIN
NEXT:    MOV    A,B        ;If no key press
    ADD    A,#04H        ;on column, then
    MOV    B,A        ;add 4 to B
    MOV    A,R1        ;Get Column number
    RLC    A
    SETB    Acc.1        ;rotate and set col 1
    MOV    R1,A        ;
    JB    Acc.4,COL    ;check if last colum
    MOV    B,#0h        ;If no key pressed set to 0
FIN:    MOV    A,B        ;move key into A and leave
    RET

DATAHOME:
    PUSH    Acc
    MOV    A, #080H    ;Home
    ACALL    COMNWRT   
    POP    Acc
    RET

COMNWRT:             ;send command to LCD
    MOV     P1,A         ;copy reg A to port 1
    CLR     P3.7         ;RS=0 for command
    CLR     P3.6         ;R/W=0 for write
    SETB     P3.5         ;E=1 for high pulse
    ACALL     DELAY        ;give LCD some time
    CLR     P3.5         ;E=0 for H-to-L pulse
    RET
DATAWRT:             ;write data to LCD
    MOV     P1,A         ;copy reg A to port 1
    SETB     P3.7         ;RS=1 for data
    CLR     P3.6         ;R/W=0 for write
    SETB     P3.5         ;E=1 for high pulse
    ACALL     DELAY         ;give LCD some time
    CLR     P3.5         ;E=0 for H-to-L pulse
    RET
DELAY: 
    MOV R3,#30 ;50 or higher for fast CPUs
HERE2:     MOV R4,#255 ;R4 = 255
HERE:     DJNZ R4,HERE ;stay until R4 becomes 0
    DJNZ R3,HERE2
    RET

END
 
You first read the pins to see if a key has been pressed
Allow a debounce time (100mS+)

Convert the number of the keypress to ascii to display it.

Sorry Ian,

100 msec? A delay that big? In my own routine, to read a keypad of 16 buttons of really bad quality (on purpose to be sure I cope with the worst possible), I have always been able to go away with no more than 35 msec. Even 25, but went back to 35 to play safe.

IIRC, with 100 msec the user could start feeling some "sluggishness" (hope this is the right word).

PIC micros in Assembler.
 
Ah the old software trap!!!! Set up a experiment.. Put a 5v rail and resistor on a button and watch the output on a scope!!

If you can press the button within 100mS you are very good!!

So well try a 20mS de-bounce.... I bet your code reads the button several times before you let go.

In my logic ( In my head.... AND it works extremely well ) is... Press the button... Make an audible beep so the user knows the firmware has responded to the button press...

I beep 25o mS after a key response.. Wait!! Far too long I hear you say... Nope still not slow enough so I then place a 250mS delay after the beep to ensure the user has let go... The key repeat is reasonable... ie 2 acknowledges a second.. The delay is only when a key is pressed... If the user hasn't let go by now its not my problem...
 
I read the whole matrix as necessary, until I find a key pressed down. Once there, I start a counter (to materialize 35 msec).

Once the counter is back to zero, I re-read the matrix and confirm that the same key is pressed down. It then becomes valid for me. I set he flag KEY_ACTIVE (meaning: there is at least a key currently pressed down).

I go to the routine servicing that particular key and done.

When I read again the matrix, if no key is sensed as pressed down, that flag is reset. Otherwise further action is aborted.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top