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

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

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

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

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

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

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

 
Опции темы
Непрочитано 14.04.2011, 14:15  
st_1
Заблокирован
 
Регистрация: 26.12.2009
Сообщений: 3,124
Сказал спасибо: 116
Сказали Спасибо 867 раз(а) в 614 сообщении(ях)
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,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
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, время: 14:20.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot