please dont rip this site

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


		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


		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




		mov	w,#-250			; 1 ms per interrupt at 4MHz, prescaler is /8

		retiw	 			; return from interrupt now


		;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


		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/6/13 01:27,

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

<A HREF=""> scenix keyscan</A>

Did you find what you needed?


Welcome to!


Welcome to!