Myke's Home Page
|
"Debounce" ExperimentAny time a switch is closed, the contacts will "bounce", which may be interpreted by the PICmicro® MCU as multiple button presses or key closures. There are many different ways to "debounce" an input, in this experiment, I demonstrate how to implement it using a polling loop. The circuit is identical to the one used by "LEDOn":
The parts needed for this experiment are listed in the table:
Using a breadboard, the experiment is wired using the guide:
If the EMU-II or YAP-II is used, the experiment is wired as:
The debounce operation can be modeled as the "C" pseudo-code:
Debounce_Down: // Wait for the Switch to be held down
// for 20 msec
while (Switch == Up); // Wait for the Switch to go down
for (Dlay = 0; (Switch == Down) && (Dlay < 20msec); Dlay++);
// Poll the Switch while Incrementing
// the Delay Timer
if (Dlay < 20msec)
goto Debounce_Down; // If 20 msecs has NOT passed, wait for
// Switch Down and Repeat Process
// When Execution reaches here, the switch is "Down" and Debounced
and was converted into the macro:
Debounce MACRO Port, Pin, Direction
if (Direction < 0) ; Going Down
btfsc Port, Pin
else
btfss Port, Pin ; Wait for Button Released
endif
goto $ - 1
movlw 0x0100 - 0x0C4 ; Initialize Dlay for a 20 msec
movwf Dlay ; Delay
movlw 0x0100 - 0x00A
movwf Dlay + 1
bcf STATUS, Z ; Make Sure that Zero is Reset
incfsz Dlay, f
goto $ + 2
incf Dlay + 1, f
if (Direction < 0)
btfsc Port, Pin
else
btfss Port, Pin ; Button Still Released?
endif
goto $ - 11 ; No - Loop Around Again
btfss STATUS, Z ; Zero Flag Set (20 mSecs Past?)
goto $ - 6
ENDM ; End the Macro
The source code listed below can be accessed from the CD-ROM by clicking Here.
title "debounce - Debounce Button input and Toggle LED"
;
; This Application waits for the button on RA0 to be released
; (for more than 20 msecs) and then when it has been pressed and
; stays constant for 20 msecs, the LED on RB0 is toggled. The
; Process then repeats.
;
; Hardware Notes:
; _MCLR is tied through a 4.7K Resistor to Vcc and PWRT is Enabled
; A 220 Ohm Resistor and LED is attached to PORTB.0 and Vcc
; A 10K pull up is connected to RA0 and it's state is passed to
; RB0
;
; Myke Predko
; 99.12.04
;
LIST R=DEC
ifdef __16F84
INCLUDE "p16f84.inc"
else
ifdef __16F877
INCLUDE "p16f877.inc"
endif
; Registers
CBLOCK 0x020
Dlay:2 ; Delay Value
ENDC
Up EQU 1 ; Flag Value for Debounce "Up"
Down EQU -1 ; Flag Value for Debounce "Down"
; Macros
Debounce MACRO Direction
if (Direction < 0) ; Going Down
btfsc PORTA, 0
else
btfss PORTA, 0 ; Wait for Button Released
endif
goto $ - 1
movlw 0x0100 - 0x0C4 ; Initialize Dlay for a 20 msec
movwf Dlay ; Delay
movlw 0x0100 - 0x00A
movwf Dlay + 1
bcf STATUS, Z ; Make Sure that Zero is Reset
incfsz Dlay, f
goto $ + 2
incf Dlay + 1, f
if (Direction < 0)
btfsc PORTA, 0
else
btfss PORTA, 0 ; Button Still Released?
endif
goto $ - 11 ; No - Loop Around Again
btfss STATUS, Z ; Zero Flag Set (20 mSecs Past?)
goto $ - 6
ENDM ; End the Macro
ifdef __16F84
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON
else
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON & _DEBUG_OFF & _LVP_OFF & _BODEN_OFF
endif
PAGE
; Mainline of ledon
org 0
nop
bsf PORTB, 0 ; Make LED on RB0 "off" Initially
bsf STATUS, RP0 ; Goto Bank 1 to set Port Direction
bcf TRISB & 0x07F, 0 ; Set RB0 to Output
bcf STATUS, RP0 ; Go back to Bank 0
Loop ; Loop Here
Debounce Up ; Wait for Key to Go Up
nop ; Location for Stopping after
; "Up" Debounce
Debounce Down ; Wait for Key to Go Down
comf PORTB, f ; Toggle the PORTB Value
goto Loop
end
|