STM32 Button Debounce Code Examples [Tutorial]

In this tutorial, we’ll discuss how to implement STM32 Button Debouncing using different Button Debounce Techniques With STM32 microcontrollers. You’ll also learn how to use the STM32 systick timer to replace delay-based button (switch) debounce techniques. Without further ado, let’s get right into it!

Table of Contents

  1. STM32 Button Debounce Preface
  2. STM32 Button Debouncing Techniques
  3. STM32 Button Debounce Code Example
  4. Wrap Up

STM32 Button Debounce Preface

A push button is a mechanical switch that we use in all sorts of electronic projects. Ideally, a push button (switch) will connect two pins (leads) together when it’s held down which produces a perfect clean voltage transition on the input pin (High to Low or the opposite).

However, in the real world, this ideal behavior is not always how a push button behaves. The mechanical motion results in a contact bounce that therefore creates a jitter in the input voltage signal that we typically refer to as “switch bounce”.

I’ve captured an input pin signal while clicking a push button and here is how it looks on my oscilloscope. Those glitches in the digital signal are what we consider “button bouncing”.

I’ve clicked the push button hundreds of times in order to capture those bouncing glitches that you’ve seen in the oscilloscope’s screenshots above. This doesn’t mean that switch bouncing is a rare event, it does depend on the switch quality and some other factors. So it can be described as a random event.

❕ Note

Switch bouncing is a random event. This means it can happen and introduce aggressive sharp transitions to the input signal, or it can not happen at all. You need to press the push button multiple times to confirm the fact that this is a random event that doesn’t always happen. Yet we need to protect our systems against it.


STM32 Button Debouncing Techniques

There are so many techniques for button debouncing that you can use in your project and it just depends on the needs of your project. In this section, we’ll explore all possible button debouncing techniques as a general overview of what we’ll discuss in detail later on in this tutorial.

Button debouncing techniques can be categorized into the following two main categories:

  • Hardware Button Debouncing Techniques
  • Software Button Debouncing Techniques

Hardware button debouncing is to achieve button input debouncing with a hardware electronic circuit so that the microcontroller doesn’t have to deal with a noisy input and no extra software is required to handle such an issue in the first place.

  • RC Filter Circuit
  • Schmit Trigger Circuit
  • Flip-Flop Circuit
  • Special Debouncing ICs
  • etc…

Software button debouncing, on the other hand, saves you extra hardware electronic parts and uses different algorithms and a bit of the CPU time to process the incoming non-debounced signal and clean it out before sending it to the designated software component that needs this input signal.

  • Using delay
  • Using timers
  • Bit Shifting
  • Moving average (digital filter)
  • etc…

We’ll discuss a couple of software-based techniques in detail hereafter and see how to implement them with STM32 microcontrollers on real projects.

1. STM32 Button Debounce (With Delay)

The first and easiest software debouncing technique is to just insert a delay after reading the button input pin state. Then, we can read it again and make sure that the pin state didn’t change due to the button bouncing. In this way, we can guarantee that the input pin state change is not some random noise due to the button bouncing.

❕ Note

Using delay for button debouncing is not recommended at all. But if you’re prototyping something really quick and only need one button, this can suffice. However, I’d highly recommend that you keep going with this tutorial and check the other button debouncing techniques presented hereafter.

2. STM32 Button Debounce (With Delay + Counter)

This is a very similar method to the previous one, except the fact that it tries to make it less inefficient by reducing the delay amount and replacing that with a digital counter to count the consecutive times of the input pin state.

If the pin state has been high for 20 consecutive times, the button press event is confirmed. Otherwise, we’ll reset the counter and start all over again. With a delay of 1 ms, we expect the button to stay HIGH for 20 ms in order to register a confirmed button click event.

Here is the code example for STM32 Button Debouncing With Delay + Counter.

3. STM32 Button Debounce (Without Delay)

And now let’s get to some reliable debouncing techniques. First of which is the shown below which uses the built-in STM32’s SysTick Timer interrupt to keep track of elapsed time (SysTicks Counter Variable).

Instead of using delays, we’ll now keep track of time without forcing the CPU to busy wait with a delay function. Which was unnecessarily blocking the CPU, holding the system back, and potentially making it unscalable at all.

For this SysTick_Callback() handler function to work, you need to add a prototype for it in the main.h file as shown below:

And we need also to call it within the stm32f1xx_it.c file, inside the SysTick_Handler() function as shown below:

4. STM32 Button Debouncing (Moving Average Filter)

This is a very elegant button debouncing technique. And here is how it goes: We first call the  BtnScan() function at fixed time intervals (let’s say 5 ms).

In the  BtnScan() function, we create a circular buffer that holds the history of the push button states over the past n samples. Then, we apply a special case of the general FIR low-pass filter which is the “Moving Average Filter”. I’m not rigiously following the moving average filter’s formula, to be honest. The method shown in this example code is building on the same concept with a few tweaks to get even more robust results.

The buffer variable that holds the button states history is bit-wise manipulated to save on some space. So we don’t need to create an array of  uint8_t variables. And we count the 1’s in the variable using the  __builtin_popcount() function.

For this SysTick_Callback() handler function to work, you need to add a prototpye for it in the main.h file and call it inside the SysTick_Handler() function within the stm32f1xx_it.c file as shown in the earlier example.

❕ Note

The  __builtin_popcount() function is a standard built-in function in the GCC compiler itself. This function is used to count the number of 1’s bits in an unsigned integer variable. 

5. STM32 Button Debouncing (Bit-Shifting)

For this SysTick_Callback() handler function to work, you need to add a prototpye for it in the main.h file and call it inside the SysTick_Handler() function within the stm32f1xx_it.c file as shown in the earlier example.

❕ Note

Note that in the example above, I’m using a pull-down resistor for the button’s input pin. In case you’re using a pull-up inverted logic, the debounce function logic will need a small change and will be as follows. (We just need to invert the digital pin state read result)


STM32 Button Debounce Code Example

In this example project, we’ll use the STM32 button debouncing technique #5 which was illustrated in the previous section. We’ll define a couple of GPIO pins, one for an output LED, and the other for an input push button (pull-down).

Upon each button press event, the LED should be toggled. And we’ll observe both signals on a DSO (digital storage oscilloscope) to see the effectiveness of this debouncing technique in filtering the noisy button signal.

Step #1

Open STM32CubeMX, create a new project, and select the target microcontroller.

Step #2

Configure a GPIO pin in output mode (LED).

Configure a GPIO pin in input mode with internal pull-down (Push Button).

Step #3

Go to the RCC clock configuration page and enable the HSE external crystal oscillator input.

STM32 RCC External Clock Selection CubeMX

Step #4

Go to the clock configurations page, and select the HSE as a clock source, PLL output, and type in 72MHz for the desired output system frequency. Hit the “ Enter” key, and let the application solve for the required PLL dividers/multipliers to achieve the desired clock rate.

STM32-Blue-Pill-Proteus-Library-Simulation-Clock-Configuration

Step #5

Name & Generate The Project Initialization Code For CubeIDE or The IDE You’re Using.

STM32 Button Debouncing Example Code

Here is The Application Code For This LAB (main.c)

STM32 Button Debounce Example Testing

Here is the testing result of this example project running on my STM32 blue pill (F103C8T6) board.

Yellow Trace: Bouncy Push Button Signal

Blue Trace: Clean Output Signal on The LED

STM32 Switch Debounced Reading
In this screenshot, I was testing a press to turn LED on kind of behavior not the LED toggle on press. But it’s basically the exact same thing!


Required Parts For STM32 Examples

All the example Code/LABs/Projects in this STM32 Series of Tutorials are done using the Dev boards & Electronic Parts Below:

QTY.Component NameAmazon.comAliExpresseBay
1STM32-F103 BluePill Board (ARM Cortex-M3 @ 72MHz)AmazonAliExpresseBay
1Nucleo-L432KC (ARM Cortex-M4 @ 80MHz)AmazonAliExpresseBay
1ST-Link V2 DebuggerAmazonAliExpresseBay
2BreadBoardAmazonAliExpresseBay
1LEDs KitAmazonAmazonAliExpresseBay
1Resistors KitAmazonAmazonAliExpresseBay
1Capacitors KitAmazonAmazonAliExpress & AliExpresseBay & eBay
1Jumper Wires PackAmazonAmazonAliExpress & AliExpresseBay & eBay
1Push ButtonsAmazonAmazonAliExpresseBay
1PotentiometersAmazonAliExpresseBay
1Micro USB CableAmazonAliExpresseBay

★ Check The Links Below For The Full Course Kit List & LAB Test Equipment Required For Debugging ★

Download Attachments

You can download all attachment files for this Article/Tutorial (project files, schematics, code, etc..) using the link below. Please consider supporting our work through the various support options listed in the link down below. Every small donation helps to keep this website up and running and ultimately supports the whole community.


Wrap Up

In conclusion, we’ve explored different button debouncing techniques that can be used with any STM32 microcontroller. Delay-based button (switch) debounce techniques should work just fine, however, the provided examples in this tutorial will give you a much more reliable/expandable setup, and your CPU will be much more free to do more important processing tasks.

You can build on top of the example provided in this tutorial and/or explore the other STM32 tutorial series linked below.

Getting Started With STM32 (Tutorials)

Share This Page With Your Network!
Join Our +25,000 Newsletter Subscribers!

Stay Updated With All New Content Releases. You Also Get Occasional FREE Coupon Codes For Courses & Other Stuff!

Photo of author
Author
Khaled Magdy
Embedded systems engineer with several years of experience in embedded software and hardware design. I work as an embedded SW engineer in the Automotive & e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI/ML, and other fields I'm passionate about.
I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?

Leave a Comment