---
# System prepended metadata

title: '[STM32 GPIO EXTI] - Detection of the falling and rising edges of a button press and relase'

---

## [STM32 GPIO EXTI] - Detection of the falling and rising edges of a button press and release
**Board:** NUCLEO-F072RB
**IDE:** STM32CubeIDE

---
### Introduction
---
This article introduces how to use GPIO interrupt (EXIT) to detect the button press or release via falling and rising edges and use HAL_GetTick() to measure the time, determining whether the button is a short press or a long press. If it's a long press, the LED will blink.

---
### STM32CubeMX settings
---
![image](https://hackmd.io/_uploads/SyRoka7F0.png)
**PC13:** Configure as GPIO_EXTI for the button.
**PA5:**  Configure as GPIO output for the LED.

![image](https://hackmd.io/_uploads/Sy1re67FC.png)
GPIO mode: select Rising/Falling edge trigger detection.

![image](https://hackmd.io/_uploads/S1qhg6QKR.png)
Enable EXTI interrupts.

---
### HAL_GPIO_EXTI_IRQHandler()
---
**stm32f0xx_it.c:** you can see *HAL_GPIO_EXTI_IRQHandler()* in *EXTI4_15_IRQHandler()*, the function will be called when the button is pressed or released.
![image](https://hackmd.io/_uploads/Hkp0lpXFA.png)

---
### HAL_GPIO_EXTI_Callback()
---
**stm32f0xx_hal_gpio.h:** you can see HAL_GPIO_EXTI_Callback(), we will use it to write some button long press and short press logic.
![image](https://hackmd.io/_uploads/HkORWpmKC.png)

---
### main.c
---
When the callback function HAL_GPIO_EXTI_Callback() is called, use HAL_GPIO_ReadPin() to detect falling or rising edge trigger. 
* **Falling edge:** GPIO_PIN_RESET
* **Rising edge:** GPIO_PIN_SET

If the button is pressed for more than 1 second, set isLongPressed to true. Then, in the super loop, the LED blinking will be triggered. Since interrupts are not suitable for time-consuming operations, the blinking is handled outside the interrupt.
```c=
//main.c
#define LONG_PRESS_THR (1000) //1 second
uint32_t btnPressTime = 0;
uint32_t btnReleaseTime = 0;
uint32_t btnPressDuration = 0;
bool isLongPressed = false;

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_PIN_13 == GPIO_Pin) {//Check if the button is triggered
        if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_Pin)) { //Falling edge
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); //Turn on the LED when button is pressed
            btnPressTime = HAL_GetTick(); //Record the time the button is pressed
            
        } else {//Rising edge
            btnReleaseTime = HAL_GetTick(); //Record the time the button is released
            btnPressDuration = btnReleaseTime - btnPressTime; //Calculate the duration from when the button is pressed to when it is released

            if (LONG_PRESS_THR < btnPressDuration) { //Check if the duration exceeds the long press threshold
                isLongPressed = true; //Set the flag to true for the main while() loop to detect
            
            } else {
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); //Turn off the LED if the button is short-pressed
            }
        }
    } 
}
```
Since HAL_Delay() cannot be used within an interrupt callback function,handle the LED blinking in this main loop.
Additionally, avoid using HAL_GPIO_TogglePin() to ensure the LED is turned off in each iteration.
```c=
//main.c
while (1) {
    if (isLongPressed) {
        isLongPressed = false;
          
        uint8_t i;
        for (i = 0; 5 > i; i++) {
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
            HAL_Delay(100);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
            HAL_Delay(100);
        }
    }
}
```
---
### Youtube Video
---
{%youtube YGOQh48LIOM %}

When the button is pressed, the green LED turns ON; otherwise, when the button is released, the green LED turns OFF.

If the button is pressed for more than 1 second, the green LED will start blinking after the button is released.

---
### Reference
---
* https://wiki.st.com/stm32mcu/wiki/Getting_started_with_GPIO