• 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.

asm -16f- switch debounce


Well-Known Member
Here's a contribution for managing up to 8 switches, not necessarily in a single port. Heavily commented. This should be called as part of a main program loop once per iteration. There is code to evaluate whether the switch is switched to ground or Vcc. Just comment out the part you don't need. Similarly, there are examples for applying a switch from any pin to fill out a single byte for parallel processing. It is dependent on a 4ms ISR for the delay counter. You can alter the ISR speed and compensate by altering the bit being evaluated for the ISR delay time counter held in GPR , 'Dbouncecount'. Just try to have the overall time within 20% of the times used here.

Keypad; Evaluate keypresses for click, hold (long press) , open with debounce & transition states. Works in parallel for up to 8 switches. Requires a 4 (can  use others) ms tick (usually done in an ISR) for 'Dbouncecount'. 
;Setup for Key_0 , in bit 0;  this method allows any pin in any port to be a key /switch as the keys are mapped to a single 8bit byte here. 'Tmp' is a locally valid temp variable for general subroutine use.
; The Transition bytes are set  if a new  debounced keystate just happened . These are cleared on each iteration.
;Each of the 8 Transition bits in the bytes (Keytrans and HoldTrans) allow for debounced edge triggering events. eg. If the DbKeystate,0  is hi and the Keytrans,0 is high then the debounced key0 press leading edge just happened.  
;If DbKeystate is Hi and Keytrans,0 is lo, then the debounced Keypress is mature.
;If the DbKeystate,0 is lo and the KeyTrans,0 is hi then the debounced key was just released - trailing edge. Stored in "Shortpress' GPR; Just do a bit check on this byte for any of the 8 switches' shortpress condition.
; A similar structure applies to HoldTrans and HoldKeystate bytes as applies to a 'long key hold/click' operation - holding down a key for a 1/2 second. Stored in 'Longpress' byte. Just do a bit check on this byte for any of the 8 switches' longpress condition.
; Thus a single key can deliver up to 4 states, leading and trailing edge for both short clicks and long clicks.
; The use of the leading edge transitions is manifest when preventing 'repeating' a routine that responds to the key condition.eg. only respond to a keypress if the transition bit is also set, like make a beep.
;The leading edge can also keep track of which key to respond to if multiple keys are pressed simultaneously.
; eg. The trailing transition can be used for triggering an acknowledgement after the key is released.

	clrf  Sw_state ;clear switch state byte for evaluation below.
	clrf KeyTrans ;limit all transitions to one complete program loop.
	clrf HoldTrans; " "
	;btfsc GPIO,3 ;  Key0 = pin physical location.  Btfsc used when key is pulled hi when closed.
	btfss GPIO,3; Key0 = pin physical location. Btfss used when key is pulled low when closed
	bsf  Sw_state,0 ; match  Sw_state bit 0 to  Key state, 1= closed, 0=open.
;Setup for Key_1 , in bit 1
	;btfsc PORTA,6 ;  Key1 pin. = PORTA,6
	;bsf  Sw_state,1 ; match  Sw_state bit 1 to  Key state, 1= closed, 0=open.
;Setup for Key_7 , in bit 7
	;btfsc PORTB,2 ;  Key7 pin. = PORTB,2
	;bsf  Sw_state,7 ; match  Sw_state bit 7 to  Key state, 1= closed, 0=open.
	movf Sw_state,w ; get newstate					eg. Sw0,2 closed	0101
	xorwf LastKeystate,w ; state changes					eg.		1100 =>	1001
	xorwf LastKeystate,f ; make Laststate =Newstate.					1100=>	0101
	andlw b'11111111'; test wreg if any bits changed
	btfss STATUS,Z; skip zero set, else (statechange)
	clrf Dbouncecount; reset counter (counts every 4 msec in ISR)
	btfss Dbouncecount,2 ; skip if bit 2 set=> 16ms passed, else
	goto Testkeyhold;
	movf LastKeystate,w;													0101
	xorwf DbKeystate,w; get changes bet. current state and debounced state.		0110 =>	0011
	movwf KeyTrans; save in transition byte.											0011 (transition bits)
	xorwf DbKeystate,f; apply them to DB state								0110 => 0101	
        movf DbKeystate,w
	xorlw .255; test for key release (open)
	andwf KeyTrans,w; verify transition of key release.
	movwf Shortpress; update shortpress status, based on click/release.				
	movf  DbKeystate,w	;														0101
	andwf HoldKeystate,w ;zero Hold bits if matching key is released - wreg.				0011 =>	0001
	xorwf HoldKeystate,w ; get Transition from Hold to release							0011 =>	0010
	movwf HoldTrans; update HoldTransition byte.														0010
	xorwf KeyTrans,f ; toggle any matching release from clicks off, release from hold priority.
	xorwf HoldKeystate,f ; now immediately switch off Hold if a key is released - file.		0011 =>	0001
	xorwf DbKeystate,w ; get newly pressed keys to test for hold.(state change)							0101 =>	0100
	btfss STATUS,Z; skip if  no new key pressed, else
Testforholdcount ; test if timer expired
	btfss Dbouncecount,7 ; 128*4ms = 512ms
	goto Keydone
	movf DbKeystate,w;							0101
	xorwf HoldKeystate,w ; get statechanges			0001 =>	0100
	iorwf HoldTrans,f; update hold transition byte.			0010 =>	0110 (transition bits)
	;using what's still in wreg to apply changes		0100
	xorwf HoldKeystate,f;apply changes				0001 =>	0101
        movf HoldKeystate,w
	andwf  HoldTrans,w; verify transition of key 
	movwf Longpress; update Longpress status.
Keydone	return
Last edited:


Well-Known Member
Yes will work on any 12f,16f18f series.

If u tell me which pins u want to place your switches on I will happilly adjust it for u.

Latest threads

EE World Online Articles