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

Новые контролллеры VIPerPLUS - практический вебинар 10 июня от ST

В программе вебинара - новые контроллеры VIPerPlus, расширяющие границы применения этих компонентов. Обзор их характеристик и преимуществ. Практика. Демонстрация испытаний из лаборатории ST. Пример моделирования в среде E-DesignSuite.

Зарегистрироваться

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
                     

Технология SOI против паразитных эффектов в драйверах затвора

Микросхемы драйверов затвора силовых транзисторов, изготавливаемые по технологии монолитного кремния, подвержены негативному влиянию отрицательных напряжений, возникающих на опорном выводе для верхнего плеча. Технология «Кремний-на-изоляторе» (Silicon-on-insulator, SOI) является надежным решением этой проблемы, о чем свидетельствуют результаты испытаний трех микросхем драйверов затвора полумостовой схемы, в том числе – SOI-драйвера производства Infineon.

Читать статью

13 hours ago, brusel said:

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

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

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

 

 

Share this post


Link to post
Share on other sites

Грубо говоря, есть. Опрос кнопок будет выполняться с интервалом в 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.

  • Сообщения

    • Приветствую! Ну вот, пришел новый моноблок, а в месте с ним, несколько вопросов. В мануале вычитал, что длинна минусового провода к усилителю, должна быть минимальна, не более 60см. С чем связано? Уменьшение общей длинны цепи, для уменьшения просадок по питанию? Помехи? Выходы на динамик в усилителе, уж что то маленькие совсем в диаметре (3,2мм), зато выводов четыре, два плюса и два минуса. Не будет ничего плохого, если я кину от усилителя к динамику два плюса и два минуса, для увеличения общего сечения проводов? Чтобы не было просадок сигнала на участке усилитель - динамик.  А то длина проводов большеватая получается, минимум метр с хвостиком.  
    • так добавь до кучи еще и интерферометр и пиролизный котел ....   Только вот потом и вырастают такие ТУПЫЕ и ПЕРЛЫ о его необходимости и полезности тут ..... один просто поставил, другой - потому, что у него был и так сделал первый, а третий - ищет и без него не начинает собирать УНЧ, поскольку два дурака до него поставили и сказали, что так надо .... Да, так возвращаясь к сути поста и вопроса  я так и не услышал и не записАл   Попытка номер три .... Подскажу - слово - не воробей, молчание - золото, сказал А - говори Б .... но ты перечеркнул ВСЕ ЭТО .... теперь надобно ответить за базар ....
    • Не то что любимая. Пока сабвуфер делал пару раз чуть не заснул..  
    • начинай .... таких советчиков - по 10 страниц НИ О ЧЕМ в темах - результат - един и прогнозируемый мной - ТОЛКУ НОЛЬ .... Если нет базы - НОЛЬ - на выходе - НОЛЬ .... Если ему не нужно ЧИТАТЬ и ДЕЛАТЬ - я ЗА НЕГО - не буду писАть ему мануал по ремонту и пересказывать материал книг и форумов. вот таких и подобных советов - про литы, пропаять, постучать, посЦать в него, поизмерять с умным видом и будет как раз с десяток страниц .... а толку - НОЛЬ .... мне нет смысла и НЕ ИНТЕРЕСНО и НАХЕР НЕ НУЖНО объяснять ему прописные азы ремонта - он ОБЯЗАН это читать САМ, раз полез в ТВ .... Но ... все, что нужно и приведет к результату я ему ТЕЗИСНО ДАЛ в одном предложении выше .... Осталось прочесть, найти, осознать и сделать.
    • не зависит на рабочую частоту, в самом первом приближении
    • Далее если двигаться в том же направлении то пройдём Кебу, Яна Хаммера и подойдём к АстроПилоту. А это уже космик эмбиент.  
    • Если не секрет-зачем? Неужто инетов начитался мол без оси звучит круто,ось убивает обертона и другой ереси?
×
×
  • Create New...