Использование Tim2 внутри обработчика прерываний для STM32F1 - PullRequest
0 голосов
/ 18 февраля 2020

Я мигаю светодиодом, используя таймер TIM2 General. Код в основном. c

HAL_TIM_Base_Start_IT(&htim2);

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

При нажатии кнопки необходимо вызвать прерывание EXTI для более быстрого мигания светодиода в 20 раз. Тем не менее, светодиод остается включенным и перестает мигать вообще.

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);
        }
    }
}

Не могли бы вы посоветовать, как я могу настроить прерывание ISR для EXTI, чтобы он также использовал TIM2 с более быстрым миганием.

1 Ответ

3 голосов
/ 18 февраля 2020

HAL_GPIO_EXTI_Callback() работает в контексте прерывания - неправильно указывать sh индикатор, который намного меньше включает задержку. Никакой другой код во время работы в режиме прерывания, и HAL_Delay(), вероятно, не является безопасным для прерывания в любом случае.

Вместо этого в обработчике кнопки установите понижающий счетчик, который будет уменьшен в обработчике таймера, и в обработчике таймера установите перезагрузку в зависимости от того, равен ли счетчик нулю или нет. Примерно так:

[Я не включил вызовы HAL для выполнения TODO выше, потому что мне пришлось бы их искать, но это план.]

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
    }
}
...