首页 文章

STM32定时器中断意外行为

提问于
浏览
0

我想实现长按按钮来打开设备 . 我使用外部中断按钮在按下时启动计时器,并在释放按钮时停止并重置计时器 . 如果按住按钮足够(1秒),它将调用Timer_Update事件并打开LED .

但是,当我将代码加载到Discovery并按下复位时,第一次按下用户按钮会立即点亮LED,就像在第一次启动Timer时产生中断一样 . 然后它正常工作 - 如果按住按钮> = 1秒,则更改LED状态 .

项目通过CubeMX生成

这是按钮中断处理程序

void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */
    static uint8_t is_pressed = 0;
  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  /* USER CODE BEGIN EXTI0_IRQn 1 */
    if (!is_pressed) {
        HAL_TIM_Base_Start_IT(&htim7);
        HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_13);
        is_pressed = 1;
    }
    else {
        HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_13);
        HAL_TIM_Base_Stop_IT(&htim7);
        __HAL_TIM_SET_COUNTER(&htim7, 0);
        is_pressed = 0;
    }
  /* USER CODE END EXTI0_IRQn 1 */
}

这是Timer中断处理程序

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_14);
    HAL_TIM_Base_Stop_IT(htim);
    __HAL_TIM_SET_COUNTER(htim, 0);
}

CubeMX中Timer的触发事件设置为“Update Event”

1 回答

  • 0

    我建议以下实现:

    设置上升沿和下降沿的EXTI引脚检查中断处理程序中的引脚状态(而不是is_pressed变量)

    EXTI处理程序可以像下面这样实现:

    #define BUTTON_GPIO                GPIOA
    #define BUTTON_PIN                 GPIO_PIN_0
    #define BUTTON_PRESSED_STATE       GPIO_PIN_RESET
    
    void EXTI0_IRQHandler(void)
    {        
        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
    
        if (HAL_GPIO_ReadPin(BUTTON_GPIO, BUTTON_PIN) == BUTTON_PRESSED_STATE ) {
            HAL_TIM_Base_Start_IT(&htim7);
            __HAL_TIM_SET_COUNTER(&htim7, 0);
            HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET);
        } else {
            HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);
            HAL_TIM_Base_Stop_IT(&htim7);
        }
    }
    

相关问题