| Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
Как отследить короткое и продолжительное нажатие кнопки в фонаре?
15.04.2011, 08:59
|
|
|
Временная регистрация
Регистрация: 11.04.2011
Сообщений: 54
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от oleg_harp
|
А вот этот кусок нерабочий. Пока у Вас нажата кнопка каждые 10mS переменная state будет инвертироваться (cnt же будет проходить значения от 4 до скольких-нибудь), и из этого If state будет выходить каждый раз с неопределенным значением.
|
Код:
|
if ((cnt › 3) && (cnt ‹ 100)) { // проверяем условие короткого нажатия (держали › 40 мс и ‹ 1 сек; 10мс * 100 срабатываний)
// заодно и подавляем дребезг 40 мс (10 мс * 4 срабатывания)
if (!state) { // если фонарь выключен, то
OCR2=0x7D; // установили 50% ШИМ
TCCR2=0x6A; // запустили таймер (вкл)
state = 1; // флаг что фонарь включен
}
else if (state) { // если фонарь включен, то
OCR2=0x00; // выключили ШИМ
TCCR2=0x00; // остановили таймер (выкл)
state = 0; // флаг что фонарь выключен
}
}
if (cnt › 100) { // если держим › 1 сек - это длинное нажатие
long_push = 1; // потом проверяем long_push в основном цикле
}
} |
|
Точно!!! Понял. Сейчас ломаю голову как переделать этот кусок
|
|
|
|
15.04.2011, 09:58
|
|
|
Временная регистрация
Регистрация: 11.04.2011
Сообщений: 54
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
В коде реализовать не могу
Итак:
1. Как только заметили ноль на пине, нужно подождать 40-50 мс и проверить ещё раз пин;
2. Если там по прежнему ноль, то это не помеха/дребезг.
3. Запустить при этом увеличение какой либо переменной.
4. Если на выходе стал 1 (кнопку отпустили) то остановить приращение переменной.
5. Посмотреть до скольки досчитали, если меньше отсечки "длинного нажатия", то это короткое нажатие, если больше - то это долгое нажатие
6. Сбросить всё, вернуться в режим ожидания.
Но как это записать в прерывании не знаю. Туповат
|
|
|
|
15.04.2011, 11:06
|
|
|
Прописка
Регистрация: 25.08.2007
Сообщений: 193
Сказал спасибо: 11
Сказали Спасибо 57 раз(а) в 33 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
|
Цитата:
|
|
Но как это записать в прерывании не знаю.
|
Прерывание по таймеру используется только для тактирования последовательного цикла.
|
Цитата:
|
Итак:
1. Как только заметили ноль на пине, нужно подождать 40-50 мс и проверить ещё раз пин;
2. Если там по прежнему ноль, то это не помеха/дребезг.
3. Запустить при этом увеличение какой либо переменной.
4. Если на выходе стал 1 (кнопку отпустили) то остановить приращение переменной.
5. Посмотреть до скольки досчитали, если меньше отсечки "длинного нажатия", то это короткое нажатие, если больше - то это долгое нажатие
6. Сбросить всё, вернуться в режим ожидания.
|
Вы не учитываете, что при отпускании кнопки происходит такой же дребезг как и при нажатии. По вашему заданию не обойтись без отслеживания изменения состояния пина. Поэтому алгоритм такой:
1. начало цикла
2. проверить изменение пина (для этого испольуется Prev_PIN_State)
если изменений нет -› начало цикла
если есть, запомнить значение пина (0 или 1) сделать задержку на дребезг (переменная Time), после задержки проверить значение пина. Если изменилось -› начало цикла
Если нет - кнопка сработала.
3. Если кнопку нажали, запустить таймер (переменная Time) для оценки времени удержания кнопки (больше или меньше 1сек )
если кнопку отпустили:
в режиме выключено - включить фонарь,
в режиме включено - выключить фонарь,
в режиме регулировка яркости - отставить фонарь включённым, выйдя из режима регулировки яркости.
4. Если во включенном режиме кнопка удерживалась 1сек включить режим регулировки яркости и регулировать.
5. -› начало цикла
Подробней уже не могу.  В коде вроде всё это так же подробно расписано в комментах.
Кстати, сократил код, выкинув ту фичу, про которую говорил раньше(возможность регулировать яркость сразу после включения, удерживая кнопку). Может так понятней будет.
|
|
|
|
15.04.2011, 13:36
|
|
|
Временная регистрация
Регистрация: 11.04.2011
Сообщений: 54
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Всё пытаюсь въехать в логику. Умом понимаю как надо, а логика моя отказывается понимать...
А может срабатывание всё таки не по отпусканию кнопки, а по нажатию делать? Зачем ещё ждать дребезг по отпусканию? если условие нажатия сработало.
P.S. oleg_harp, спасибо за проделанную работу
|
|
|
|
15.04.2011, 13:42
|
|
|
Прописка
Регистрация: 25.08.2007
Сообщений: 193
Сказал спасибо: 11
Сказали Спасибо 57 раз(а) в 33 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
|
Цитата:
|
|
А может срабатывание всё таки не по отпусканию кнопки, а по нажатию делать? Зачем ещё ждать дребезг по отпусканию? если условие нажатия сработало.
|
Вот у Вас режим - фонарь включен. Нажали Вы кнопку и фонарь сразу выключился. А как же удержание, чтобы через секунду начать регулировать яркость?
|
|
|
|
15.04.2011, 14:39
|
|
|
Временная регистрация
Регистрация: 11.04.2011
Сообщений: 54
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Пока только вот это родить смог. Первое событие - кнопка нажата, второе - кнопку отжали
|
Код:
|
#define button PINB.0
volatile bit enable = 1;
volatile unsigned int timer_count = 0;
...
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0xB2; // срабатывание каждые ~10 мс
timer_count++; // постоянно считаем 10 мс интервалы
if (timer_count›65534) { // если насчитали больше 65535, то сбрасываем на 0
timer_count=0;
}
if ((button == 0) && (enable == 1)) { // если нажата кнопка и это первое срабатывание
timer_count = 0; // сбрасываем счетчик
enable = 0; // запрещаем сброс timer_count (случайный дребезг)
}
if (timer_count == 4) { // подавили дребезг 40 мс
if (button == 0) { // если кнопка всё ещё нажата через 40 мс
// кнопка нажата // фиксируем что кнопку нажали
}
}
if (timer_count == 30) { // если через 300 мс кнопка не нажата, то её отпустили
if (button == 1) {
// кнопку отпустили
enable = 1;
}
}
} |
Дальше пока никак
|
|
|
|
15.04.2011, 15:42
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,487
Сказал спасибо: 30
Сказали Спасибо 3,070 раз(а) в 2,011 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
oleg_harp, а зачем 2 таймера и по 8 бит на каждый флаг?
poligon_85, хотя бы ради смеха посмотрите вот сюда и сравните с этим. m8_PWM+Key.zip
Последний раз редактировалось omercury; 15.04.2011 в 21:41.
|
|
|
|
15.04.2011, 16:03
|
|
|
Прописка
Регистрация: 25.08.2007
Сообщений: 193
Сказал спасибо: 11
Сказали Спасибо 57 раз(а) в 33 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
|
Цитата:
|
|
oleg_harp, а зачем 2 таймера и по 8 бит на каждый флаг?
|
Если Вы смотрели код, там есть только один таймер, который используется для тактирования. Таймером в описании алгоритма я назвал инкремент счетчика, который используется для вычисления временного интервала. 8-ми битные переменные, чтобы ТС удобно было смотреть их в окне AVR Variables Proteus, потому что битовые переменные в Proteus отображаются не наглядно.
Насчет ради смеха и что с чем сравнить, не понял. Ваш код не короче моего, и в Proteus Ваш пример у меня не работает.
Последний раз редактировалось oleg_harp; 15.04.2011 в 16:12.
|
|
|
|
15.04.2011, 16:56
|
|
|
Временная регистрация
Регистрация: 11.04.2011
Сообщений: 54
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от omercury
|
oleg_harp, а зачем 2 таймера и по 8 бит на каждый флаг?
poligon_85, хотя бы ради смеха посмотрите вот сюда и сравните с этим.
Вложение 20589
|
Не понимаю зачем KeyEXE. И в протеусе у меня тоже не работает.
Не понимаю я оба ваших примера. Почему так сложно. Можно же проще. Зачем кучу дэфайнов, запутаться можно
Последний раз редактировалось poligon_85; 15.04.2011 в 17:07.
|
|
|
|
15.04.2011, 17:20
|
|
|
Прописка
Регистрация: 25.08.2007
Сообщений: 193
Сказал спасибо: 11
Сказали Спасибо 57 раз(а) в 33 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
|
Цитата:
|
|
Зачем кучу дэфайнов, запутаться можно
|
Дефайны по науке облегчают понимание и способствуют переносимости кода. Но, как видно, и здесь на вкус и цвет .....
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 22:32.
|
|