Scenix Keyscan.src

 
;		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,#0ドルf			; 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,#0ドルe			; points mode register to pull-up enable
		mov	!rb,#%00001111		; Enable pull-ups on Port B inputs
		
		mov	m,#0ドルc			; 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: 2025年9月5日 17:21,
40.74.122.252:LOG IN

©2025 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?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://massmind.org/techref/scenix/keyscan.src"> scenix keyscan</A>

Did you find what you needed?

Welcome to massmind.org!

Welcome to massmind.org!

.

AltStyle によって変換されたページ (->オリジナル) /