0
votes

I am blinking LED using TIM2 General timer.

Code in main.c

HAL_TIM_Base_Start_IT(&htim2);

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
    if(htim->Instance==TIM2){
        HAL_GPIO_TogglePin(GPIOB, LED_Pin);
    }
}

When the button is clicked EXTI interrupt should be called to blink the led faster 20 times. However, LED stays on and stops blinking at all.

void EXTI0_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
    if(GPIO_Pin == BT_Pin){
        for(volatile int i=20; i>0; i--){
            HAL_GPIO_TogglePin(GPIOB, LED_Pin);
            HAL_Delay(100);
        }
    }
}

Could you please advice how can i adjust interrupt ISR for EXTI so it will use TIM2 as well with faster blinking.

1
Not related, but the use of volatile here is unnecessary. - Clifford

1 Answers

3
votes

HAL_GPIO_EXTI_Callback() runs in the interrupt context - it is not appropriate to flash the indicator there much less include a delay. No other code while run while in the interrupt, and HAL_Delay() is probably not interrupt safe in any case.

Instead, in the button handler, set a down-counter to be decremented in the timer handler, and in the timer handler set the reload depending on the down-counter being zero or not. Something like this:

[I have not included the HAL calls to do the TODO's above, because I'd have to look them up, but that is the outline.]

volatile unsigned fast_flash_count = 0 ;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM2)
    {
        HAL_GPIO_TogglePin(GPIOB, LED_Pin);

        if( fast_flash_count > 0 )
        {
            fast_flash_count-- ;

            // Set TIM2 reload to fast-flash period
            TODO
        }
        else
        {
            // Set TIM2 reload to slow-flash period
            TODO
        }
    }
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == BT_Pin)
    {
        fast_flash_count = 20 ;

        // Set TIM2 counter to current reload value 
        // to force immediate interrupt
        TODO
    }
}