Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы

Как отследить короткое и продолжительное нажатие кнопки в фонаре?

Непрочитано 14.04.2011, 14:15  
st_1
Заблокирован
 
Регистрация: 26.12.2009
Сообщений: 3,102
Сказал спасибо: 113
Сказали Спасибо 860 раз(а) в 610 сообщении(ях)
st_1 на пути к лучшему
По умолчанию Re: Отследить короткое и продолжительное нажатие кнопки в фонаре. Как???

В такой задаче прерывания и нафиг не впёрлись, разве что только выходить из сна... Всё остальное в цикле по флагам...
Реклама:
st_1 вне форума  
Непрочитано 14.04.2011, 16:15  
poligon_85
Временная регистрация
 
Аватар для poligon_85
 
Регистрация: 11.04.2011
Сообщений: 54
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
poligon_85 на пути к лучшему
Вопрос Re: Отследить короткое и продолжительное нажатие кнопки в фонаре. Как???

Спасибо, за ответы, но я всё таки хочу понять что именно я делаю не так???? Описываю каждый шаг.

Итак, кратко нажали - запустили таймер на генерацию ШИМа, ещё раз нажали - выключини таймер. Удерживаем › 1 сек - флаг долгого нажатия.
Код:
#define button PINB.0 

volatile bit long_push = 0;
volatile unsigned int cnt = 0;
volatile bit state = 0;
...
// Clock value: 7812,5 Hz
TCCR0=0x05;
TCNT0=0xB2;
...
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
                       // Reinitialize Timer 0 value
  TCNT0=0xB2;          // срабатывание каждые ~10 мс
  
  if (!button) {       // если нажата кнопка т.е. PINB.0 не равен 1
    cnt++;             // прибавляем счетчик
    if (cnt›65534) {   // если кому то вздумается очень долго удерживать кнопку
      cnt=101;         // чтобы не перевалили за значение 65535
      }
    }
  else if (button) {   // если на PINB.0 стал 1 
    cnt=0;             // то сбрасываем счетчик
    long_push=0;       // сбрасываем бит долгого нажатия
    }

  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 в основном цикле
    } 
}
Что не правильно то??? Не понимаю

Последний раз редактировалось poligon_85; 14.04.2011 в 16:49.
poligon_85 вне форума  
Непрочитано 14.04.2011, 16:39  
oleg_harp
Прописка
 
Регистрация: 25.08.2007
Сообщений: 193
Сказал спасибо: 11
Сказали Спасибо 57 раз(а) в 33 сообщении(ях)
oleg_harp на пути к лучшему
По умолчанию Re: Отследить короткое и продолжительное нажатие кнопки в фонаре. Как???

Сообщение от poligon_85 Посмотреть сообщение
что именно я делаю не так????
Да вот сразу не так. Если нажата кнопка, прибавляете счетчик. Так уже на следующем срабатывании таймера (через 10mS) у вас придет 1 из за дребезга кнопки и Ваш счетчик сбрасывается. Дальше смотреть даже нет смысла. Вы вложение в посте №25 скачайте, там точно выполнено то что Вы хотите и посмотрите как.
oleg_harp вне форума  
Непрочитано 14.04.2011, 16:54  
poligon_85
Временная регистрация
 
Аватар для poligon_85
 
Регистрация: 11.04.2011
Сообщений: 54
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
poligon_85 на пути к лучшему
Вопрос Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?

Да скачивал я. Там в #defineах запутаться можно. Хотя в протеусе всё работает с вашей прошивкой.

Но хочу разобраться в своем варианте. Что подправить то????
Код:
volatile int cnt = 0;
...
else if (button) {     // если на PINB.0 стал 1 
    cnt--;             // то вычитаем счетчик
    long_push=0;       // сбрасываем бит долгого нажатия
    }
Т.е. как накопилось в cnt нужное значение, то выполняем действие. Тем самым компенсируем случайный дребезг. Так?

Последний раз редактировалось poligon_85; 14.04.2011 в 17:00.
poligon_85 вне форума  
Непрочитано 14.04.2011, 17:18  
oleg_harp
Прописка
 
Регистрация: 25.08.2007
Сообщений: 193
Сказал спасибо: 11
Сказали Спасибо 57 раз(а) в 33 сообщении(ях)
oleg_harp на пути к лучшему
По умолчанию Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?

Чтобы компенсировать дребезг нужно сделать задержку 40-100mS, после этого нужно убедится, что состояние пина то же, что и до задержки. Значит сработала кнопка. Или нажата или отжата. Ведь, в Вашем случае важно и то и другое. Причем и нажатие и отжатие кнопки обрабатывается каждый раз по разному, в зависимости от того в каком режиме находится устройство (сами такие условия задали управлением одной кнопкой). Поэтому, представьте сначала на бумаге (или в голове, если умещается) алгоритм работы. Пока, судя по коду, Вы его не представляете. А вот если в #definах моих разберетесь, а это кстати все состояния автомата вашей задачи, тогда и код напишете.
oleg_harp вне форума  
Непрочитано 14.04.2011, 17:18  
Easyrider83
Гуру портала
 
Аватар для Easyrider83
 
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,821
Сказал спасибо: 919
Сказали Спасибо 4,289 раз(а) в 2,570 сообщении(ях)
Easyrider83 на пути к лучшему
По умолчанию Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?

Запускаем два таймера, один быстрый, другой медленный. Лучше все сделать на одном, но для начала можно использовать и два.
Быстрый таймер опрашивает кнопку. Если кнопка нажата, инкременирует одну переменную и сбрасывает на ноль второй таймер.
Если сработал второй таймер, значит кнопку уже отпустили. Значение инкременнированной переменной - длинна нажатия кнопки.
Элементарная работа для двух прерываний. Но опять же - это простой и не корректный способ.
Зато дребезг мы победили.
Easyrider83 вне форума  
Непрочитано 14.04.2011, 18:43  
poligon_85
Временная регистрация
 
Аватар для poligon_85
 
Регистрация: 11.04.2011
Сообщений: 54
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
poligon_85 на пути к лучшему
По умолчанию Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?

Не понимаю я ваш код oleg_harp, точнее отчасти понимаю, но считаю что он избыточен.

Зачем так писать?
Код:
 PIN_State = PINB.0;              // считать состояние пина кнопки
    if (PIN_State ==!Prev_PIN_State)  // если состояние пина кнопки изменилось
    {  
        Button_State = PIN_State;       // запомнить состояние пина кнопки
        PIN_Change = Changed;               // установить флаг изменения
        Time = 0;                              // запустить отсчет времени для антидребезга
    };
Если можно: "считать состояние пина кнопки; если состояние пина кнопки изменилось"
Код:
if (PINB.0 == 0)
"запустить отсчет времени для антидребезга"
Код:
cnt++;
Дальше:
Код:
if (Time == 5)            // если через 8ms x 5 = 40mS 
                          // состояние пина не изменилось
мой код:
Код:
if ((cnt › 3) && (cnt ‹ 100)) {   // проверяем условие короткого нажатия (держали › 40 мс и ‹ 1 сек; 10мс * 100 срабатываний)
                               // заодно и подавляем дребезг 40 мс
Зачем писать так сложно как вы? Я наверное слишком тупой, но я хоть убейте не понимаю

Последний раз редактировалось poligon_85; 14.04.2011 в 18:49.
poligon_85 вне форума  
Непрочитано 14.04.2011, 21:56  
oleg_harp
Прописка
 
Регистрация: 25.08.2007
Сообщений: 193
Сказал спасибо: 11
Сказали Спасибо 57 раз(а) в 33 сообщении(ях)
oleg_harp на пути к лучшему
По умолчанию Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?

Цитата:
Не понимаю я ваш код oleg_harp, точнее отчасти понимаю, но считаю что он избыточен.
Не спорю. Я его не оптимизировал. Просто написал по быстрому решение Вашей задачи. Я не профессионал. Но Вы можете проверить, он будет надёжно работать не только в Proteus, но и в реале.
Цитата:
Если можно: "считать состояние пина кнопки; если состояние пина кнопки изменилось"
Код:
Код:
if (PINB.0 == 0)
А где здесь проверяется изменение состояния пина? Я вижу, что проверяется состояние пина на равенство нулю (нажатие кнопки). А если кнопку отпустили? По Вашему когда её отпускают ничего не должно происходить?
oleg_harp вне форума  
Непрочитано 14.04.2011, 23:42  
poligon_85
Временная регистрация
 
Аватар для poligon_85
 
Регистрация: 11.04.2011
Сообщений: 54
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
poligon_85 на пути к лучшему
По умолчанию Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?

Когда отпускают:
Код:
else if (button) {   // если на PINB.0 стал 1 
    cnt=0;             // то сбрасываем счетчик
    long_push=0;       // сбрасываем бит долгого нажатия
    }
Не понимаю почему не работает у меня, и не понимаю почему работает у вас
poligon_85 вне форума  
Непрочитано 15.04.2011, 00:29  
oleg_harp
Прописка
 
Регистрация: 25.08.2007
Сообщений: 193
Сказал спасибо: 11
Сказали Спасибо 57 раз(а) в 33 сообщении(ях)
oleg_harp на пути к лучшему
По умолчанию Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?

Сообщение от poligon_85 Посмотреть сообщение
Когда отпускают:
Код:
else if (button) {   // если на PINB.0 стал 1 
    cnt=0;             // то сбрасываем счетчик
    long_push=0;       // сбрасываем бит долгого нажатия
    }
Не понимаю почему не работает у меня, и не понимаю почему работает у вас
Этот кусок кода как раз в Proteus у Вас будет работать. В реальной схеме через раз, потому что вы не отрабатываете дребезг контактов. Я об этом написал в посте #33.
А вот этот кусок нерабочий. Пока у Вас нажата кнопка каждые 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 в основном цикле
    } 
}
А я, кстати, понял почему мой код показался Вам сложным. Я действительно немного усложнил Ваш алгоритм, потому что мне показалось это удобным для пользователя. У меня при включении фонарика сразу можно удержать кнопку и регулировать яркость. Если это выкинуть и сделать как Вы написали изначально, т.е. включение - короткое нажатие-отпускание, а затем опять нажатие и удержание для регулировки яркости, то можно будет выкинуть пару состояний и код сократится.
oleg_harp вне форума  
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Книги dosikus Электронная библиотека 11242 29.12.2015 23:45
Как правильно отследить импульс sdsrem Микроконтроллеры, АЦП, память и т.д 8 17.08.2010 21:28
[Решено] Третье Послание Человечеству lelkanet Отвлекитесь, эмбеддеры! 201 06.01.2010 00:33


Часовой пояс GMT +4, время: 21:17.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.