0

我正在使用 TIM2 通用定时器闪烁 LED。

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

单击按钮时,应调用 EXTI 中断以使 LED 快速闪烁 20 次。但是,LED 保持亮起并完全停止闪烁。

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

您能否建议我如何调整 EXTI 的中断 ISR,以便它可以使用 TIM2 以及更快的闪烁。

4

1 回答 1

3

HAL_GPIO_EXTI_Callback()在中断上下文中运行 - 在那里闪烁指示器是不合适的,更不用说延迟了。在中断中运行时没有其他代码,并且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
    }
}
于 2020-02-18T19:22:12.097 回答