Перейти к содержанию

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


brusel

Рекомендуемые сообщения

Привет, помогите сделать так, чтобы по нажатию кнопки на несколько секунд появлялся высокий уровень на выходах 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));          //выкл
    }
}

 

Ссылка на комментарий
Поделиться на другие сайты

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

Правильно? В протеусе вроде работает. Пауза где-то 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));          //выкл         
    }
}

 

Ссылка на комментарий
Поделиться на другие сайты

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

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

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

11 hours ago, brusel said:

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

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

Ссылка на комментарий
Поделиться на другие сайты

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

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

Изменено пользователем BARS_
Ссылка на комментарий
Поделиться на другие сайты

Just now, IMXO said:

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

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

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

4 hours ago, BARS_ said:

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

Just now, Yurkin2015 said:

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

65536 мс

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

2 hours ago, ARV said:

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

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

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

Just now, Yurkin2015 said:

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

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

Just now, IMXO said:

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

Мда...

Just now, IMXO said:

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

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

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

23 minutes ago, IMXO said:

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

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

 

24 minutes ago, IMXO said:

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

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

Ссылка на комментарий
Поделиться на другие сайты

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

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

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;} получаем таймер с перезапуском по фронту.

Ссылка на комментарий
Поделиться на другие сайты

Мда...

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

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

2 hours ago, IMXO said:

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

 

52 minutes ago, IMXO said:

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

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

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

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

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

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

 

Ссылка на комментарий
Поделиться на другие сайты

53 minutes ago, Yurkin2015 said:

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

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

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

1 hour ago, ARV said:

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

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

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

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

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

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

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

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

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

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

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

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

Мудрость приходит вместе с импотенцией...

Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.

Ссылка на комментарий
Поделиться на другие сайты

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

Ссылка на комментарий
Поделиться на другие сайты

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

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

11 minutes ago, IMXO said:

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

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

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

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

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

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

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

второе = 430мс

дребезг=20мс

1022800334___.png.471a10827eb239c83039c44ea9780430.png

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

Ссылка на комментарий
Поделиться на другие сайты

1 hour ago, IMXO said:

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

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

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

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

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

1 hour ago, IMXO said:

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

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

Ссылка на комментарий
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • Когда дверь открыта, сигнал блокирован, а когда закрыта - то на общих основаниях )) Реально полезное устройство, раньше все время бегали проверять, не вернулась ли домой собака. Фиг угадаешь. Потом заманивай ее...
    • То, что Я написал, Я подразумевал, что w25qReadPage читает реальный сектор w25 длиной 4096, если это не так, то нужно состыковывать w25qReadPage и disk_read.
    • ИК-датчик не подходит его котолапые видят. Ультразвуковой слышат, он их пугает. Рентгеновский ставить не будете сами понимаете почему Остается датчик давления. Тензодатчик 5кг 4шт + HX711 + дурина = проект выходного дня. Ну а ежли извращаться : под лоток резиновую грелку или камеру от велосипеда + шланг , в нее воду, к шлангу электро-контактный манометр.   
    • Всем привет! Я новичок. Помогите пожалуйста с ремонтом телевизора Электроника 25ТЦ-313Д ( а точнее Electroniсa C433, но как я понял это почти одинаковые модели). Предыстория такая. Сам телевизор был до меня передалан в монитор для спектрумов, все лишнее для приема каналов в нем отсутсвует, только подавай сигнал RGB и синхронизацию, в дальнейшем я и планирую его так и использовать. Когда он у меня появился телевизор так себе работал, я перепаял все электролиты на новые, но особо ничего не изменилось, и он не мог поймать нормально картинку ( подавал с тюнера спутникового тв через SCART)  , на секунду устаканивалась а потом пропадала. Я попробовал поэксперементировать с блоком кадровой развертки (BKR - 10), также перепаивал там электролиты, проверял все диоды и транзисторы, потом попробовал поменять микросхемы. Поменяв микросхему КА174ХА11 на некоторое время стало лучше, картинка была не четкая не отрегулирована, но стояла на месте, и я начал крутить крутилки... Что то случилось и после моих экспериментов все заглохло. Телевизор при включении пищал, но не было накала кинескопа, и пропало изображение вообще. При этом грелся конденсатор на 1,5 кВ возле регулировки фокуса, выпаяв и проверив его оказалось что он превартился в резистор.  Пошарившись по плате еще поменял транзистор КТ815б, он превратился в диод. После этих манипуляций накал появился, и начала проявлятся слабая и тусклая картинка фона, и по середине вертикальная полоска широкая, иногда цветов радуги , иногда просто зеленая немного выделяющаяся из фона. При этом начал грется подстроечный резистор "центровка по горизонтали" (отметил его на схеме). Не знаю что дальше делать, кто что может подсказать в какую сторону двигаться, какие напряжения проверить, сам я не особо разбираюсь, и еще осциллографа нет, только тестер. Буду очень рад за помощь. Электроника_25тц-313д_схема.pdf
    • кто скачал версию (архив) BootLoader12.zip, прошу скачать его заново. в первом посте я заменил архив. к сожалению, после одного изменения функции записи флеши я допустил критическую ошибку. в результате при определенной длине прошивки маленький "хвост" прошивки не записывался. я проверял на других файлах, где не было этого "обрезания". а сейчас на одном файле столкнулся с этой ошибкой.
    • @Сергей Азиатский , вы правы. Страдать фигнёй не запретишь.
×
×
  • Создать...