/********************************* (C) РОТЕК *********************************** * @module buttons * @file buttons.c * @version 1.0.0 * @date XX.XX.XXXX * $brief buttons ******************************************************************************* * @history Version Author Comment * XX.XX.XXXX 1.0.0 Telenkov D.A. First release. ******************************************************************************* */ #include "common_config.h" #include "stm32f4xx.h" #include "buttons.h" #include "led.h" #include "settings_api.h" #include "commands_api.h" #include "FreeRTOS.h" #include "task.h" BUTTON_NO_FIX_t defButton; BUTTON_NO_FIX_t setButton; uint8_t DefCounter = 0; uint8_t SetCounter = 0; /** * @brief * @retval */ void BUTTON_Init(void) { defButton.id_pin = KEY_DEF; defButton.timeDelay = 5; defButton.pressHandler = BUTTON_DEF_UpHandler; defButton.unpressHandler = BUTTON_DEF_DownHandler; defButton.counterActivation = 0; defButton.timeActivation = 40; defButton.fActivation = false; defButton.stateOld = BUTTON_GetState(&defButton); setButton.id_pin = MODE_JUMPER; setButton.timeDelay = 5; setButton.pressHandler = BUTTON_SET_UpHandler; setButton.unpressHandler = BUTTON_SET_DownHandler; setButton.counterActivation = 0; setButton.timeActivation = 40; setButton.fActivation = false; setButton.stateOld = BUTTON_GetState(&setButton); } /** * @brief Возвращает сотояние ключа */ BUTTON_STATE_t BUTTON_GetState(BUTTON_NO_FIX_t *button) { return (BUTTON_STATE_t)gpio_get(button->id_pin); } /** * @brief Обработчик кнопки без фиксации. В обработчике реализована защита * от дребезга с помощью задержки. Защита срабатывает при нажатии * и при отпускании. * @param *button: указатель на структуру типа BUTTON_NO_FIX * @retval нет */ void BUTTON_NoFixHandler(BUTTON_NO_FIX_t *button) { uint8_t temp; if (button->stateNew != BUT_NO_DEFINE) { temp = gpio_get(button->id_pin); if (temp == 0) // определяем текущее (новое) состояние кнопки button->stateNew = BUT_ON; else button->stateNew = BUT_OFF; if (button->stateNew != button->stateOld) // зафиксирован факт нажатия/отжатия button->stateNew = BUT_NO_DEFINE; // переводим кнопку в неопределенное состояние } else { button->counterDelay++; // запускаем счетчик на задержку if (button->counterDelay > button->timeDelay) // задержка закончилась { button->counterDelay = 0; temp = gpio_get(button->id_pin); button->counterActivation = 0; if (temp == 0) // определяем текущее (новое) состояние кнопки { button->stateNew = BUT_ON; button->unpressHandler(); } else { button->stateNew = BUT_OFF; button->pressHandler(); } } } button->stateOld = button->stateNew; } /** * @brief Обработчик кнопки без фиксации. Кнопка срабатывает через определеное время нажатия. * @param *button: указатель на структуру типа BUTTON_NO_FIX * @retval нет */ void BUTTON_DellayHandler(BUTTON_NO_FIX_t *button) { /* Кнопка нажата. Ведем отсчет времени удержания */ if (gpio_get(button->id_pin) == 0) // определяем текущее (новое) состояние кнопки { button->counterActivation++; button->fActivation = false; /* Кнопка нажата более необходимого времени - начинаем чаще мигать диодом */ if (button->counterActivation > button->timeActivation) LED_SetStatusLedFreq(100); } /* Кнопку отжата. Если до этого она была нажата нужное время - вызываем хендлер */ else { if ((button->counterActivation > button->timeActivation) && button->fActivation == false) { button->fActivation = true; LED_SetStatusLedFreq(1000); button->unpressHandler(); } else button->counterActivation = 0; } } /** * @brief Опрос кнопок */ void vTaskButtons(void *pvParameters) { for (;;) { BUTTON_DellayHandler(&defButton); vTaskDelay(100); //20 } } /** * @brief Хендлер кнопки DEFAULT. */ void BUTTON_DEF_UpHandler(void) { DefCounter++; #ifdef LED_INIT_ERR LED_Off(LED_INIT_ERR); #endif #ifdef LED_ALARM LED_Off(LED_ALARM); #endif #ifdef LED_RED_MINOR LED_Off(LED_RED_MINOR); #endif } /** * @brief Хендлер кнопки DEFAULT. Сброс всех настроек, сохранение и перезагрузка */ void BUTTON_DEF_DownHandler(void) { #ifdef LED_INIT_ERR LED_On(LED_INIT_ERR); #endif #ifdef LED_ALARM LED_On(LED_ALARM); #endif #ifdef LED_RED_MINOR LED_On(LED_RED_MINOR); #endif fDefPressed = true; } /** * @brief Хендлер кнопки SET. */ void BUTTON_SET_UpHandler(void) { #ifdef LED_INIT_OK LED_On(LED_INIT_OK); #endif #ifdef LED_GREEN_MINOR LED_On(LED_GREEN_MINOR); #endif } /** * @brief Хендлер кнопки SET */ void BUTTON_SET_DownHandler(void) { SetCounter++; #ifdef LED_INIT_OK LED_Off(LED_INIT_OK); #endif #ifdef LED_GREEN_MINOR LED_Off(LED_GREEN_MINOR); #endif } /********************************* (C) РОТЕК **********************************/