STM32: How to use GPIO Input & Button-Controlled LED

Episode 3 – STM32 Basics_ Push Button - Cover Image Site

STM32 HAL Tutorial: Handling Push Buttons and Debouncing

Abstract

Learn how to configure STM32 GPIO input pins using CubeMX and HAL drivers. Step-by-step tutorial on controlling an LED with a push button and handling debouncing.

1. Introduction

In Episode 2, we learned how to blink an LED using STM32 HAL drivers.
Now, it’s time to read input from GPIO pins—a fundamental skill for interactive embedded systems.

In this episode, you’ll learn:

  • How to configure GPIO pins as input.
  • How to read button presses.
  • How to control an LED based on button input.
  • Techniques for debouncing mechanical switches.
Special thanks to Fritzing for the generated image.

This project will make your board react to user input, laying the foundation for more complex applications.

2. Prerequisites

Make sure you have:

  • A STM32 board (e.g., Nucleo or Discovery).
  • One push button (or use the on-board USER button).
  • One LED (on-board LED works).
  • STM32CubeIDE installed with a previously generated project (from Episode 2).

3. Configuring GPIO Input Pins in CubeMX

Step 1 – Open Your STM32CubeMX

  • Create a new project for the [STM32G071RBT6]

Step 2 – Set Button Pin Mode

  • Find the USER button pin, PC13 on NUCLEO-G071RB.
  • Click the pin → select GPIO_Input.
  • Optionally, enable Pull-Up if the button doesn’t have a resistor, which is not the case for the selected hardware:

📌 Pull-up ensures the pin reads HIGH when the button is not pressed.

Step 3 – Verify LED Pin

  • Ensure your LED pin is still configured as GPIO_Output. Refer to EP2 in case you have issues.

Step 4 – Generate Code

  • Click Project → Generate Code.
  • CubeMX updates the HAL initialization for your input pin.

4. Writing Button-Controlled LED Code

				
					/* USER CODE BEGIN WHILE */
while (1)
{
    // Read button state
    if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET) // Button pressed
    {
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);   // Turn LED ON
    }
    else
    {
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // Turn LED OFF
    }
}
/* USER CODE END WHILE */

				
			

Code Explanation

  • HAL_GPIO_ReadPin(GPIOx, PINx) → Reads HIGH or LOW from the button.
  • GPIO_PIN_RESET indicates the button is pressed (due to pull-up resistor).
  • HAL_GPIO_WritePin() sets the LED state based on button input.

5. Handling Button Debouncing

Mechanical buttons may generate multiple signals when pressed. This is called bouncing.

Simple Debounce Method

Add a short delay after detecting a press:

				
					if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET)
{
    HAL_Delay(50); // Wait 50ms
    if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET)
    {
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // Toggle LED
        while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET); // Wait for release
    }
}
				
			

Tip: 50ms delay is usually enough for most buttons.

6. Compiling and Running the Project

Step 1 – Build

  • Click Build (hammer icon) in STM32CubeIDE or [Ctrl + B].

Step 2 – Flash

  • Connect your STM32 board via USB.
  • Enter in Debug Mode and Run the code

Step 3 – Test

  • Press the button: LED should toggle ON/OFF.
  • Release button: LED remains in last state.
  • Monitor the GPIOA ODR5 and GPIOC IDR13 in the [SFRs].

7. Common Issues & Fixes

Issue Cause Solution
LED doesn’t respond to button Wrong GPIO pin Check CubeMX configuration
LED toggles multiple times Button bouncing Implement debounce using HAL_Delay()
Compilation error Pin or HAL not initialized Regenerate CubeMX code

8. Hands-On Lab Recap

You’ve learned:

  • How to configure GPIO pins as input using CubeMX.
  • How to read push button states with HAL.
  • How to control an LED with a button.
  • How to debounce a mechanical switch.

This adds interactivity to your STM32 projects, preparing you for timers, interrupts, and sensors in the next tutorials.

9. What’s Next

In Episode 4, we’ll explore External Interrupts (EXTI):

  • Configure GPIO pins to trigger interrupts.
  • Learn real-time button handling without polling.
  • Improve performance and responsiveness for embedded applications.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top