PDA

View Full Version : 8 bit parallel debounce routine



cncmachineguy
- 26th July 2011, 14:54
Here is a debounce routine that just works. It will process up to 8 inputs in parallel. It works using something called vertical counters. I would try to explain them, but will fail so I suggest googling them as there is some really good information out there. I did not write this myself, I found the ASM version over on the Piclist - link in the code header.

The nuts and bolts are just some tricky boolean math. The usage goes like this:

Inputs to be de-bounced are placed in a variable called SWKEYS.
Using your favorite timebase technique, call DB8 every 1mSec (not real critical)
Upon return all de-bounced states will be in SLATCH.

So in your program, check the bits of SLATCH to decide if an input has changed. At 1mSec timbase, it will take 24mSec to get a valid input. If this is too fast for your switches, just adjust the timebase.

You can paste all the code into your program, or just include it.



;################################################# #####
; The purpose of this code is to debounce up to 8 switch
;inputs in parallel. It could be called from you main with either
;an ISR or or my favorite is to set up a counter for 1 mSec and poll
;it's int flag.
; It will take 24 iterations of this code to call a switch debounced. So
;if your timer is 1mSec, it will be a 24mSec debounce + any short elapsed
;time from the timer overflow and the call to here.
; To use this, just "include" the file, then assign up to 8 switches to
;SWKEYS. When the program returns, you will have the debounced switches in
;SLATCH. If you poll a PIF to call this, don't forget to clear the flag
;upon return. Suggested code:
; IF PIF then
; gosub DB8
; PIF = 0
; ENDIF
; This compiles to ~50 words so not much space taken.
; This program is a direct conversion from this:
; http://www.piclist.com/techref/microchip/debouncebeeptoggleK8HL.htm
; There is lots of good info there and even better if one googles
; Vertical Counters

SWKEYS var byte ;Actual switch data
SLATCH var byte ;This is the debounced switch states
VCBIT0 var byte ;Vertical counter bit 0
VCBIT1 var byte ;Vertical counter bit 1
COLPOS var byte ;This is a shift reg. 1 is shifted at each loop
VCMASK var byte ;Vertical counter mask
TEMP VAR BYTE ;Just a temp needed for the counting

DB8:
TEMP = SWKEYS ^ SLATCH
VCBIT0 = TEMP & VCBIT0
VCBIT1 = TEMP & VCBIT1
VCMASK = TEMP & COLPOS ; 8-msec 'column' prescaler
;seed "cumulative AND" mask
VCBIT0 = VCBIT0 ^ VCMASK ; b0 ^= vcmask
TEMP = TEMP ^ VCBIT0 ; restore b0' in W
VCMASK = VCMASK & TEMP ; vcmask &= b0'

VCBIT1 = VCBIT1 ^ VCMASK ; b1 ^= vcmask
TEMP = VCBIT1 ^ TEMP ; restore b1' in W
TEMP = TEMP & VCMASK ; vcmask &= b1'

SLATCH = SLATCH ^ TEMP ; update debounced state latch

;################################################# ################
; advance ring counter prescaler
; for the next interrupt cycle
COLPOS = COLPOS<<1 ; advance column ring counter
IF COLPOS = 0 THEN COLPOS = 1
;################################################# ################
Return



And here is a quick snippet to test it with:


####################
insert device setup stuff here
####################

goto myinit

include "debounce8.pbp"

myinit:
mainloop:
pause 1
swkeys = portb
gosub DB8
porta = slatch

goto mainloop


Of course the above assumes you will save the de-bounce program as debounce8.pbp