Push buttons switches are commonly used input devices. It takes some effort to filter out the glitches caused by contact bouncing in order to get a steady signal. Especially if the switch is a Single Pole Single Throw (SPST) kind of type. This blog describes a digital filter which will eliminate any glitches from a push button output signal.
This GAL22V10 implementation is intended for educational purposes. A more efficient way is to implement it in software on a microcontroller or in a CPLD/FPGA.
- SPST switch debouncing
- Oscillator with 3 passive R & C
- Digital filter design
- One GAL or ATF22V10
LET’S GET STARTED
The GAL comprises an oscillator circuit, a 4-bit counter and flip-flops (FFs). The filter time is defined by the clock frequency and the counter’s maximum value. A FF samples BUTTON continuously and thus synchronizes it with clock (CLK). As long as BUTTON input is steady, the counter counts up until 15. On count 15 the counter is disabled and the output FF is enabled. The next positive transition of CLK updates the output (DEBOUNCED). A steady input signal is transfered to the output after 18 clock cycles. Any change of the sampled input signal is detected by an XOR gate which compares the current sample with the one before. This ‘input has changed’ signal of the XOR output resets the counter.
A practical value for the filter time is 20ms. Timing resistors should be equal for a 50% duty cycle and greater 1k.
In this screen shot the input thresholds (ca. 1.5V), as well as the input clamping (ca. -1V) is shown. It’s taken from an actual ATF22V10CQZ oscillator circuit.
This oscillator design was chosen because two stage inverter oscillator circuits will not work reliably with the Atmel Zero Power types.
MODULE TITLE 'PUSH BUTTON DEBOUNCER' "Yorck Thiele, December 2020 DEVICE 'p22V10'; "INPUTS CLK pin 1; BUTTON pin 2; "OUTPUTS Q3,Q2,Q1,Q0 pin 17,18,19,20 istype 'reg'; DEBOUNCED pin 23 istype 'reg'; BTN_SAMPLE pin 22 istype 'reg'; BTN_SYNC pin 21 istype 'reg'; OSC_CTRL pin 16 istype 'com'; OSC_RC1 pin 15 istype 'com'; OSC_RC2 pin 14 istype 'com'; "fosc=0.44/(R*C) " ___ "OSC_RC1 ---o---|_R_|-o VCC " __|__ " _____ C " | ___ "OSC_RC2 ---o---|_R_|-o VCC count=[Q3..Q0]; BTN_CHANGED=(BTN_SAMPLE $ BTN_SYNC); EQUATIONS when BTN_CHANGED==1 then count:=0 else when (count!=15) then count:=count+1 else count:=count; when count==15 then DEBOUNCED:=BTN_SAMPLE else DEBOUNCED:=DEBOUNCED; BTN_SYNC:=BUTTON; BTN_SAMPLE:=BTN_SYNC; count.clk=CLK; BTN_SAMPLE.clk=CLK; BTN_SYNC.clk=CLK; DEBOUNCED.clk=CLK; OSC_RC1.OE = !OSC_CTRL; OSC_RC1=0; OSC_RC2.OE = OSC_CTRL; OSC_RC2=0; OSC_CTRL= (!OSC_RC1 & OSC_RC2) # (!(OSC_RC1 & !OSC_RC2) & OSC_CTRL); " RS flip flop Q = S + /R * Q END