External Interrupts (NVIC)
Most of the GPIO pins on STM32 MCUs can trigger an interrupt. This page will explain how to configure that in STM32CubeIDE and how to deal with it in the C.
Video
Black Pill User Key
On the Black Pill development board there is a user key, which, according to the Schematics, are connected like this:
Worth noticing is:
- The button shorts to GND
- There is no pull-up or pull-down, so when not pressed, the PA0 is dangling.
STM32CubeMX Configuration
First step is to configure the required GPIO as an external interrupt. First, left-click on the required pin and select the appropriate option:
The GPIO Configuration can now be tweaked in the System Core section:
Finally, the NVIC needs to be configured to actually trigger the interrupt:
The C Code
Once the code has been generated by STM32CubeMX, the following code will be in 'stm32f4xx_it.c':
/** * @brief This function handles EXTI line0 interrupt. */ void EXTI0_IRQHandler(void) { /* USER CODE BEGIN EXTI0_IRQn 0 */ /* USER CODE END EXTI0_IRQn 0 */ HAL_GPIO_EXTI_IRQHandler(BTN_Pin); /* USER CODE BEGIN EXTI0_IRQn 1 */ /* USER CODE END EXTI0_IRQn 1 */ }
This will call a function in 'stm32f4xx_hal_gpio.c':
/** * @brief This function handles EXTI interrupt request. * @param GPIO_Pin Specifies the pins connected EXTI line * @retval None */ void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) { /* EXTI line interrupt detected */ if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); HAL_GPIO_EXTI_Callback(GPIO_Pin); } }
This finally calls:
/** * @brief EXTI line detection callbacks. * @param GPIO_Pin Specifies the pins connected EXTI line * @retval None */ __weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { /* Prevent unused argument(s) compilation warning */ UNUSED(GPIO_Pin); /* NOTE: This function Should not be modified, when the callback is needed, the HAL_GPIO_EXTI_Callback could be implemented in the user file */ }
By default, this function does nothing, but it is defined as weak, so the trick is to write your own version of this function, for example in the 'main.c' (or any other source file included in the project):
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == BTN_Pin) { btn_press = 1; } }
And that is all there is to it really.