Обсуждаем контроллеры компании Atmel.
Ответить

Как организовать задержку в ожидании нажатия кнопок

Ср окт 12, 2022 11:43:55

Пользуюсь CVAVR, учусь писать программы на языке Си. Надо осуществить задержку после включения устройства и прохождения теста микропроцессора (Attini23132) для нажатия одной или нескольких кнопок поочередно. После нажатия каждой кнопки время задержки должно оставаться прежним. Если ни одна кнопка не нажата за время задержки, должно включиться выполнение программы. Подскажите, пожалуйста, как это можно осуществить или где посмотреть пример применения

Re: Как организовать задержку в ожидании нажатия кнопок

Ср окт 12, 2022 12:42:51

После нажатия каждой кнопки время задержки должно оставаться прежним.

Это как ? Первоначальная задержка 5 сек. Нажатие кнопки дает еще 5 сек для нажатия следующей или наоборот нужно уложиться всеми нажатиями в 5 сек ? В любом случае непонятно что тут непонятного. Тикайте таймером, проверяйте нажатия, если таймер оттикал задержку - выполняйте программу.

Re: Как организовать задержку в ожидании нажатия кнопок

Ср окт 12, 2022 13:31:19

"КОДОВЫЙ ЗАМОК"?
8)

Re: Как организовать задержку в ожидании нажатия кнопок

Ср окт 12, 2022 14:14:37

Valer5, нарисуй обычный конечный автомат. Системный таймер пусть миллисекунды отсчитывает, а ты, находясь в состоянии, скажем, INITIALIZING, мониторишь, сколько миллисекунд прошло с момента входа в это состояние. Ну и соответствующие решения принимаешь.
Если, как тут предположили, это - кодовый замок, все очень просто: в суперлупе ты проверяешь, не нажата ли какая кнопка, если надо - выставляешь флаги (какая нажата, заодно меняя состояние КА на JUSTPRESSED), а потом запускаешь свою машину состояний. В состоянии JUSTPRESSED выставляешь таймер нажатия в текущее значение, проверяешь, верно ли нажата очередная кнопка, и, в зависимости от результата, переходишь в следующее состояние. Условно говоря:
Код:
// ext. #define T_WAIT  5000
// ext. #define T_CLOSE 1000
// ext. uint32_t Tms; ext uint8_t keypressed; ext uint8_t the_code[N];
static uint32_t t_pressed;
static uint8_t key_ctr;
switch(state){
  case JUSTPRESSED:
    if(t_pressed - Tms > T_WAIT){ // start from zero
      key_ctr = 0;
    }
    t_pressed = Tms;
    if(keypressed == the_code[key_ctr++]){
      if(key_ctr == N){ open(); state = SLEEPING; } // open the lock
      else state = SLEEPING;
    }else state = SLEEPING;
  break;
  default:
    if(Tms - t_pressed > T_CLOSE) close(); // close the lock
  break;
}

Re: Как организовать задержку в ожидании нажатия кнопок

Ср окт 12, 2022 19:45:21

Можно как то так:


Мой пример программных таймеров.

Re: Как организовать задержку в ожидании нажатия кнопок

Ср окт 12, 2022 20:02:11

После нажатия каждой кнопки время задержки должно оставаться прежним.

Это как ? Первоначальная задержка 5 сек. Нажатие кнопки дает еще 5 сек для нажатия следующей или наоборот нужно уложиться всеми нажатиями в 5 сек ? В любом случае непонятно что тут непонятного. Тикайте таймером, проверяйте нажатия, если таймер оттикал задержку - выполняйте программу.


Я имел в виду, что после каждого нажатия кнопки общее время задержки увеличится на то время, через которое произошло нажатие.
Это не кодовый замок, а что такое конечный автомат, извините, не знаю! потом посмотрю.

Re: Как организовать задержку в ожидании нажатия кнопок

Ср окт 12, 2022 20:06:13

Все равно подробнее. Пусть у нас задержка 30 секунд. В течении этих 30 секунд скажем, 5 секунд прошло, нажали кнопку, добавилось 5 секунд? Что за устройство. Зачем то, что вы просите?

Re: Как организовать задержку в ожидании нажатия кнопок

Ср окт 12, 2022 23:22:06

Пользуюсь CVAVR, учусь писать программы на языке Си. Надо осуществить задержку после включения устройства

Если я правильно понял, то задержку можно организовать например с помощью таймер-счётчика… при старте МК поднимаете флаг, назовём его произвольно "ПАУЗА" и контролируете его сброс. При каждом нажатии любой кнопки таймер-счётчик (или его счётная переменная) обнуляется и счёт начинается сначала… если кнопки не нажимать, то таймер-счётчик (или его счётная переменная) переполняются что приводит к сбросу флага ПАУЗА… вот как только данный флаг сбросился значит можно выполнять требуемую программу… в Си ничего не понимаю, потому пример на Си показать не могу… :)

Re: Как организовать задержку в ожидании нажатия кнопок

Ср окт 12, 2022 23:48:40

Алгоритм похож или на кодовый замок или на начальный конфигуратор устройства.
Для кодового замка еще нормально, а вот для ввода начальных параметров при первом запуске - к примеру запуск RTC или первичное внесение параметров в "пустую" ЕЕПРОМ такой подход не есть удачный.
Там достаточно одной "волшебной кнопы" (перемычки) для активации программы ввода параметров, аналогичной обычным обработчикам кнопок/индикации устройства.
:roll:

Re: Как организовать задержку в ожидании нажатия кнопок

Вс окт 16, 2022 15:20:59

...Подскажите, пожалуйста, как это можно осуществить или где посмотреть пример применения


учитесь мыслить в 3d - т.е. никогда не используйте подход прямых задержек в циклах, если только это не простая программа типо хэллоу ворд.
старайтесь использовать прерывания (которые собственно либо реализованы аппаратно либо прерывают ход основной программы на некий маленький временной квант), либо представляйте ваш код как НЕ вытесняющая многозадачность (если нет осей поддерживающих параллелизм) - т.е. в большом лупе некой подпрограмме отдаётся квант времени, который она должна (опираясь на внутренне сохранённом состоянии) делать очередное действие и сразу (не используя всякие глупые лупы-циклы) отдавать управление вызывающей программе - return.

как то так
(круглый)

Re: Как организовать задержку в ожидании нажатия кнопок

Вс окт 16, 2022 16:36:43

А 3d - это как?
Ну и "никогда не говори никогда" - бывают моменты, когда блокирующая задержка как раз нужна, и не только в простом "хеловорде".

Re: Как организовать задержку в ожидании нажатия кнопок

Вс окт 23, 2022 22:34:50

Всем спасибо. Написал простой кусок программы и не понимаю,
почему она не работает.
1.назначил переменную K1, в прерывании таймера T0 -k1++, таймер работает с частотой 32 Гц, в инициации таймера запретил прерывания, назначил выход PORTD.5 входом с подтяжкой, на него повесил кнопку "sec". Далее в main, wail, запускаю прерывание и проверяю замыкание кнопки.
Код:
if((!PIND.3)&& sbros)
  { TIMSK=0x02,PORTB=k1;}
  if((k1==50)&&(!PIND.3))
   {sec=sec+1;}
    if((k1>150)&&(!PIND.3))
    {TIMSK=0x00,sec=sec+10-1,sbros=0,k1=0;
}

Считаю, что за 20 периодов дребезг закончится, с запасом считаю короткое нажатие 50мс и увеличиваю переменную sec. Давлее проверяю не отпустится ли кнопка за 150 тактов (длинное нажатие) и в этом случае увеличиваю K1 на 10. Выключаю прерывание и жду отпускания кнопки.
При проверке в Протеусе получается ерунда.
В чём дело?

Re: Как организовать задержку в ожидании нажатия кнопок

Пн окт 24, 2022 00:18:25

Пять раз прочитал пост, но какой требуется алгоритм так и не понял… :dont_know: :))


Версия для поиграть в протеусе… на выводе РD5 кнопка (коммутирует GND)… на выводе РD3 и PD4 светодиоды… светодиод PD3 сигнализирует о нажатии кнопки, а светодиод на выводе PD4 загорается если в течении 5 секунд кнопка не нажималась… если периодически нажимать на кнопку с интервалом менее 5 сек, то светодиод на выводе PD4 не загорается… МК тактируется на заводских установках (1 МГц)…
test_but.hex
(758 байт) Скачиваний: 47

Подобную задачу преследует ТС или нет, я так и не понял… поиграв с прошивкой, может что ТС и скажет… :dont_know:

Re: Как организовать задержку в ожидании нажатия кнопок

Чт дек 01, 2022 15:27:24

Доброе время всем. Всё ещё мучаюсь сам и не даю покоя сообществу.
Написал часть программы, обрабатывающей нажатие кнопки, длительность которого определяет интервал времени для дальнейшей программы. Пытаюсь писать на Си, компилирую в CVAVR. проверяю в Протеус.
Контроллер Attiny2313, при нажатии кнопки на PA0 запускаю таймер1, по отпусканию считываю содержание счётчика в bufer и далее определяю длительность нажатия. Параллельно кнопке (для определённости) включил транзистор, управляемй генератором импульсов и их периодом.

Код:
while (1)
    {
     while(PINA.0&(1<<0))
       { TCCR1B=0x00, TCNT1 = 0;} //остановка таймера1, обнуление счетчика
        if(!(PINA.0&(1<<0)))     // Проверяем нажатие  кнопки S1
         {TCCR1B=0x05;}         //запускаем таймер1     
          if (PINA.0&(1<<0))     // Проверяем отпускание  кнопки S1,
           {
            TCCR1B = 0x00, bufer = TCNT1;//записываем значение счетчика1 в bufer     
              if(bufer>=100)             
               { sec=sec+9;}        //определяем длительность желаемого интервала в сек             
              if(30<bufer<100)   
                {sec=sec+1;}     
            }

Вроде всё работает, но первый импульс упорно не читает. Почему, кто подскажет?

Re: Как организовать задержку в ожидании нажатия кнопок

Чт дек 01, 2022 15:59:50

В псевдо-коде, что получилось у вас в условиях:
Код:
пока (кнопка_нажата)
    если (кнопка_не_нажата)
          если (кнопка_нажата)

Ну как бы что-то тут не то в логике. Вам же вроде как показывали же ранее. Логика должна работать так:
Код:
если (кнопка_нажата)
    если (перед_этим_она_была_отпущена)
          выполнить_действие и установить состояние Кнопка_нажата
     выйти из проверки
иначе
    установить состояние Кнопка_отпущена

То есть, ключевое слово "перед этим", предыдущее состояние кнопки. Предудущее состояние должно сохраняться в отдельной переменной статического типа. В исходном состоянии в момент запуска эта переменная должна содержать состояние "не нажата". И тогда при срабатывании условия проверки текущего состояния кнопки, в случае, если она сейчас нажата, проверяется уже предыдущее состояние "а до этого она была нажата?". То есть, нужно получить именно изменение состояния.
Последний раз редактировалось MLX90640 Чт дек 01, 2022 16:25:16, всего редактировалось 2 раз(а).

Re: Как организовать задержку в ожидании нажатия кнопок

Чт дек 01, 2022 16:10:08

Ваше "всё работает" относится к модели "в Протеус", или на реальном железе "Attiny2313"?

Re: Как организовать задержку в ожидании нажатия кнопок

Чт дек 01, 2022 16:20:23

Наверняка в Протеусе в пошаговом исполнении, потому как в реальном времени в железе это навряд ли будет работать. Возможно, из-за дребезга контактов что-то будет срабатывать в условиях железа..

Re: Как организовать задержку в ожидании нажатия кнопок

Сб дек 03, 2022 12:27:53

Ваше "всё работает" относится к модели "в Протеус", или на реальном железе "Attiny2313"?

В Протеус в непрерывном режиме в течении 6 интервалов имитации замыкания кнопки.

Добавлено after 4 minutes 22 seconds:
Наверняка в Протеусе в пошаговом исполнении, потому как в реальном времени в железе это навряд ли будет работать. Возможно, из-за дребезга контактов что-то будет срабатывать в условиях железа..


MLX90640, а почему в реальном железе не должно работать, исключая дребезг контактов?

Re: Как организовать задержку в ожидании нажатия кнопок

Сб дек 03, 2022 13:45:00

А, пардон, у вас "нетрадиционное" выравнивание текста, оное сбивает с толку. Но всё равно, это довольно скользкий путь, из-за дребезга контактов почти стопудово будут ложные срабатывания в железе. Вот типичное поведение pull-up кнопки при нажатии (слева) и отпускании (справа):
Изображение Изображение

Re: Как организовать задержку в ожидании нажатия кнопок

Вс дек 04, 2022 00:10:16

Ну что.. У вас, Valer5, появился отличный шанс понять, как именно надо работать с аппаратурой. То бишь, с железом.
Поменьше читать (обзоры и чужие мнения) и побольше думать (своей головой).
То, что вы написали, не работает и никогда работать не будет. "Железо" никогда не работает так, как пишут в учебниках. Истина простая, только программеры этого 'просто' не понимают. При работе реальной аппаратуры всегда происходит нечто, что портит все графики. Это - лишние импульсы, уплывание порогов по времени и/или уровню, банальый шум и помехи. Всё это надо учитывать.
К чему я? Симуляция в Протеус - это симуляция. А "жизнь" - это не симуляция. К слову, никогда даже мысли небыло что-то симулировать в Протеус и прочем. И это при обширном опыте использования PSPICE. Как-нибудь погуглите, что это за фигня. В нём я симулирую только аналоговые и "полу-аналоговые" схемы, т.к. практически проверено, что этот симулятор практически никогда не ошибается. И это экономит время и деньги. Впрочем, это off.
Учитывайте реальные свойства аппаратуры, отталкивайтесь от них. Если у вас входным является "кнопка", значит берите ее свойства - время переключения, время дребезга замыкания, время дребезга размыкания. Ваш алгоритм работы обязан. Так, вы не поймете, еще раз. Ваш алгоритм работы обязан учитывать все особенности работы вашей аппаратуры.
Конечно, вы можете спросить "помощь зала" и ничему не учиться, воля ваша. Вот только ... я здесь вижу свалку мыслей, приведшею к паталогически неправильному решению. Смысл таких рекомендаций от меня ускользает. Ну, автор темы оказался настолько глухой, что-бы что-то слышать. Ну, как-бы, решения не наблюдается, как и даже попытки по нему пойти.

Перепишите алгоритм. Нет, этот можно только выкинуть, жуть на жути.
Напишите новый алгорим, который учитывал тот _факт_, что реальная кнопка имеет дребезг.
Уточнение - я правильно понял, что MCU 'стоит и ждет', сколько времени будет удерживаться кнопка, и после отпускания начинает работать остальная программа? Я правильно понял?
Ответить