## [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
---

**PC13:** Configure as GPIO_EXTI for the button.
**PA5:** Configure as GPIO output for the LED.

GPIO mode: select Rising/Falling edge trigger detection.

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.

---
### 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.

---
### 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