![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) |
|
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 |
|
|
|
|
|
|
(permalink) |
|
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?
|
|
|
|
|
|
|
(permalink) |
|
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 |
|
|
|
|
|
|
(permalink) |
|
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. |
|
|
|
|
| Bookmarks |
| Thread Tools | |
| Display Modes | |
|
|
|
|
||||
| Thread | Thread Starter | Forum | Replies | Latest |
| Help with problem programming 16F628A | ukatv | Micro Controllers | 8 | 25th September 2007 08:23 PM |
| LCD and keypad, scroll problem | sarang1_in | Micro Controllers | 3 | 29th June 2005 03:07 PM |
| Problem with onboard EEPROM on 16f628A | clueless123 | Micro Controllers | 3 | 7th March 2005 08:38 AM |
| problem with 16f628a | gang | Micro Controllers | 6 | 5th March 2005 04:55 PM |
| Compiling 16F628A - problem | kenmac | Micro Controllers | 4 | 23rd September 2004 04:59 AM |