This code provides the same features as the 'debounce', 'beep', and 'toggle' example with additional vertical counters and code to provide a 512.0-msec 'repeat' capability for designated switches.
;******************************************************************
;
; Mike McLaren's vertical counter "debounce" & "repeat" sample
; ISR code based on concepts from Jonny Doin and Scott Dattalo
;
; <> process up to eight switches using 'parallel' code
; <> eight independent 24.0-msec "debounce" vertical counters
; <> debounced switch press audible feedback (beep or click)
; <> 512.0-msec repeat rate for designated repeat switches
; <> designate repeat switches on-the-fly
; <> momentary switch operation (test then clear a SWITCH bit)
; <> toggle switch emulation (push to toggle a SWITCH bit from
; off-to-on or from on-to-off) perfect for lighted switches
;
; 48 words/48 cycles (16-bit core)
;
;
;
; setup the SWKEYS variable with "live" switch press data from
; your switch input pins or your scanned switch matrix before
; falling into this routine. A '1' bit represents a 'pressed'
; switch and a '0' bit represents a 'released' switch.
;
; execute this code each 1.0-msec interrupt cycle
;
;
; clear vertical counters for any released or bouncing switches
;
ISR_Sw
movf SWKEYS,W ; live switch press data
andwf VCBIT0,f ; VC bit 0 byte
andwf VCBIT1,f ; VC bit 1 byte
andwf VCBIT2,f ; VC bit 2 byte
andwf VCBIT3,f ; VC bit 3 byte
andwf VCBIT4,f ; VC bit 4 byte
andwf VCBIT5,f ; VC bit 5 byte
andwf SWDATA,f ; debounce byte (24-msec latch)
;
; cyclic vertical counter algorithm. vcmask is seeded with an
; active switch mask and bn' is the previous state of bn before
; the bit increment operation.
;
; a switch is debounced or filtered after sampling it at the
; same level through four vertical counts spanning 24.0-msecs
;
; b0 ^= (vcmask)
; b1 ^= (vcmask & b0')
; b2 ^= (vcmask & b0' & b1')
; b3 ^= (vcmask & b0' & b1' & b2')
; b4 ^= (vcmask & b0' & b1' & b2' & b3')
; b5 ^= (vcmask & b0' & b1' & b2' & b3' & b4')
;
; Mike McLaren's "cumulative AND" vertical counter method
;
; b0 ^= vcmask : vcmask &= b0'
; b1 ^= vcmask : vcmask &= b1'
; b2 ^= vcmask : vcmask &= b2'
; b3 ^= vcmask : vcmask &= b3'
; b4 ^= vcmask : vcmask &= b4'
; b5 ^= vcmask : vcmask &= b5'
;
andwf COLPOS,W ; 8-msec 'column' prescaler
movwf VCMASK ; seed "cumulative AND" mask
xorwf VCBIT0,f ; b0 ^= vcmask
xorwf VCBIT0,W ; restore original b0' in W
andwf VCMASK,W ; vcmask &= b0'
movwf VCMASK ;
xorwf VCBIT1,f ; b1 ^= vcmask
xorwf VCBIT1,W ; restore original b1' in W
andwf VCMASK,W ; vcmask &= b1'
;
; each '1' bit in the SWDATA variable represents a "debounced"
; 24.0-msec switch press (bit cleared when switch is released)
;
iorwf SWDATA,f ; set debounced switch bits
;
; repeat counters (512.0-msecs)
;
movwf VCMASK ;
xorwf VCBIT2,f ; b2 ^= vcmask
xorwf VCBIT2,W ; restore original b2' in W
andwf VCMASK,W ; vcmask &= b2'
movwf VCMASK ;
xorwf VCBIT3,f ; b3 ^= vcmask
xorwf VCBIT3,W ; restore original b3' in W
andwf VCMASK,W ; vcmask &= b3'
movwf VCMASK ;
xorwf VCBIT4,f ; b4 ^= vcmask
xorwf VCBIT4,W ; restore original b4' in W
andwf VCMASK,W ; vcmask &= b4'
movwf VCMASK ;
xorwf VCBIT5,f ; b5 ^= vcmask
xorwf VCBIT5,W ; restore original b5' in W
andwf VCMASK,W ; vcmask &= b5'
;
; alternate version of code above uses 10 words/31 cycles
; compared to 16 words/16 cycles
;
; lfsr 0,VCBIT2 ; can't mess up WREG
; lfsr 1,0x0004 ;
;vcinc movwf VCMASK ; save vcmask
; xorwf INDF0,f ; bn ^= (VCMASK)
; xorwf POSTINC0,W ; restore bn' in W
; andwf VCMASK,W ; vcmask &= bn'
; decfsz FSR1L,f ;
; bra vcinc ;
;
; apply repeat switch mask and and make any new repeating
; switch look like a "new" switch press by toggling its
; SWPEND switch pressed latch bit off.
;
andwf REPEAT,W ; mask non-repeat switches
xorwf SWPEND,f ; turn a "repeat" into a "new"
;
; update SWPEND debounced switch pressed latch
;
movf SWDATA,W ; debounced switch pressed bits
xorwf SWPEND,W ; xor switch pressed latch
xorwf SWPEND,f ; update switch pressed latch
;
; send a 32-msec short beep for new debounced switch presses
;
andwf SWDATA,W ; new debounced switch press?
btfss STATUS,Z ; no, skip, else
bsf BEEPER,5 ; send 32-msec short beep
;
; toggle SWITCH flag bits for processing by the MAIN program
;
; test SWITCH bits for emulated "toggle" switches. test then
; clear SWITCH bits for "momentary" and "repeat" switches.
;
xorwf SWITCH,f ; toggle SWITCH bits for MAIN
;
; advance ring counter prescaler (initialized value = 00000001)
; for the next interrupt cycle
;
rlncf COLPOS,f ; advance column ring counter
;
; beep (500-Hz tone with 1.0-msec interrupts)
;
movf BEEPER,W ; beep on?
bz ISR_Next ; no, branch, else
btg Speaker ; toggle piezo speaker pin
decf BEEPER,f ; decrement beep msec counter
;
ISR_Next