Перейти к содержанию
    

Помогите с кнопками

Помогите пожалуйста реализовать.

1)Необходимо, чтоб некая функция начинала выполняться после кратковременного нажатия кнопки и прерывалась после повторного нажатия.

2)Эта же функция начинала выполняться во время длительного нажатия кнопки (на протяжении всего нажатия) и прекращала выполняться после отпускания.

Кнопка одна и та же.

Контроллер: AtMega8;

Язык программирования:Си.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Начните с обработчика нажатия кнопки и распознавания короткого и длительного нажатия

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Конечный автомат. Автоматное программирование. Цикл статей Татарчевского.

Есть нюанс. Так как кнопка одна, вам нужно тщательно продумать интерфейс, чтобы не было проблем. Нужно четко отличать, в каком состоянии какое нажатие. Иначе вы будете ожидать одной реакции на нажатия, а будет совершенно другая, так как не продуман интерфейс.

 

К примеру, исходное состояние девайса. Он должен ждать только короткое нажатие или только длинное. Или два коротких, к примеру. Два длинных.

В принципе, в одном состоянии можно ожидать короткое либо длинное нажатие. Но, повторяю, тщательно продумывайте. И без использования конечных автоматов не обойтись, если параллельно нужно выполнять какие-либо еще действия.

 

Программа будет примерно такая:

 

Опрос кнопки:

//========================================================================
#include "kbd_drv.h"
//========================================================================

//========================================================================
u08 _kbd_drv;

static u08 keys_buf;
//========================================================================

//========================================================================
void kbd_drv (void)
{
  switch (_kbd_drv)
  {
     case KBD_DRV_NONE: // Состояние ожидания нажатия кнопки.
        if (!(KNOPKA_PIN & (1<<KNOPKA))) // Если кнопка нажата,
        {
           set_timer (ST_KBD_1, DEBOUNCE_DELAY); // то установка таймера на подавление дребезга.
           _kbd_drv = KBD_DRV_DOWN;
        }
        break;

     case KBD_DRV_DOWN: // Подавление дребезга нажатия кнопки.
        if (KNOPKA_PIN & (1<<KNOPKA))
        {
           _kbd_drv = KBD_DRV_NONE;
        }
        else
        {
           if (wait (ST_KBD_1)) // Если время подавления дребезга вышло,
           {
              Set_Event (EV_ID_KEY_PRESSED, SET_CLR_EVENT);
              keys_buf = KEY_COD;

              set_timer (ST_KBD_1, HOLD_DELAY); // то установка таймера на проверку удержания кнопки.
              _kbd_drv = KBD_DRV_HOLD;
           }
        }
        break;

     case KBD_DRV_HOLD:
        if (KNOPKA_PIN & (1<<KNOPKA))
        {
           _kbd_drv = KBD_DRV_WAIT_UP; // Установка состояния ожидания отжатия кнопки.
        }
        else
        {
           if (wait (ST_KBD_1)) // Если время удержания кнопки вышло,
           {
              Set_Event (EV_ID_KEY_PRESSED, SET_CLR_EVENT);
              keys_buf = KEY_COD_HOLD;

              set_timer (ST_KBD_1, HOLD_DELAY);
           }
        }
        break;

     case KBD_DRV_WAIT_UP: // Состояние ожидания отжатия кнопки.
        if (KNOPKA_PIN & (1<<KNOPKA)) // Если кнопка отжата,
        {
            set_timer (ST_KBD_1, DEBOUNCE_DELAY); // то установка таймера на подавление дребезга.
            _kbd_drv = KBD_DRV_UP;
        }
        break;

     case KBD_DRV_UP: // Подавление дребезга отжатия кнопки.
        if (!(KNOPKA_PIN & (1<<KNOPKA))) // Если кнопка нажата,
        {
           _kbd_drv = KBD_DRV_WAIT_UP;
        }
        else
        {
           if (wait (ST_KBD_1)) // Если время подавления дребезга вышло,
           {
              Set_Event (EV_ID_KEY_UNPRESSED, SET_CLR_EVENT);
              _kbd_drv = KBD_DRV_NONE; // Установка состояния ожидания нажатия кнопки.
           }
        }
        break;

     default:
        break;
  }
}
//========================================================================

//========================================================================
u08 GetKeyCod (void)
{
  return keys_buf;
}
//========================================================================

 

Выбор режима в зависимости от нажатий кнопки:

//========================================================================
#include "proc_fsm.h"
//========================================================================

//========================================================================
void proc_fsm (void)
{
  static u08 _proc_fsm;

  switch (_proc_fsm)
  {
     case PROC_FSM_INIT:
        // Инициализация ввода-вывода
        _proc_fsm = PROC_FSM_WAIT_KEYS_PRESSED;
        break;

     case PROC_FSM_WAIT_KEYS_PRESSED:
        if (Get_Event (EV_ID_KEY_PRESSED)) // Если событие нажатия кнопки,
        {
           _proc_fsm = PROC_FSM_WAIT_SELECT_MODE; // то установка состояния выбора нажатия.
        }
        break;

     case PROC_FSM_WAIT_SELECT_MODE:
        if (Get_Event (EV_ID_KEY_UNPRESSED)) // Если событие отжатия кнопки, то это в любом случае было короткое нажатие.
        {
           set_led_1_blink_on (); // Включаем мигание светодиодом.
           _proc_fsm = PROC_FSM_MODE_1;
           return;
        }

        if (Get_Event (EV_ID_KEY_PRESSED)) // Если повторное событие нажатия кнопки, то это длинное нажатие кнопки.
        {
           led_1_on (); // Включаем светодиод.
           _proc_fsm = PROC_FSM_MODE_2;
           return;
        }
        break;

     case PROC_FSM_MODE_1:
        if (Get_Event (EV_ID_KEY_PRESSED)) // Если событие нажатия кнопки,
        {
           set_led_1_blink_off (); // то выключаем мигание светодиодом.
           _proc_fsm = PROC_FSM_WAIT_KEYS_PRESSED;
           return;
        }

        led_1_blink (); // Мигание светодиодом.
        break;

     case PROC_FSM_MODE_2:
        if (Get_Event (EV_ID_KEY_UNPRESSED)) // Если событие отжатия кнопки,
        {
           led_1_off (); // то выключаем светодиод.
           _proc_fsm = PROC_FSM_WAIT_KEYS_PRESSED;
        }
        break;

     default:
        break;
  }
}
//========================================================================

//========================================================================
static u08 _led_blink;

#pragma inline
void set_led_1_blink_on (void)
{
  led_1_on ();
  set_timer (ST_LED_1_BLINK, LED_1_TIME);
  _led_blink = 1;
}

#pragma inline
void set_led_1_blink_off (void)
{
  led_1_off ();
  _led_blink = 0;
}

#pragma inline
void led_1_blink (void)
{
  switch (_led_blink)
  {
     case 0:
        break;

     case 1:
        if (wait (ST_LED_1_BLINK))
        {
           led_1_switch ();
           set_timer (ST_LED_1_BLINK, LED_1_TIME);
        }
        break;

     default:
        break;
  }
}
//------------------------------------------------------------------------
#pragma inline
void led_1_on (void)
{
  set_bit (LED_1_DDR, LED_1);
}

#pragma inline
void led_1_off (void)
{
  clr_bit (LED_1_DDR, LED_1);
}

#pragma inline
void led_1_switch (void)
{
  switch_bit (LED_1_DDR, LED_1);
}
//========================================================================

Изменено пользователем demiurg1978

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Помогите пожалуйста реализовать.

1)Необходимо, чтоб некая функция начинала выполняться после кратковременного нажатия кнопки и прерывалась после повторного нажатия.

2)Эта же функция начинала выполняться во время длительного нажатия кнопки (на протяжении всего нажатия) и прекращала выполняться после отпускания.

Кнопка одна и та же.

Контроллер: AtMega8;

Язык программирования:Си.

Если на кнопку будет нажимать человек, то достаточно будет прерывания

(к примеру 1 ms) в котором опрашивать состояние кнопки.

Запоминать время нажатия и по отпусканию решать длительное/кратковременно оно было.

Обязательно позаботиться об устранении дребезга контактов кнопки.

На СИ это мне не под силу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Запоминать время нажатия и по отпусканию решать длительное/кратковременно оно было.Обязательно позаботиться об устранении дребезга контактов кнопки.

На СИ это мне не под силу.

так выше demiurg1978 Вам уже все очень даже подробно изложил, осталось только перенести в тело программы его код

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...