In this lesson, you will learn how to use timer-based filtering to eliminate mechanical "chatter" from switch inputs, ensuring your system registers a single clean transition.
The Mechanical Reality
When you press a physical button, the internal metal contacts don't meet perfectly. Instead, they bounce against each other for a few milliseconds, creating a rapid series of high-to-low and low-to-high voltage transitions. If your microcontroller is monitoring these inputs, it might interpret this "chatter" as dozens of rapid button presses rather than one.
The Timer-Based Filtering Solution
To solve this, we implement a filter that ignores any signal changes occurring within a short, predefined "stability window." Instead of responding to the initial edge detection (like we do with standard GPIO interrupts), we use a timer to wait until the signal has settled.
Here is the logic for a typical timer-based debounce:
- Detect Initial Edge: A GPIO interrupt triggers on the first transition.
- Disable Further Interrupts: Temporarily mask the interrupt to prevent re-triggering.
- Start Timer: Configure a hardware timer to expire after the debounce interval (e.g., 20ms).
- Verify State: When the timer interrupt fires, check the GPIO input pin again.
- Accept Transition: If the pin state remains stable, register the event. If it has reverted (due to a bounce), ignore the event and reset the system to watch for the next transition.
void GPIO_Interrupt_Handler() {
// 1. Disable interrupt to ignore noise
Disable_Interrupt(BUTTON_PIN);
// 2. Start a 20ms timer for stability check
Start_Timer(20ms);
}
void Timer_Callback() {
// 3. Verify the signal is still in the active state
if (Read_GPIO(BUTTON_PIN) == PRESSED_STATE) {
Perform_Action();
}
// 4. Clear flag and re-enable interrupt for next press
Clear_Timer_Flag();
Enable_Interrupt(BUTTON_PIN);
}
By leveraging the precision of hardware timers, we move the burden of "cleaning up" the signal away from the CPU's main loop and into a reliable, asynchronous peripheral sequence. This ensures that your system only reacts to intentional user input, not the mechanical imperfections of the switch.
Key Takeaway: By delaying the processing of an input signal using a timer-based stability window, you effectively filter out high-frequency mechanical noise to ensure accurate, single-event detection.