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 |