maximan 0 22 октября, 2015 Опубликовано 22 октября, 2015 · Жалоба Помогите пожалуйста реализовать. 1)Необходимо, чтоб некая функция начинала выполняться после кратковременного нажатия кнопки и прерывалась после повторного нажатия. 2)Эта же функция начинала выполняться во время длительного нажатия кнопки (на протяжении всего нажатия) и прекращала выполняться после отпускания. Кнопка одна и та же. Контроллер: AtMega8; Язык программирования:Си. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость TSerg 22 октября, 2015 Опубликовано 22 октября, 2015 · Жалоба Начните с чего-нибудь, уж. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexeyv 0 22 октября, 2015 Опубликовано 22 октября, 2015 · Жалоба 1. Начните с обработчика нажатия кнопки и распознавания короткого и длительного нажатия Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 22 октября, 2015 Опубликовано 22 октября, 2015 (изменено) · Жалоба Конечный автомат. Автоматное программирование. Цикл статей Татарчевского. Есть нюанс. Так как кнопка одна, вам нужно тщательно продумать интерфейс, чтобы не было проблем. Нужно четко отличать, в каком состоянии какое нажатие. Иначе вы будете ожидать одной реакции на нажатия, а будет совершенно другая, так как не продуман интерфейс. К примеру, исходное состояние девайса. Он должен ждать только короткое нажатие или только длинное. Или два коротких, к примеру. Два длинных. В принципе, в одном состоянии можно ожидать короткое либо длинное нажатие. Но, повторяю, тщательно продумывайте. И без использования конечных автоматов не обойтись, если параллельно нужно выполнять какие-либо еще действия. Программа будет примерно такая: Опрос кнопки: //======================================================================== #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); } //======================================================================== Изменено 22 октября, 2015 пользователем demiurg1978 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 22 октября, 2015 Опубликовано 22 октября, 2015 · Жалоба Помогите пожалуйста реализовать. 1)Необходимо, чтоб некая функция начинала выполняться после кратковременного нажатия кнопки и прерывалась после повторного нажатия. 2)Эта же функция начинала выполняться во время длительного нажатия кнопки (на протяжении всего нажатия) и прекращала выполняться после отпускания. Кнопка одна и та же. Контроллер: AtMega8; Язык программирования:Си. Если на кнопку будет нажимать человек, то достаточно будет прерывания (к примеру 1 ms) в котором опрашивать состояние кнопки. Запоминать время нажатия и по отпусканию решать длительное/кратковременно оно было. Обязательно позаботиться об устранении дребезга контактов кнопки. На СИ это мне не под силу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mcheb 0 23 октября, 2015 Опубликовано 23 октября, 2015 · Жалоба Это только за пиво, причём очень хорошее Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MarkOne 0 24 октября, 2015 Опубликовано 24 октября, 2015 · Жалоба ...Запоминать время нажатия и по отпусканию решать длительное/кратковременно оно было.Обязательно позаботиться об устранении дребезга контактов кнопки. На СИ это мне не под силу. так выше demiurg1978 Вам уже все очень даже подробно изложил, осталось только перенести в тело программы его код Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться