External Interrupts (NVIC)

From Stm32World Wiki
Jump to navigation Jump to search

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:

Black Pill User Key.png

Worth noticing is:

  1. The button shorts to GND
  2. 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:

GPIO EXTI.png

The GPIO Configuration can now be tweaked in the System Core section:

GPIO Config.png

Finally, the NVIC needs to be configured to actually trigger the interrupt:

GPIO NVIC.png

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.

Miscellaneous Links