STM32定时器中断意外行为

时间:2018-06-14 11:56:52

标签: timer interrupt stm32 stm32f4discovery st

我想实现长按按钮来打开设备。 我使用外部中断按钮在按下时启动计时器,并在释放按钮时停止并重置计时器。如果按住按钮足够(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 */
}

这是定时器中断处理程序

    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的触发事件设置为"更新事件"

1 个答案:

答案 0 :(得分:0)

我会建议以下实施:

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

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