Реализация выбора при длительном и коротком нажатии в STM32: изучено несколько методов

В этой статье блога мы рассмотрим различные методы реализации выбора длительного и короткого нажатия в микроконтроллерах STM32. Мы рассмотрим различные методы, в том числе подходы на основе прерываний, устранение дребезга и программные таймеры, попутно предоставляя примеры кода. Давайте погрузимся!

Метод 1: подход на основе прерываний
Одним из распространенных методов обработки нажатий кнопок в STM32 является использование прерываний. Вот пример того, как можно реализовать длинное и короткое нажатие с помощью прерываний:

// Define the button pin and its corresponding interrupt line
#define BUTTON_PIN GPIO_PIN_0
#define BUTTON_PORT GPIOA
#define BUTTON_EXTI_LINE EXTI_LINE_0
// Interrupt handler for button press
void EXTI0_IRQHandler(void)
{
    // Check if the interrupt was generated by the button
    if (__HAL_GPIO_EXTI_GET_IT(BUTTON_EXTI_LINE) != RESET)
    {
        // Clear the interrupt flag
        __HAL_GPIO_EXTI_CLEAR_IT(BUTTON_EXTI_LINE);
        // Perform short press actions
        // ...
        // Delay for detecting a long press
        HAL_Delay(1000);
        // Check if the button is still pressed after the delay
        if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) == GPIO_PIN_RESET)
        {
            // Perform long press actions
            // ...
        }
    }
}

Метод 2: техника устранения дребезга
Подпрыгивание кнопок — распространенная проблема, которая может привести к ложным срабатываниям. Чтобы смягчить эту проблему, можно использовать методы устранения дребезга. Вот пример использования базового алгоритма устранения дребезга:

// Define the button pin
#define BUTTON_PIN GPIO_PIN_0
#define BUTTON_PORT GPIOA
// Global variables
GPIO_PinState buttonState = GPIO_PIN_RESET;
uint32_t buttonPressStartTime = 0;
// Button polling function
void pollButton(void)
{
    // Read the current button state
    GPIO_PinState currentState = HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
    // Check for a button press
    if (currentState == GPIO_PIN_SET && buttonState == GPIO_PIN_RESET)
    {
        // Record the button press start time
        buttonPressStartTime = HAL_GetTick();
        buttonState = GPIO_PIN_SET;
    }
// Check for a button release
    else if (currentState == GPIO_PIN_RESET && buttonState == GPIO_PIN_SET)
    {
        // Calculate the press duration
        uint32_t pressDuration = HAL_GetTick() - buttonPressStartTime;
        // Perform actions based on press duration
        if (pressDuration < 1000)
        {
            // Short press actions
            // ...
        }
        else
        {
            // Long press actions
            // ...
        }
        buttonState = GPIO_PIN_RESET;
    }
}

Метод 3: подход с программным таймером
Использование программных таймеров позволяет более точно контролировать время и позволяет избежать блокировки системы. Вот пример использования функции программного таймера библиотеки STM32 HAL:

// Define the button pin
#define BUTTON_PIN GPIO_PIN_0
#define BUTTON_PORT GPIOA
// Global variables
TIM_HandleTypeDef htimer;
uint32_t buttonPressStartTime = 0;
uint8_t buttonState = 0;
// Timer callback function
void timerCallback(void)
{
    if (buttonState == 1)
    {
        // Get the current time
        uint32_t currentTime = HAL_GetTick();
        uint32_t pressDuration = currentTime - buttonPressStartTime;
        // Perform actions based on press duration
        if (pressDuration < 1000)
        {
            // Short press actions
            // ...
        }
        else
        {
            // Long press actions
            // ...
        }
    }
}
// Button interrupt handler
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == BUTTON_PIN)
    {
        // Start or restart the timer
        buttonPressStartTime = HAL_GetTick();
        buttonState = 1;
        HAL_TIM_Base_Start_IT(&htimer);
    }
}
// Timer initialization
void initTimer(void)
{
    htimer.Instance = TIM2;
    htimer.Init.Prescaler = HAL_RCC_GetHCLKFreq() / 1000 - 1;
    htimer.Init.Period = 1 - 1;
    HAL_TIM_Base_Init(&htimer);
}

В этой статье мы рассмотрели несколько методов реализации выбора длительного и короткого нажатия в микроконтроллерах STM32. Мы рассмотрели подходы, основанные на прерываниях, методы устранения дребезга и программные таймеры. В зависимости от ваших конкретных требований и ограничений вы можете выбрать наиболее подходящий метод для вашего приложения. Не стесняйтесь экспериментировать с предоставленными примерами кода и адаптировать их к своим потребностям. Приятного программирования на STM32!