Electronic – STM32F4 HAL Library Button Interrupt

armgpio-external-interruptinterruptsstm32cubemxstm32f4

I'm trying to toggle built in LED with external interrupt instead of while loop. Probably I'm doing something wrong with EXTI functions. Can you help me to fix it?

Here is my code:

#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"


void SystemClock_Config(void);

void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_0) 
    {
HAL_NVIC_DisableIRQ(EXTI0_IRQn);
    HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);
HAL_Delay(100);
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
  }
}

void EXTI0_IRQHandler(void)
{
  HAL_NVIC_ClearPendingIRQ(EXTI0_IRQn);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  {
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
    HAL_GPIO_EXTI_Callback(GPIO_PIN_0);
  }
}
}





void SysTick_Handler(void)
{
    HAL_IncTick();
}



int main(void)
{
  /* Reset of all peripherals, Initializes the Flash interface and the 
Systick. */
  HAL_Init();


  /* Configure the system clock */
  SystemClock_Config();
  /* Initialize all configured peripherals */
        __HAL_RCC_GPIOD_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

GPIO_InitTypeDef GPIO_InitLED;
GPIO_InitLED.Pin = GPIO_PIN_12;
GPIO_InitLED.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitLED.Pull = GPIO_NOPULL;
GPIO_InitLED.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_InitLED);

GPIO_InitTypeDef GPIO_InitButton;
GPIO_InitButton.Pin = GPIO_PIN_0;
GPIO_InitButton.Mode = GPIO_MODE_IT_RISING;
GPIO_InitButton.Pull = GPIO_PULLUP;
GPIO_InitButton.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitButton);


HAL_NVIC_SetPriority(EXTI0_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); 

}





static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
clocks
dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); }

Best Answer

@Bence I checked MXCube generated code and it solved the problem much easier. It does not require the "callback" function, only "handler".

@Tut Yes you're right. It requires a loop in main code.

Changes in my code:

1)

void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)

Deleted

2)

void EXTI0_IRQHandler(void)

Changed to

void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */
    if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)) HAL_GPIO_TogglePin(GPIOD, 
GPIO_PIN_12);
  HAL_Delay(50);
    /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  /* USER CODE BEGIN EXTI0_IRQn 1 */

  /* USER CODE END EXTI0_IRQn 1 */

}

3) Added

while(1)
{

}

4) Button pull options is changed to "GPIO_NOPULL".