; Key scan Virtual Periperal ; device pins28,pages4,banks8,turbo,oschs,stackx,optionx ; use oschs only for debugging ; set to 4MHz internal RC for actual operation org 8 key_val ds 1 ; contains the key value in 2's complement ; this is for ease of display routine only ; to get real value, please remove the ~ signs in ; the virtual matrix scanb ds 1 ; scan mask, the column to scan will have a zero scan_result ds 1 ; result of scanning cnt1 ds 1 ; column count (3 2 1 0, 3 being leftmost) cnt2 ds 1 ; row count (3 2 1 0, 3 being the top row) ; virtual matrix index is computed as 4*cnt2+cnt1 key_state ds 1 ; store the states of the keyboard scan debounce_cnt ds 1 ; debouncing count temp equ cnt1 ; store the key scanned until key is released ; key scan states fast_scan equ 7 ; scan all columns at once debounce equ 6 ; debounce state detailed_scan equ 5 ; scan a column at a time release equ 4 ; wait until key is released reset start ; goto 'start' on reset org 0 ; interrupt routine sb key_state.fast_scan ; current state=fast scan? jmp chk_debounce ; no, check if debounce state ;do fast scan mov rb,#%11110000 ; set all scan lines to low mov scan_result,rb ; store result and scan_result,#%11110000 ; mask all output lines csne scan_result,#%11110000 ; to examine only inputs jmp key_done ; no key pressed if results is 11110000 ; key pressed, go to debounce state clrb key_state.fast_scan ; clear current state setb key_state.debounce ; next state= debounce mov debounce_cnt,#20 ; 20 ms debouncing time jmp key_done ; change state on next interrupt chk_debounce sb key_state.debounce ; current state=debouncing? jmp chk_rescan ; no, check if detailed scan ;do debounce decsz debounce_cnt ; count down jmp key_done ; and continue on next interrupt if not done ; 20 ms elapsed clrb key_state.debounce ; clear current state setb key_state.detailed_scan ; next state=detailed scan jmp key_done ; state transition on next interrupt chk_rescan sb key_state.detailed_scan ; current state=detailed scan? jmp chk_release ; no, check if it is key release check mov cnt1,#3 ; leftmost column=3 ;detailed scan mov scanb,#%11110111 ; scan leftmost column first detail_scan mov rb,scanb ; send scan mask out mov scan_result,rb ; store result and scan_result,#%11110000 ; examine only inputs cse scan_result,#%11110000 ; any key? jmp encode ; yes, encode it dec cnt1 ; scan next column stc ; maintain the 1's rr scanb ; scan next column by moving the 0 to the right snc ; no carry means last column has been scanned jmp detail_scan ; still more to scan ; no key detected after scanning all columns, may be just noise on port clrb key_state.detailed_scan ; clear current state setb key_state.fast_scan ; return to fast scan jmp key_done ; on next interrupt encode mov cnt2,#0 ; find out on which row the key is pressed stc ; we are looking for a zero so set carry to 1 first cont_enc rl scan_result ; put the scan result in carry bit sc ; skip if zero is not there jmp lookup ; zero found, look up for value inc cnt2 ; increment the row number jmp cont_enc ; and continue ;virtual matrix offset=4 cnt2+cnt1 lookup clc ; clear carry to prepare for multiplication rl cnt2 ; multiply by 2 rl cnt2 ; multiply by 4 and add cnt2,cnt1 ; +cnt1 mov w,#virtual_matrix ; start of table add w,cnt2 ; index into table mov m,#0 ; prepare for iread which load the value at m:w iread ; read the value into m:w mov temp,w ; store mov m,#$f ; restore m to eliminate side effects clrb key_state.detailed_scan ; clear current state setb key_state.release ; next state=check key release jmp key_done ; on next interrupt virtual_matrix dw ~$f dw ~$0 dw ~$f dw ~$f dw ~9 dw ~8 dw ~7 dw ~$f dw ~6 dw ~5 dw ~4 dw ~$f dw ~3 dw ~2 dw ~1 dw ~$f chk_release sb key_state.release ; check key release state? jmp key_done ; no mov rb,scanb ; use last scanned column mask mov scan_result,rb ; get key and scan_result,#%11110000 ; mask outputs cse scan_result,#%11110000 ; equ to $F0 if no key pressed anymore jmp key_done ; key still pressed ; key released mov key_val,temp ; store final value clrb key_state.release ; state transition setb key_state.fast_scan ; next state is scan again key_done mov w,#-250 ; 1 ms per interrupt at 4MHz, prescaler is /8 retiw ; return from interrupt now start ;initialize port B mov m,#$0f ; Points mode register to set data direction mov !rb,#%11110000 ; RB0-3 will be outputs, and RB4-7 will be inputs ;set inputs with weak pull ups mov m,#$0e ; points mode register to pull-up enable mov !rb,#%00001111 ; Enable pull-ups on Port B inputs mov m,#$0c ; set Schmitt-trigger to increase noise immunity mov !rb,#%00001111 ; on RB4-7 mov m,#$F ; restore mode register mov !option,#%10000010 ; RTCC divide rate=8 setb key_state.fast_scan ; initial state is fast scan mov key_val,#0 ; no key pressed initially loop mov rb,key_val ; put key pressed on LEDs jmp loop ; loop forever
file: /Techref/scenix/keyscan.src, 5KB, , updated: 1999/2/20 13:23, local time: 2024/9/1 10:21,
3.144.6.236:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://techref.massmind.org/Techref/scenix/keyscan.src"> scenix keyscan</A> |
Did you find what you needed? |
Welcome to massmind.org! |
Welcome to techref.massmind.org! |
.