3
\$\begingroup\$

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); }
\$\endgroup\$
  • 1
    \$\begingroup\$ Complete process: stackoverflow.com/a/40061542/3820025 \$\endgroup\$ – Bence Kaulics Sep 27 '17 at 10:37
  • 2
    \$\begingroup\$ I don't use HAL or STM32CubeMx generated code, but isn't there supposed to be a loop in main()? \$\endgroup\$ – Tut Sep 27 '17 at 10:55
2
\$\begingroup\$

@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".

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.