Jump to content
brusel

Помощь с кодом

Recommended Posts

Привет, помогите сделать так, чтобы по нажатию кнопки на несколько секунд появлялся высокий уровень на выходах LED и OUT.

#define F_CPU 1200000UL
#define OUT PB2
#define LED PB0
#define BUTTON1 PB4 
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
  // Пины кнопок
  DDRB &= ~((1<<BUTTON1)); // входы
  PORTB |= (1<<BUTTON1); // подтянуты
  // Пин светодиода
  DDRB |= (1<<LED)|(1<<OUT); // выход
  PORTB &= ~((1<<LED)|(1<<OUT)); // выключен
  
    while (1) 
    {
        _delay_ms (50); // антидребезг
        if ( (PINB & (1<<BUTTON1)) == 0 )    // если нажата кнопка
          {
          PORTB |= ((1<<OUT)|(1<<LED));           //вкл
          }
          _delay_ms (1000);                       // пауза 
          PORTB &= ~((1<<OUT)|(1<<LED));          //выкл
    }
}

 

Share this post


Link to post
Share on other sites

Паузу в несколько секунд сделайте там же, где и "вкл" :) 

Share this post


Link to post
Share on other sites

Правильно? В протеусе вроде работает. Пауза где-то 7-8 сек.

#define F_CPU 1200000UL
#define OUT PB2
#define LED PB0
#define BUTTON1 PB4 
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
  // Пины кнопок
  DDRB &= ~((1<<BUTTON1)); // входы
  PORTB |= (1<<BUTTON1); // подтянуты
  // Пин светодиода
  DDRB |= (1<<LED)|(1<<OUT); // выход
  PORTB &= ~((1<<LED)|(1<<OUT)); // выключен
  
    while (1) 
    {
        _delay_ms (50); // антидребезг
        if ( (PINB & (1<<BUTTON1)) == 0 )    // если нажата кнопка
          {
          PORTB |= ((1<<OUT)|(1<<LED));           //вкл
          _delay_ms (45000);                       // пауза 
          }
          PORTB &= ~((1<<OUT)|(1<<LED));          //выкл         
    }
}

 

Share this post


Link to post
Share on other sites

Литиевые батарейки Fanso для систем телеметрии и дистанционного контроля

Системы телеметрии находят все более широкое применение во многих отраслях на промышленных и коммунальных объектах. Требования, предъявляемые к условиям эксплуатации приборов телеметрии и, как следствие, источников питания для них, могут быть довольно жесткими. Fanso предоставляет широкую линейку продукции, рассчитанной на различные условия эксплуатации, что позволяет подобрать батарейку для каждого конкретного применения, в том числе и для устройств телеметрии.

Подробнее

6 hours ago, brusel said:

Правильно?

Проверьте, потом нам расскажите :)

Share this post


Link to post
Share on other sites
11 hours ago, brusel said:

Пауза где-то 7-8 сек.

Значит неправильно настройки заданы. Пауза должна быть 45 секунд. И вообще, на кой для такой простейшей задачи целый МК?

Share this post


Link to post
Share on other sites
                     

Приглашаем на вебинар Решения для построения ультразвуковых счетчиков жидкостей и газов на базе MSP430

Компэл совместно с Texas Instruments 23 октября 2019 приглашают на вебинар, посвященный системам-на-кристалле для построения ультразвуковых расходомеров жидкостей и газов на базе ядра MSP430. Вебинар проводит Йоханн Ципперер – эксперт по ультразвуковым технологиям, непосредственно участвовавший в создании данного решения. На вебинаре компания Texas Instruments представит однокристальное решение, позволяющее создавать точные недорогие счетчики жидкостей и газов.

Подробнее...

13 hours ago, brusel said:

    _delay_ms (50); // антидребезг      

  if ( (PINB & (1<<BUTTON1)) == 0 )    // если нажата кнопка

нет здесь никакого антидребезга!

 

 

Share this post


Link to post
Share on other sites
Posted (edited)

Грубо говоря, есть. Опрос кнопок будет выполняться с интервалом в 50 мс, что не даст среагировать на дребезг. Правда, 50 мс вряд ли хватит, надо хотя бы 100 мс. Но делать антидребезг на задержках - костыль. Гораздо оптимальнее опрашивать состояние портов через промежутки времени. Допустим, 10 раз в секунду. Это отлично фильтрует дребезг.

Edited by BARS_

Share this post


Link to post
Share on other sites
Just now, IMXO said:

нет здесь никакого антидребезга!

Как же нет, если есть? Опрос состояния контактов кнопки с интервалами, заведомо больше, чем длительность дребезга - это и есть защита от последнего. Например, во многих проектах опрашивают пины кнопок по таймеру каждые 50-100 мс, сразу формируя коды нажатий - и никаких проблем не возникает и возникнуть не может!

При желании могу привести и диаграммы, но думаю, вы и сами понимаете, что поспешили с утверждением... Вот и ув. @BARS_ в ту же дуду...

Share this post


Link to post
Share on other sites
4 hours ago, BARS_ said:

Пауза должна быть 45 секунд

А час задержки сможет эта функция отработать _delay_ms(3600000)?

Я не спец в AVR, но должен же быть какой-то предел, максимально возможная задержка у _delay_ms() ...

Share this post


Link to post
Share on other sites
Just now, Yurkin2015 said:

должен же быть какой-то предел, максимально возможная задержка у _delay_ms()

65536 мс

Share this post


Link to post
Share on other sites
5 minutes ago, ARV said:

65536 мс

Это потому, что аргумент у _delay_ms() имеет размер 2 байта?

Ну, всё понятно, спасибо.

Share this post


Link to post
Share on other sites
2 hours ago, ARV said:

Например, во многих проектах опрашивают пины кнопок по таймеру каждые 50-100 мс, сразу формируя коды нажатий - и никаких проблем не возникает и возникнуть не может!

может и возникает.

ситуация первая : кнопка не нажата, на линии проходит импульсная помеха в момент опроса пина = включение таймера

ситуация вторая: кнопка отпускается после окончания отсчета таймера , дребезг контактов  в момент опроса пина = ложный запуск таймера по отпусканию кнопки

так что нет у товарища антидребезга.

Share this post


Link to post
Share on other sites
Just now, Yurkin2015 said:

Это потому, что аргумент у _delay_ms() имеет размер 2 байта?

Нет, аргумент имеет тип float, но реализация сделана так, что более догую задержку не отрабатывает

Just now, IMXO said:

так что нет у товарища антидребезга

Мда...

Just now, IMXO said:

ситуация первая

Расскажите про алгоритм подавления дребезга для этой ситуации.

Наиболее оптимальный, как я понимаю, заключается в сравнении состояния пина ДО и ПОСЛЕ некоторой задержки. Если вам известен алгоритм 100% безошибочного обнаружения нажатий кнопок в условиях сильного дребезга и помех - хотел бы узнать о нем.

Share this post


Link to post
Share on other sites
23 minutes ago, IMXO said:

ситуация первая

Это не антидребезг, а борьба с импульсными помехами на линии.

 

24 minutes ago, IMXO said:

ситуация вторая:

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

Share this post


Link to post
Share on other sites

дребезг это и есть импульсные помехи на линии.

причем здесь повторное нажатие , читайте не по диагонали

1 hour ago, ARV said:

 хотел бы узнать о нем.

я пользую примерно такой:

Spoiler

struct button_type {
  unsigned jitter         :8; // Для подавления дребезга
  unsigned old            :1; // Старое состояния пина
  unsigned new            :1; // Состояния пина
  unsigned pressed        :1; // Состояние кнопоки
  unsigned oldpressed     :1; // Старое состояния кнопоки
  unsigned justPressed    :1; // Кнопка только что нажата
  unsigned justReleased;  :1; // Кнопка только что отпущена
  unsigned     :1;
  unsigned     :1;
} m_Batton;

unsigned int tamer=0;
unsigned char task=0;

void Task_Button (void)
{
//**опрос кнопки
  m_Batton.new=0;
  if( (PINB & (1<<BUTTON1)) == 0 ) m_Batton.new=1;

//** подавление дребезга  
  if(m_Batton.new==m_Batton.old)
    { 
      if (m_Batton.jitter<5) 
        {m_Batton.jitter++;}
       else
        {m_Batton.pressed=m_Batton.new;} 
    }
   else
    {
      m_Batton.jitter=0;
    }
   m_Batton.old=m_Batton.new;

//*** фиксация фронтов нажатия/отпускания
  if(!m_Batton.oldpressed && m_Batton.pressed)
     {m_Batton.justPressed=1;}

  if(m_Batton.oldpressed && !m_Batton.pressed)
     {m_Batton.justReleased=1;} 
   m_Batton.oldpressed=m_Batton.pressed;
}

 

применительно к задаче ТС получим

Spoiler

int main(void)
{
  // Пины кнопок
  DDRB &= ~((1<<BUTTON1)); // входы
  PORTB |= (1<<BUTTON1); // подтянуты
  // Пин светодиода
  DDRB |= (1<<LED)|(1<<OUT); // выход
  PORTB &= ~((1<<LED)|(1<<OUT)); // выключен
  
    while (1) 
    {
        _delay_ms (1); // 
        Task_Button (); 

        if(task==2) {m_Batton.justPressed=0;} 
        
        if(m_Batton.justPressed)
          {
           task=1;
           m_Batton.justPressed=0;
          }

        switch (task) {
         case 0:
              PORTB &= ~((1<<OUT)|(1<<LED));          //выкл 
              break;
         case 1:
              PORTB |= ((1<<OUT)|(1<<LED));           //вкл
              tamer=0; 
              task=2
              break;
         case 2:
              if(tamer<45000)
                {
                  tamer++;
                } 
                else
                 {
                   task=0;
                 }    
              break;
        default:
             task=0;
        } 
        
    
    }
}

 

делай заменяем на системный тик 1мс и получаем сквозной, нигде не тормозящий код с возможность расширения на другие задачи.

если комментируем строку  if(task==2) {m_Batton.justPressed=0;} получаем таймер с перезапуском по фронту.

Share this post


Link to post
Share on other sites

Мда...

А я опрашиваю кнопки раз в 100 мс и ни разу не зафиксировал ложного срабатывания за примерно лет 15, как я стал так делать. И пропуска нажатия тоже не было, во всяком случае в те моменты, когда я это делал.

Что же не так со мной?!

Share this post


Link to post
Share on other sites
2 hours ago, IMXO said:

кнопка отпускается после окончания отсчета таймера , дребезг контактов  в момент опроса пина = ложный запуск таймера по отпусканию кнопки

 

52 minutes ago, IMXO said:

читайте не по диагонали

Ну, батенька, специально для Вас разжую свой вопрос.

Состояние кнопки читается один раз во время дребезга. Возможно только два варианта.

Если прочитали состояние "нажато", то значит состояние кнопки не изменилось, как было нажато, так и осталось нажато. Прочитаем правильное установившееся состояние при следующем опросе, когда дребезг уже закончится.

Если прочитали "отпущено", то значит кнопка отпустилась. Так и останется отпущеной при следующем опросе.

Откуда "ложный запуск таймера" возьмётся?

 

Share this post


Link to post
Share on other sites
53 minutes ago, Yurkin2015 said:

Состояние кнопки читается один раз во время дребезга

а откуда ты знаешь, что чтение точно совпадает с дребезгом?

кнопка может быть нажата и между циклам чтения порта, и к следующему чтению дребезг уже закончится.

1 hour ago, ARV said:

А я опрашиваю кнопки раз в 100 мс и ни разу не зафиксировал ложного срабатывания за примерно лет 15, как я стал так делать. И пропуска нажатия тоже не было, во всяком случае в те моменты, когда я это делал.

а я опрашиваю кнопки раз в 1/3 секунды, и тоже никогда проблем не имел.

в принципе пропуск возможен - когда опрос попадет точно на разомкнутую цепь во время дребезга. и это вообще не горе, подержишь кнопку нажатой, пока она не сработает в следующем цикле опроса.

а еще можно сделать так - лет 20 с гаком я такой алгоритм подсмотрел у профессиональных программистов.

опрашиваем кнопки довольно часто и имеем на каждую кнопку свой счетчик нажатого состояния.

а потом в главном цикле проверяем счетчики кнопок.

например, опрашиваем через 20 мс., а главный цикл равен, допустим, 500 мс.

тогда при длительном нажатии кнопки за 500 мс счетчик насчитает 25.

но в главном цикле делаем проверку не на все 25, а, например, на 15. если счетчик насчитал 15 или больше, то считаем, что кнопка была нажата.

а если там меньше 15 - то считаем, кнопка не была нажата.

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

в своих первых проектах я сам применял этот алгоритм со счетчиками нажатого состояния кнопок. а потом решил, что мне достаточно однократной проверки кнопок.

Share this post


Link to post
Share on other sites

Один челдон утверждал, что по военной приемке читать состояние пина надо несколько раз. А чтобы не было импульсных помех на пине, то RC цепь и подтяжка. Можно применять как порознь, так и вместе.

Share this post


Link to post
Share on other sites
2 hours ago, Yurkin2015 said:

Ну, батенька, специально для Вас разжую свой вопрос. 

Состояние кнопки читается один раз во время дребезга. Возможно только два варианта.

Если прочитали состояние "нажато", то значит состояние кнопки не изменилось, как было нажато, так и осталось нажато. Прочитаем правильное установившееся состояние при следующем опросе, когда дребезг уже закончится.

1. покажите мне где в этом куске кода:

    while (1) 
    {
        _delay_ms (50); // антидребезг
        if ( (PINB & (1<<BUTTON1)) == 0 )    // если нажата кнопка
          {
          PORTB |= ((1<<OUT)|(1<<LED));           //вкл
          _delay_ms (45000);                       // пауза 
          }
          PORTB &= ~((1<<OUT)|(1<<LED));          //выкл         
    }

повторное чтение?

2. у ТС четко сформированы задача

On 24.07.2019 at 10:01, brusel said:

по нажатию кнопки на несколько секунд появлялся высокий уровень на выходах LED и OUT

читай по спадающему фронту на пине.  в коде выше  при удержании кнопки таймер работает в цикле:  работа 45сек/ пауза 50мс.

теперь, если кнопка будет отпущена в конце "работа" и в момент опроса пина при дребезге будет прочитан лог0 = будет перзапуск таймера.

так понятно или надо на картинках показывать?

1 hour ago, Starichok said:

в принципе пропуск возможен - когда опрос попадет точно на разомкнутую цепь во время дребезга. и это вообще не горе, подержишь кнопку нажатой, пока она не сработает в следующем цикле опроса. 

я об этом и говорил , но в случае задачи ТС это заранее расставленные грабли на плохо отлавливаемый баг в процессе работы.

1 hour ago, Starichok said:

а еще можно сделать так - лет 20 с гаком я такой алгоритм подсмотрел у профессиональных программистов.

опрашиваем кнопки довольно часто и имеем на каждую кнопку свой счетчик нажатого состояния.

а потом в главном цикле проверяем счетчики кнопок.

что собственно и делает код приведенный мной выше.

Share this post


Link to post
Share on other sites
11 minutes ago, IMXO said:

если кнопка будет отпущена в конце "работа" и в момент опроса пина при дребезге будет прочитан лог0

Это всего-навсего означает, что кнопку передержали более 45 секунд, и таймер пошёл на новый круг. При чём тут дребезг?

Точно такая же ситуация будет и при идеальной кнопке без дребезга. Продержите её на миллисекунду дольше, чем 45 сек, и таймер точно так же перезапустится.

Share this post


Link to post
Share on other sites
30 minutes ago, Yurkin2015 said:

Это всего-навсего означает,

 что код изначально не фиксирует фронт и подавление дребезга в нем нет.

 

Share this post


Link to post
Share on other sites

То, что топикстартер не корректно обрабатывает события нажатий, не означает, что его код чувствителен к дребезгу кнопки. 

Ранее я спрашивал: что я делаю не так, если делаю так же и не имею проблем? И не один я...

Share this post


Link to post
Share on other sites

то что вы не видете/ не замечаете суслика не значит что его нет.

элементарная симуляция опроса кнопки

системный тик кнопки = 100мс

первое нажатие = 120мс

второе = 430мс

дребезг=20мс

1022800334___.png.471a10827eb239c83039c44ea9780430.png

куда потерялось нажатие

Share this post


Link to post
Share on other sites
1 hour ago, IMXO said:

куда потерялось нажатие

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

С идеальной кнопкой без дребезга тоже будут пропуски нажатий, если время нажатия меньше периода опроса кнопки.

Чтобы гарантировано не было пропусков нужно обеспечить время удержания кнопки дольше, чем период опроса плюс длительность "дребезга".

Вот увеличьте немного

1 hour ago, IMXO said:

первое нажатие = 121мс

и проверьте, есть ли суслик на самом деле.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

  • Сообщения

    • Всё бы Вам об плохом думать..., мало ли применений туалетной бумаги не по прямому её назначению (ну не всё же только  Вам пилу к смычку прилаживать) Туалетная бумага (ТБ) - прекрасный, одноразовый, довольно прочный обтирочный материал, хорошо впитывающий любую жидкую субстанцию, от воды до машинного масла, практически не оставляющая ворса.... (одно из применений ТБ не по назначению - протираю ФЭУ и сцинтилляционный детектор, перед нанесением масла для лучшего оптического контакта).... , стекловата тут точно не прокатит ,  а то что Вы подумали -  С уважением, Сергей  
    • Трилогию "назад в будущее "вспомнил.Док у Дока спросил:-у Вас случайно с собой нет ключа на 12?
    • TL081 в качестве IC2 не пригоден. Да и вообще тут вся линейка TL0xx не пригодна. То есть работать может и будет, но без гарантии, и возможно, недолго.  В эту схему надо ставить те оперы, которые позволяют подавать на вход напряжение, превышающее напряжение питания. Например OPA134, OPA627 , и так далее. В даташе это должно выглядеть примерно так (смотрим вторую строчку, Vin): Но если даташ дурниной орёт, что: то это повод хотя бы слегка напрячься  Несколько лет назад делал себе двухполярный БП со следящим плечом по такому же принципу. В плюс ставил NE5534, в минус, в слежение - OPA134. Для пробы втыкал в слежение и TL071 - в режиме "воткнул_оба-на_работает" работало, но набирать статистику не стал 
    • Тёзка, я-то как раз умею. Ибо занимался этими вопросами профессионально и даже выполнял по ним научную тему в лаборатории электрофизиолгии, когда ейной заведовал. Мне просто любопытно, сколько нужно ламерам понаступать на грабли чтобы они убедились-таки. что они ламеры? Всё, что я здесь публикую - это МОИ СОБСТВЕННЫЕ разработки. Да, в большинстве своём они  мелкие, простые, но они МОИ, а не скопированные со сторонних ресурсов!
    • Благодарю Вас! Вы не смогли бы подсказать как правильно называется данный аппарат, пожалуйста?
    • А мультиметром проверить религия не позволяет?
    • При ремонте БП столкнулся с интересным случаем. конденсатор 470n 275V X2. При проверке емкости на трех приборах (UT61E MG328 DE-5000) емкость в рамках допуска. Однако DE-5000 при изменении частоты проверки на 120Hz показал норму, на 1kHz разница в 20%, на 10khz в 50%, а на 100 килогерцах емкость составила аж 15nF! Так как с таким сталкиваюсь впервые - соответственно вопрос - что это такое и с чем это едят. P.S: LCR метр DE-5000 полностью исправен - на других кондерах как и должно быть, почти незаметные изменения емкости от частоты.
  • Покупай!

×
×
  • Create New...