9
votes

I want to implement a GPIO-Interrupt, but I dont know how, I also found no real sample or explaination for it.

I already know how to write to Pins, but not much more, please consider that I dont really have any knowlegde about c or programming microcontrollers.

A simple example or explaination would help me alot. The following code is what I already have, but I am not sure if this is correct.

GPIO_InitTypeDef   GPIO_InitStructure;
GPIO_InitStructure.Pin = GPIO_PIN_2;
GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;

HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
2

2 Answers

22
votes

Since @Mouin has described the steps for you and you are using HAL already, here is how to execute those steps, so the way to configure it by using STM32CubeMX software provided by ST Microelectronics. (Note: Browsing that link is recommended as there are many-many examples for the STM32 family, STM32CubeF3 package for example.)

So in brief download it, create a new project for an STM32F3 Discovery board.

  1. On the Pinout tab, the MCU will be shown with all its pins. Just click on a pin and select a functionality you want. In your case GPIO_EXTI2 on PA2 pin:

    enter image description here

  2. Now switch to do Configuration tab, and in the last column called System, click on the GPIO button. Available options can be seen on the image below:

    enter image description here

  3. Next step is to enable the corresponding interrupt. To do so close the Pin Configuration window and from the System column, click on the NVIC button. If you remember, the EXTI2 has been chosen on PA2 so tick the Enable checkbox for EXTI line2. You can set the priorities here as well.

    enter image description here


Everything is ready, click on the Generate source code based on user settigns button → enter image description here. Following source files will be genereted:

enter image description here

GPIO configuration in gpio.c:

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __GPIOA_CLK_ENABLE();

  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

  /*Configure GPIO pin : PA2 */
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI2_TSC_IRQn, 0, 0); // <--- This and
  HAL_NVIC_EnableIRQ(EXTI2_TSC_IRQn); // <--- this are what were missing for you.

Interrupt service rutine in the stm32f3xx_it.c:

/**
* @brief This function handles EXTI line2 and Touch Sense controller.
*/
void EXTI2_TSC_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI2_TSC_IRQn 0 */

  /* USER CODE END EXTI2_TSC_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
  /* USER CODE BEGIN EXTI2_TSC_IRQn 1 */

  /* USER CODE END EXTI2_TSC_IRQn 1 */
}

This is what will be called when an interrupt is triggered, it will call an IRQ handler for the GPIO2 and if everything is fine, the following callback will be called. You have to write your handler code here.

/**
* @brief Interrupt callback for GPIOs
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if ( GPIO_Pin == GPIO_PIN_2)
    {
        // Write your code here
    }
}

You have to add the previous part manually (the callback), it has a weak declaration only but won't be generated. You can place it in the stm32f3xx_it.c .


If you want to learn more about the MCU, open up the reference manual and read the GPIO and NVIC section to know how it is done on register level.

4
votes

Typically when talking about interrupts there is 2 main things to configure :

CPU +------+ Interrupt Vector (NVIC) +--------+ Peripheral

On the peripheral side : you have to configure which kind of event you 're wating: for example a rising edge on a GPIO, timer ticks...besides you have to tell your peripheral to notify the NVIC once this event happen

On Interrupt vector side: CPU will get notified by the mean of the interrupt vector, so here, basically, you have to configure the priority of your interrupt and the ISR to execute.

If you do this correctly the CPU will execute the ISR once the interrupt happens.

In your code there is no configuration for the NVIC, also you forget the link between the NVIC and the GPIO. I hope i give you some help, you can search the in the internet for concise code.