Close

Software Switch Debouncing

A project log for SCPI-over-Ethernet Foot Controller

A microcontroller-based solution to foot-controlling test equipment.

john-wJohn W. 06/05/2016 at 21:420 Comments

There are countless code examples for debouncing a switch solely with software, but there's really no reason to use an example, it only takes a few lines of C to do this, even for a relative beginner like me. Here's what I came up with:

void ISR_Debounce ( uintptr_t context, uint32_t alarmCount )
{
    if((BSP_SwitchStateGet(BSP_SWITCH_1) == BSP_SWITCH_STATE_PRESSED) && debounceData.sw1counter < 5)
        debounceData.sw1counter++;
    if(BSP_SwitchStateGet(BSP_SWITCH_1) == BSP_SWITCH_STATE_RELEASED) debounceData.sw1counter = 0;
    if((BSP_SwitchStateGet(BSP_SWITCH_2) == BSP_SWITCH_STATE_PRESSED) && debounceData.sw2counter < 5)
        debounceData.sw2counter++;
    if(BSP_SwitchStateGet(BSP_SWITCH_2) == BSP_SWITCH_STATE_RELEASED) debounceData.sw2counter = 0;
    appData.dbSwitch1 = (debounceData.sw1counter == 5) ? 1 : 0; //Ternary for setting debounce output.
    appData.dbSwitch2 = (debounceData.sw2counter == 5) ? 1 : 0;

sw1counter and sw2counter are defined in my debounceData structure as uint8's, and dbSwitch1 and dbSwitch2 in the appData struct are bools.

The function parameters (uintptr_t context and uint32_t alarmCount) are there because the callback parameter in the dynamic timer driver is defined like this:

typedef void (* DRV_TMR_CALLBACK)(uintptr_t context, uint32_t alarmCount);

So you give it what it wants, right? :) I did a little copying from Microchip's typo-ridden Harmony examples.

Here's the business:

  1. Every X number of timer ticks (as defined when you register the timer alarm) the debounce ISR function runs.
  2. A switch is first checked if it's pressed and the counter variable is less than 5. If both of these conditions are met, the counter is incremented.
  3. If the switch is in its released state, the counter is reset back to 0.
  4. A ternary operation is used to set the debounced output. If the counter is 5, the output is true.

This just implements a really simple kind of low-pass button-press filtering. In Verilog, I've seen the same technique used, but with a several-bit-wide shift register. All the bits in the register are ANDed together, so when the register fills with 1's from a button press, the output of the AND gate is your debounced button bit.

Discussions