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 Scanning Problem with AN557 16F628A

Status
Not open for further replies.

johnnyquest

New Member
Using Microchip Application Note AN557 I have a problem with keypad scanning. When the keypad is pressed at times for numbers in the first column a "zero" will appear instead of the correct value. The zero appears randomly and introducing a delay as noted below reduces the zero from appearing when other numbers are pressed. The other columns are not affected so it does not seem to be some type of roll-over? I have seen similar code on the net used for keyscans, what could be wrong?

;ScanKeys, scans the 4X4 keypad matrix and returns a key value in
;NewKey (0 - F) if a key is pressed, if not it clears the keyhit flag.
;Debounce for a given keyhit is also taken care of.
;The rate of key scan is 20mS with a 4.096Mhz clock.
ScanKeys
btfss KeyFlag,DebnceOn ;debounce on?
goto Scan1 ;no then scan keypad
decfsz Debnce, F ;else dec debounce time
return ;not over then return
bcf KeyFlag,DebnceOn ;over, clr debounce flag
return ;and return
Scan1
call SavePorts ;save port values
movlw B'11101111' ;init TempD
movwf TempD
ScanNext
movf PORTB,W ;read to init port
bcf INTCON,RBIF ;clr flag
rrf TempD, F ;get correct column
btfss STATUS,C ;if carry set?
goto NoKey ;no then end
movf TempD,W ;else output
movwf PORTB ;low column scan line
; Intoducing this delay kinda helps
; MOVLW D'80' ;cycle delay
; MOVWF KeyScanDelay
; DECFSZ KeyScanDelay,F
; GOTO $-1
nop
btfss INTCON,RBIF ;flag set?
goto ScanNext ;no then next
btfsc KeyFlag,keyhit ;last key released?
goto SKreturn ;no then exit
bsf KeyFlag,keyhit ;set new key hit
swapf PORTB,W ;read port
movwf TempE ;save in TempE
call GetKeyValue ;get key value 0 - F
movwf NewKey ;save as New key
bsf KeyFlag,ServKey ;set service flag
bsf KeyFlag,DebnceOn ;set flag
movlw 4
movwf Debnce ;load debounce time
SKreturn
call RestorePorts ;restore ports
return
;
NoKey
bcf KeyFlag,keyhit ;clr flag
goto SKreturn
;
;GetKeyValue gets the key as per the following layout
;
; Col1 Col2 Col3 Col3
; (RB3) (RB2) (RB1) (RB0)
;
;Row1(RB4) 0 1 2 3
;
;Row2(RB5) 4 5 6 7
;
;Row3(RB6) 8 9 A B
;
;Row4(RB7) C D E F
;
GetKeyValue
clrf TempC
btfss TempD,3 ;first column
goto RowValEnd
incf TempC, F
btfss TempD,2 ;second col.
goto RowValEnd
incf TempC, F
btfss TempD,1 ;3rd col.
goto RowValEnd
incf TempC, F ;last col.
RowValEnd
btfss TempE,0 ;top row?
goto GetValCom ;yes then get 0,1,2&3
btfss TempE,1 ;2nd row?
goto Get4567 ;yes the get 4,5,6&7
btfss TempE,2 ;3rd row?
goto Get89ab ;yes then get 8,9,a&b
Getcdef
bsf TempC,2 ;set msb bits
Get89ab
bsf TempC,3 ; /
goto GetValCom ;do common part
Get4567
bsf TempC,2
GetValCom
movf TempC,W
addwf PCL, F
retlw 0
retlw 1
retlw 2
retlw 3
retlw 4
retlw 5
retlw 6
retlw 7
retlw 8
retlw 9
retlw 0a
retlw 0b
retlw 0c
retlw 0d
retlw 0e
retlw 0f
 
I think I see a potential problem in the author's use of the RBIF (interrupt on change) flag bit while scanning the keypad and I suspect the flag may not always be valid when scanning the first keypad column.

Do you feel like testing a small program change? This modified code doesn't use the RBIF "change" flag but tests for a pressed key using a slightly different method. Please let us know if it helps.

Code:
ScanNext
        rrf     TempD,F         ; last column done?
        skpc                    ; no, skip, else
        goto    NoKey           ; done, exit, no press
        movf    TempD,W         ; get new column pattern
        movwf   PORTB           ; update column lines
        nop                     ; settling time
        comf    PORTB,W         ; invert PORTB bits
        andlw   b'11110000'     ; any keys pressed?
        bz      ScanNext        ; no, branch, else
        btfsc   KeyFlag,keyhit  ; last key released?
 
Mike,

Your revised code does indeed work, many thanks for your help.

I am trying to learn as much as I can on pic programming. Would this affect all pics? Could you please tell me why the use of the RBIF flag was not valid scanning the first column?

Again Thanks,
JohnnyQuest
 
Glad you got it working.

It looked to me like the author was relying on the RB7 through RB4 "row" pins being set or high (ie; '1111xxxx') from a previous column scan cycle (when no keys connected to that column are pressed) before starting a new column scan cycle. This won't be the case for the first column scan when one of the keys in that column are pressed.

I believe the author's method would produce the same symptoms on all PICs.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top