• 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.

4x4 keypad bug on pic16f627a Please help

Status
Not open for further replies.

Koosiekloek

New Member
good day

i am using a PIC16F627A for decoding a key pressed and sending to another controller.
the program is running and doing most of what it should.
the process should be to pull the 4 columns high one by one namely PB4, PB5, PB6, PB7 and test each row namely RA0, RA1, RA2, RA3 for which button is being pressed, if a button is pressed it should wait until the button is released and then put the decoded key value on the 4 output pins PB0, PB1, PB2, PB3 and then toggle PA6 to say data is available.
the problem is when a button is pressed say in column 1 row 1 and the button is held down while another button in the same column is pressed say column 1 row 2, the PA6 pin is toggled when the button in row 2 is pressed and toggled again when the button in row 1 is released.
can anyone please tell me what i am doing wrong?
my code below.
 

Attachments

Koosiekloek

New Member
CODE

list p=pic16f627a
#include "p16f627a.inc"

; EQUATINGS // DECLARATIONS

COUNTER_1 EQU H'23'
COUNTER_2 EQU H'24'
COUNTER_3 EQU H'25'


; DISABLE COMPARITORS AND INITIALIZING OF PORTS

ORG 0X00 ;BEGIN AT H'00'
BANKSEL CMCON ;SELECT BANK 0
MOVLW H'07' ;LOAD VALUE IN W
MOVWF CMCON ;DISABLE COMPARITORS
BANKSEL TRISA ;SELECT BANK 1
MOVLW B'00000000' ;LOAD VALUE IN W ascii + key find
MOVWF TRISB ;MAKE PORTB ALL INPUTS
MOVLW B'10111111' ;LOAD VALUE IN W data availeble pin
MOVWF TRISA ;MAKE PORTA(6)OUTPUT (0,1,2,3,4,5,7)INPUTS 5 can't be output
BANKSEL PORTA ;SELECT BANK 0



main
clrf PORTB

clrf PORTA
top bsf PORTB,7 ;row 1
nop
nop
btfsc PORTA,0
goto a1
btfsc PORTA,1
goto a2
btfsc PORTA,2
goto a3
btfsc PORTA,3
goto a4
bcf PORTB,7

bsf PORTB,6 ;row 2
nop
nop
btfsc PORTA,0
goto a5
btfsc PORTA,1
goto a6
btfsc PORTA,2
goto a7
btfsc PORTA,3
goto a8
bcf PORTB,6

bsf PORTB,5 ;row 3
nop
nop
btfsc PORTA,0
goto a9
btfsc PORTA,1
goto a10
btfsc PORTA,2
goto a11
btfsc PORTA,3
goto a12
bcf PORTB,5

bsf PORTB,4 ;row 4
nop
nop
btfsc PORTA,0
call a13
btfsc PORTA,1
call a14
btfsc PORTA,2
call a15
btfsc PORTA,3
call a16
bcf PORTB,4

movlw b'00001111'
andwf PORTB,1 ;AND PortB with 0x0f to clear MSB nibbel stor in PortB

goto top


a1 call TIME_DELAY_20ms ;row1
a1a btfsc PORTA,0
goto a1a
movlw 0x00
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a2 call TIME_DELAY_20ms
a2a btfsc PORTA,1
goto a2a
movlw 0x01
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a3 call TIME_DELAY_20ms
a3a btfsc PORTA,2
goto a3a
movlw 0x02
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a4 call TIME_DELAY_20ms
a4a btfsc PORTA,3
goto a4a
movlw 0x03
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a5 call TIME_DELAY_20ms ;row2
a5a btfsc PORTA,0
goto a5a
movlw 0x04
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a6 call TIME_DELAY_20ms
a6a btfsc PORTA,1
goto a6a
movlw 0x05
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a7 call TIME_DELAY_20ms
a7a btfsc PORTA,2
goto a7a
movlw 0x06
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a8 call TIME_DELAY_20ms
a8a btfsc PORTA,3
goto a8a
movlw 0x07
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a9 call TIME_DELAY_20ms ;row3
a9a btfsc PORTA,0
goto a9a
movlw 0x08
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a10 call TIME_DELAY_20ms
a10a btfsc PORTA,1
goto a10a
movlw 0x09
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a11 call TIME_DELAY_20ms
a11a btfsc PORTA,2
goto a11a
movlw 0x0a
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a12 call TIME_DELAY_20ms
a12a btfsc PORTA,3
goto a12a
movlw 0x0b
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top


a13 call TIME_DELAY_20ms ;row4
a13a btfsc PORTA,0
goto a13a
movlw 0x0c
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a14 call TIME_DELAY_20ms
a14a btfsc PORTA,1
goto a14a
movlw 0x0d
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a15 call TIME_DELAY_20ms
a15a btfsc PORTA,2
goto a15a
movlw 0x0e
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

a16 call TIME_DELAY_20ms
a16a btfsc PORTA,3
goto a16a
movlw 0x0f
movwf PORTB
nop
nop
bsf PORTA,6
call TIME_DELAY_0.5s
bcf PORTA,6
call TIME_DELAY_20ms
goto top

; TIME DELAY OF 0,2 SECONDS

TIME_DELAY_0.5s:
MOVLW D'1' ;LOAD VALUE D'3' IN W
MOVWF COUNTER_3 ;LOAD VALUE IN W INTO FILE(COUNTER_3)
LOOP_3:
MOVLW D'255' ;LOAD VALUE D'255' INTO W
MOVWF COUNTER_2 ;LOAD VALUE IN W INTO FILE(counter_2)
LOOP_2:
MOVLW D'255' ;LOAD VALUE D'255' INTO W
MOVWF COUNTER_1 ;LOAD VALUE IN W INTO FILE(COUNTER_1)
LOOP_1:
DECFSZ COUNTER_1 ;TEST FILE(COUNTER_1) FOR 0 IF, 0 SKIP IF NOT MINUS 1 FROM FILE
GOTO LOOP_1 ;GOTO LOOP_1 (HOU AAN OM DEER LOOP TE GAAN TODAT FILE(COUNTER_1) 0 IS

DECFSZ COUNTER_2 ;TEST FILE(COUNTER_2) FOR 0 IF, 0 SKIP IF NOT MINUS 1 FROM FILE
GOTO LOOP_2 ;GOTO LOOP_2 (HOU AAN OM DEER LOOP TE GAAN TODAT FILE(COUNTER_2) 0 IS

DECFSZ COUNTER_3 ;TEST FILE(COUNTER_3) FOR 0 IF, 0 SKIP IF NOT MINUS 1 FROM FILE
GOTO LOOP_3 ;GOTO LOOP_3 (HOU AAN OM DEER LOOP TE GAAN TODAT FILE(COUNTER_3) 0 IS
RETURN ;BACK TO MAIN PROGRAM

TIME_DELAY_20ms:

MOVLW D'30' ;LOAD VALUE D'255' INTO W
MOVWF COUNTER_2 ;LOAD VALUE IN W INTO FILE(counter_2)
LOOP_2.1:
MOVLW D'255' ;LOAD VALUE D'255' INTO W
MOVWF COUNTER_1 ;LOAD VALUE IN W INTO FILE(COUNTER_1)
LOOP_1.1:
DECFSZ COUNTER_1 ;TEST FILE(COUNTER_1) FOR 0 IF, 0 SKIP IF NOT MINUS 1 FROM FILE
GOTO LOOP_1.1 ;GOTO LOOP_1 (HOU AAN OM DEER LOOP TE GAAN TODAT FILE(COUNTER_1) 0 IS

DECFSZ COUNTER_2 ;TEST FILE(COUNTER_2) FOR 0 IF, 0 SKIP IF NOT MINUS 1 FROM FILE
GOTO LOOP_2.1 ;GOTO LOOP_2 (HOU AAN OM DEER LOOP TE GAAN TODAT FILE(COUNTER_2) 0 IS

RETURN ;BACK TO MAIN PROGRAM
end
 

BobW

Active Member
It's not that you're necessarily doing anything wrong. This is just an inherent characteristic of matrixed keypads, referred to as rollover, such that simultaneous keydowns give ambiguous results. If you can wire your keyboard with steering diodes, and use the keydown event to detect key inputs rather than keyup, then you can fully decode the keys.
 

Dan Soze

Member
good day

i am using a PIC16F627A for decoding a key pressed and sending to another controller.
the program is running and doing most of what it should.
the process should be to pull the 4 columns high one by one namely PB4, PB5, PB6, PB7 and test each row namely RA0, RA1, RA2, RA3 for which button is being pressed, if a button is pressed it should wait until the button is released and then put the decoded key value on the 4 output pins PB0, PB1, PB2, PB3 and then toggle PA6 to say data is available.
the problem is when a button is pressed say in column 1 row 1 and the button is held down while another button in the same column is pressed say column 1 row 2, the PA6 pin is toggled when the button in row 2 is pressed and toggled again when the button in row 1 is released.
can anyone please tell me what i am doing wrong?
It looks like you did not set the direction for inputs and outputs on PORTA and PORTB correct.

This is your code with fixes:
Code:
    list p=pic16f627a
    #include "p16f627a.inc"

; EQUATINGS // DECLARATIONS
  cblock H'23'
    COUNTER_1:1
    COUNTER_2:1
    COUNTER_3:1
  endc

; DISABLE COMPARITORS AND INITIALIZING OF PORTS

    ORG     0X00                ; BEGIN AT H'00'
    BANKSEL CMCON               ; SELECT BANK 0
    MOVLW   H'07'               ; LOAD VALUE IN W
    MOVWF   CMCON               ; DISABLE COMPARITORS
    BANKSEL TRISA               ; SELECT BANK 1
    MOVLW   B'11111111'         ; LOAD VALUE IN W ascii + key find <Changed to match commments>
    MOVWF   TRISB               ; MAKE PORTB ALL INPUTS
    MOVLW   B'00100000'         ; LOAD VALUE IN W data availeble pin <Changed to match comments>
    MOVWF   TRISA               ; MAKE PORTA(6)OUTPUT (0,1,2,3,4,6,7)INPUTS 5 can't be output
    BANKSEL PORTA               ; SELECT BANK 0

main:
    clrf    PORTB
    clrf    PORTA
top:
    bsf     PORTB,7             ; row 1
    nop
    nop
    btfsc   PORTA,0
    goto    a1
    btfsc   PORTA,1
    goto    a2
    btfsc   PORTA,2
    goto    a3
    btfsc   PORTA,3
    goto    a4
    bcf     PORTB,7

    bsf     PORTB,6             ; row 2
    nop
    nop
    btfsc   PORTA,0
    goto    a5
    btfsc   PORTA,1
    goto    a6
    btfsc   PORTA,2
    goto    a7
    btfsc   PORTA,3
    goto    a8
    bcf     PORTB,6

    bsf     PORTB,5             ; row 3
    nop
    nop
    btfsc   PORTA,0
    goto    a9
    btfsc   PORTA,1
    goto    a10
    btfsc   PORTA,2
    goto    a11
    btfsc   PORTA,3
    goto    a12
    bcf     PORTB,5

    bsf     PORTB,4             ; row 4
    nop
    nop
    btfsc   PORTA,0
    call    a13
    btfsc   PORTA,1
    call    a14
    btfsc   PORTA,2
    call    a15
    btfsc   PORTA,3
    call    a16
    bcf     PORTB,4

    movlw   b'00001111'
    andwf   PORTB,1             ; AND PortB with 0x0f to clear MSB nibbel stor in PortB

    goto    top


a1:
    call    TIME_DELAY_20ms     ; row1
a1a:
    btfsc   PORTA,0
    goto    a1a
    movlw   0x00
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a2:
    call    TIME_DELAY_20ms
a2a:
    btfsc   PORTA,1
    goto    a2a
    movlw   0x01
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a3:
    call    TIME_DELAY_20ms
a3a:
    btfsc   PORTA,2
    goto    a3a
    movlw   0x02
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a4:
    call    TIME_DELAY_20ms
a4a:
    btfsc   PORTA,3
    goto    a4a
    movlw   0x03
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a5:
    call    TIME_DELAY_20ms     ; row2
a5a:
    btfsc   PORTA,0
    goto    a5a
    movlw   0x04
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a6:
    call    TIME_DELAY_20ms
a6a:
    btfsc   PORTA,1
    goto    a6a
    movlw   0x05
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a7:
    call    TIME_DELAY_20ms
a7a:
    btfsc   PORTA,2
    goto    a7a
    movlw   0x06
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a8:
    call    TIME_DELAY_20ms
a8a:
    btfsc   PORTA,3
    goto    a8a
    movlw   0x07
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a9:
    call    TIME_DELAY_20ms     ; row3
a9a:
    btfsc   PORTA,0
    goto    a9a
    movlw   0x08
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a10:
    call    TIME_DELAY_20ms
a10a:
    btfsc   PORTA,1
    goto    a10a
    movlw   0x09
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a11:
    call    TIME_DELAY_20ms
a11a:
    btfsc   PORTA,2
    goto    a11a
    movlw   0x0a
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a12:
    call    TIME_DELAY_20ms
a12a:
    btfsc   PORTA,3
    goto    a12a
    movlw   0x0b
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top


a13:
    call    TIME_DELAY_20ms     ; row4
a13a:
    btfsc   PORTA,0
    goto    a13a
    movlw   0x0c
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a14:
    call    TIME_DELAY_20ms
a14a:
    btfsc   PORTA,1
    goto    a14a
    movlw   0x0d
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a15:
    call    TIME_DELAY_20ms
a15a:
    btfsc   PORTA,2
    goto    a15a
    movlw   0x0e
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

a16:
    call    TIME_DELAY_20ms
a16a:
    btfsc   PORTA,3
    goto    a16a
    movlw   0x0f
    movwf   PORTB
    nop
    nop
    bsf     PORTA,6
    call    TIME_DELAY_0.5s
    bcf     PORTA,6
    call    TIME_DELAY_20ms
    goto    top

; TIME DELAY OF 0,2 SECONDS

TIME_DELAY_0.5s:
    MOVLW   D'1'                ; LOAD VALUE D'3' IN W
    MOVWF   COUNTER_3           ; LOAD VALUE IN W INTO FILE(COUNTER_3)
LOOP_3:
    MOVLW   D'255'              ; LOAD VALUE D'255' INTO W
    MOVWF   COUNTER_2           ; LOAD VALUE IN W INTO FILE(counter_2)
LOOP_2:
    MOVLW   D'255'              ; LOAD VALUE D'255' INTO W
    MOVWF   COUNTER_1           ; LOAD VALUE IN W INTO FILE(COUNTER_1)
LOOP_1:
    DECFSZ  COUNTER_1,F         ; TEST FILE(COUNTER_1) FOR 0 IF, 0 SKIP IF NOT MINUS 1 FROM FILE
    GOTO    LOOP_1              ; GOTO LOOP_1 (HOU AAN OM DEER LOOP TE GAAN TODAT FILE(COUNTER_1) 0 IS

    DECFSZ  COUNTER_2,F         ; TEST FILE(COUNTER_2) FOR 0 IF, 0 SKIP IF NOT MINUS 1 FROM FILE
    GOTO    LOOP_2              ; GOTO LOOP_2 (HOU AAN OM DEER LOOP TE GAAN TODAT FILE(COUNTER_2) 0 IS

    DECFSZ  COUNTER_3,F         ; TEST FILE(COUNTER_3) FOR 0 IF, 0 SKIP IF NOT MINUS 1 FROM FILE
    GOTO    LOOP_3              ; GOTO LOOP_3 (HOU AAN OM DEER LOOP TE GAAN TODAT FILE(COUNTER_3) 0 IS
    RETURN                      ; BACK TO MAIN PROGRAM

TIME_DELAY_20ms:

    MOVLW   D'30'               ; LOAD VALUE D'255' INTO W
    MOVWF   COUNTER_2           ; LOAD VALUE IN W INTO FILE(counter_2)
LOOP_2.1:
    MOVLW   D'255'              ; LOAD VALUE D'255' INTO W
    MOVWF   COUNTER_1           ; LOAD VALUE IN W INTO FILE(COUNTER_1)
LOOP_1.1:
    DECFSZ  COUNTER_1,F         ; TEST FILE(COUNTER_1) FOR 0 IF, 0 SKIP IF NOT MINUS 1 FROM FILE
    GOTO    LOOP_1.1            ; GOTO LOOP_1 (HOU AAN OM DEER LOOP TE GAAN TODAT FILE(COUNTER_1) 0 IS

    DECFSZ  COUNTER_2,F         ; TEST FILE(COUNTER_2) FOR 0 IF, 0 SKIP IF NOT MINUS 1 FROM FILE
    GOTO    LOOP_2.1            ; GOTO LOOP_2 (HOU AAN OM DEER LOOP TE GAAN TODAT FILE(COUNTER_2) 0 IS

    RETURN                      ; BACK TO MAIN PROGRAM
    end
 
Last edited:
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top