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

Опросы кнопок на MEGA8 и MEGA16


tifaso

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

@IMXO, лучше убрать else ? что можно сделать чтобы все работало стабильно
пока что работает, я даже могу зажать кнопку на порту D6 и в то время нажимать D7, после чего отпустить D6 и все нажатия ловит

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

вы сообщения читаете? я же привел пример кода https://forum.cxem.net/index.php?/topic/222979-опросы-кнопок-на-mega8-и-mega16/&do=findComment&comment=3514038
где реализовано удаление джитера, независимая регистрация нажатия и отпускания кнопки, и текущие состояние кнопки.

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

@IMXO не увидел почему-то раньше пример кода.
А юарт там временно только для отладки

что-то я не пойму где у вас опрос флагов,
я вижу только функции

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

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей. Подробнее>>

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

нет, там все правильно. так  размечается структура битовых полей.
Jitter=8бит
 

1 час назад, Vit@lik сказал:

что-то я не пойму где у вас опрос флагов,

это показаны функции которые вызываются по таймеру, а флаги проверяются в основном цикле программы и делаются нужные действия.

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

подавление дребезга

сдвигаем jitter, в 0бит записываем лог1 если кнопка нажата,
если jitter=0xFF  считаем что кнопка нажата
если jitter=0x00  считаем что кнопка отжата
любое иное значение = дребезг игнорируем...

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

@IMXO  что-то трудно мне ваш код дается,. Мы сдвигаем Джитер влево и если значение не ноль, (если я правильно понимаю) при сдвиге влево будет каждый раз умножаться на два). Ниже если кнопка нажата или отпущена мы его инкрементируем тоесть тоже увеличиваем .. зачем? если джиттер будет больше 255 (потому что 8 бит) он переполниться и счет начинаться с нуля а где Джитер обнуляется? и как функция в таймере взаимодействует с флагами в основном цикле, через какие переменные
в общем не очень понимаю как работает ваш код...

пытаюсь разобраться
в начале программы у нас Джитер  = 0, когда кнопка нажата, мы его умножаем сдвигая в лево и инкрементируем пока он не достигнет 255  тогда мы ставим флаг m_button2.Pressed=1 , после того когда он переполнился и кнопка уже не нажата он сам сдвигается влево пока не переполниться и не уйдет в ноль и тогда ставим флаг m_button2.Pressed=0;
хм прикинул в голове вроде так оно работать должно, интересно еще посмотреть код что в основном цикле выполняется
 

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

m_button1.Pressed = флаг состояния кнопки нажата=1, отжата=0 (проверяется в основном коде)
m_button1.JustPressed = событие кнопка только что нажата =1 (флаг сбрасывается в основном коде после обработки)
m_button1.JustReleased= событие кнопка только что отпущена =1 (флаг сбрасывается в основном коде после обработки)

Мы сдвигаем Джитер...

0000 0000 <- 0 - кнопка отпущена m_button1.Pressed = 0
0000 0000 <- 1  - нажатие кнопки
0000 0001 <- 0 - дребезг
0000 0010 <- 1 - дребезг
0000 0101 <- 0  - дребезг
0000 1010 <- 1 - дребезг закончился
0001 0101<- 1
0010 1011<- 1
0101 0111<- 1
1010 1111<- 1
0101 1111<- 1
1011 1111<-1
0111 1111<-1
1111 1111<-1 кнопка нажата m_button1.Pressed = 1

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

@IMXO  А зачем так часто опрашивать кнопки, что аж тонкая структура дребезга видна?!? Опрашивайте в 10 раз реже, и всё будет пучком: либо нажата кнопка либо нет, никакого дребезга. Заодно и жизнь процессора облегчится :) 

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

8 минут назад, IMXO сказал:

Мы сдвигаем Джитер...

мы сдвигаем Джитер каждый раз когда заходим в прерывания независимо нажата ли кнопка или нет. И только когда кнопка нажата инкрементируем его...
а то что я в сообщении выше написал верно?

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

43 минуты назад, Yurkin2015 сказал:

А зачем так часто опрашивать кнопки,

почему вы решили что часто? обычный опрос раз в 1..2мс
жизнь заставляет писать код для приложений работающих в условиях сильных ЭМП , 
если помеха ловится в момент опроса пина без подавления джитера имеем ложное срабатывание.


То @Vit@lik  почти верно, только небольшое замечание: "сдвигается влево пока не переполниться" - джитер никогда не переполняется
когда jitter=0xFF при сдвиге получаем jitter=0xFЕ , прибавляем 1 снова получаем jitter=0xFF

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

@IMXO у меня онлайн интерпретатор выдает  0xFF<<1 равно 510
как тогда джитер обнуляется?

7 минут назад, IMXO сказал:

0xFF при сдвиге получаем jitter=0xFЕ

почему

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

10 минут назад, Vit@lik сказал:

онлайн интерпретатор выдает  0xFF<<1 равно 510

:lol2: приплыли... 510 это сколько бит?
ЗЫ а у jitter  какая размерность?
ЗЫЫ пора отправлять читать Герберта Шилдта

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

Только что, IMXO сказал:

510 это сколько бит?

9 вроде.
я имел в виду что при сдвиге влево величина должна увеличиваться, а при достижении максимума переполниться. Но почему в вашем случае этого не происходит не понимаю
у джитер 8 бит
вы напишите как он обнуляется? как тогда сработает if(m_button1.Jitter==0x00) {m_button1.Pressed=0;}

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

Только что, Vit@lik сказал:

хотя для 15-17 кнопок объем будет большой.

если нет особых требований к фиксации последовательности нажатий , то можно применить это : http://www.microchip.su/showpost.php?p=76885&postcount=22

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

@IMXO у меня такое чувство что в коде по ссылке ошибка 
как выполнится условие  if (!m_Buttons.ucJitter && ucTemp) если прямо перед ним мы инкрементируем m_Buttons.ucJitter++;  тоесть он будет больше 0
а в скобках инверсия тогоже !m_Buttons.ucJitter значит
первый операнд всегда лог0
возможно те две команды (или одну) что после самого первого if нужно в скобки и else перед ними

// Можно задать до 8 кнопок

#define pin_BUTTON0     RB0
#define pin_BUTTON1     RB1
#define pin_BUTTON2     RB2
#define pin_BUTTON3     RB3
#define pin_BUTTON4     RB4
#define pin_BUTTON5     RB5
#define pin_BUTTON6     RB6
#define pin_BUTTON7     RB7


typedef struct
{
    unsigned char   ucPressed;            // Состояния кнопок
    unsigned char   ucJitter    : 2;      // Для подавления дребезга
    unsigned char   ucCounter   : 6;      // Для проверки удерживания
    unsigned char   ucHold;               // Состояние длительного удерживания
                                          // События:
    unsigned char   ucShort;              // Короткое нажатие и отпускание
    unsigned char   ucJustPressed;        // Кнопки только что нажаты
    unsigned char   ucJustReleased;       // Кнопки только что отпущены
    unsigned char   ucChanged;            // Состояние кнопок изменилось

} TBUTTONS;

volatile TBUTTONS    m_Buttons;


void Task_Buttons (void)
{
    static  unsigned char s_ucPort;     // Предыдущее состояние портов
            unsigned char ucTemp;       

    ucTemp = 0x00;

    if (!pin_BUTTON0) ucTemp |= 0x01;
    if (!pin_BUTTON1) ucTemp |= 0x02;
    if (!pin_BUTTON2) ucTemp |= 0x04;
    if (!pin_BUTTON3) ucTemp |= 0x08;
    if (!pin_BUTTON4) ucTemp |= 0x10;
    if (!pin_BUTTON5) ucTemp |= 0x20;
    if (!pin_BUTTON6) ucTemp |= 0x40;
    if (!pin_BUTTON7) ucTemp |= 0x80;

    ucTemp      ^= s_ucPort;            // Изменения с момента последнего выполнения
    s_ucPort    ^= ucTemp;              // Текущее состояние портов

    if (ucTemp)                         // Подавление дребезга
    {
        m_Buttons.ucJitter = 0;
        return;
    }
    //------------------------------------------------------------------------------
    
    m_Buttons.ucJitter++;
    ucTemp = s_ucPort ^ m_Buttons.ucPressed;// Маска изменения состояние

    if (!m_Buttons.ucJitter && ucTemp)      // Состояние изменилось, дребезг подавлен
    {
        //------------------------------------------------------------------------------
        //  Проверяем отпущенные кнопки
        //------------------------------------------------------------------------------
        
        if (m_Buttons.ucPressed & ucTemp)   // Есть отпущенные
        {
            m_Buttons.ucJustReleased    |=  ucTemp;
            m_Buttons.ucChanged         |=  ucTemp;
            m_Buttons.ucShort           |=  ucTemp;
            m_Buttons.ucShort           &= ~m_Buttons.ucHold;
            m_Buttons.ucHold            &= ~ucTemp;
        }   // if released
        //------------------------------------------------------------------------------
        //  Проверяем нажатые кнопки
        //------------------------------------------------------------------------------
        if ((m_Buttons.ucPressed ^ ucTemp) & ucTemp)    // Есть нажатые
        {
            m_Buttons.ucChanged         |=  ucTemp;
            m_Buttons.ucJustPressed     |=  ucTemp;
            m_Buttons.ucShort           &= ~ucTemp;
        }   // if pressed

        m_Buttons.ucPressed = s_ucPort;
        m_Buttons.ucCounter = 0;
    }   // if changed and debounced

    m_Buttons.ucCounter++;
    //------------------------------------------------------------------------------
    //  Проверяем длительное удерживание
    //------------------------------------------------------------------------------
    
    if (m_Buttons.ucCounter == 50)
    {
        m_Buttons.ucChanged |= m_Buttons.ucHold ^ m_Buttons.ucPressed;
        m_Buttons.ucHold = m_Buttons.ucPressed;
    }

}

 

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

Кто-то может ответить как может работать этот код?
там черным по белому написано
инкремент m_Buttons.ucJitter++;  перед условием if.
а это значит что m_Buttons.ucJitter++ в любом случае буде больше нуля тоесть - true,
а потом скобах условия  if делаем Логическое отрицание-НЕ только для одного m_Buttons.ucJitter,
тоесть он всегда будет ЛОЖЬ,
у нас в if два операнда для Логического умножения-И, и первый всегда ЛОЖЬ, а если у нас хотя бы один операнд ЛОЖЬ все выражение становиться ЛОЖЬ.
Тоесть код в скобках после If не выполнится НЕКОГДА!
как оно может работать? в чем я не прав?

 m_Buttons.ucJitter++;
    ucTemp = s_ucPort ^ m_Buttons.ucPressed;// Маска изменения состояние

    if (!m_Buttons.ucJitter && ucTemp)      // Состояние изменилось, дребезг подавлен
    {
        //

 

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

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

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

  • Сообщения

    • @1960sae "Собирал когда то такой конструктор, запустился сразу....". блин. не могу управится с ним. все проверил. нашел пробитый конденсатор, поменял. питание от адаптера сделал 7,3в. регулятор четко 5,05 в держит. на ногах пика питание есть, на всех ногах тоже какая то напруга есть. ниче не греется, транзы холодные. но не работает и все. когда щупами проверял по выводам пика моргнули индикаторы один раз и все. осцилла нет. ума не приложу, интернет рою. пока нифига не смог победить. что смущает: по схеме (я выше здесь выложил) 8 резисторов (на индикаторы идут) по 220 ом, а в наборе они по 1 кОм (я их впаял). 
    • Кто сказал? Откуда такие знания? Опишите механизм появления искаженного звука. Точно не надо.
    • Здравствуйте. Чтобы не открывать новую тему по примитивному вопросу. На фото выше справа вверху стоит ионистор. На этой плате никаких элементов памяти я не вижу, поэтому скорее всего питание с ионистора подается вверх - на плату с МК.   Правильно ли я понимаю, что ионистор нужен для хранения текущего времени, а рабочая программа хранится в eeprom или flash на плате с МК (или в кишках самого МК)? Вопрос связан с тем, что прежде чем чинить эту LOGO, надо знать, сохранилась ли в нем программа. А чтобы узнать, сохранилась ли в нем программа, надо иметь соответствующую приблуду. Приблуду можно сотворить и самому, но если программа все-таки хранится в sram с питанием от ионистора, то никакого смысла делать приблуду нет, как и чинить LOGO. Просьба просветить, кто в курсе месте хранения рабочей программы в siemens logo. LOGO само собой старый: 6ED1052-1MD00-OBA5  
    • Против разумной, никаких. Кашкаровшина к ней не относится.
    • Так и делаю правильно, из за 50 гигов диск не попру никуда.
    • Доступ к файлам проекта, серверной части и график дизайнеру есть?
    • Эта платка напрямую к УСБ подключается, я через Arduino IDE заливал тот код, как в статье. Может правда панели плохие. Ножки не смог к плате припаять, припой вообще не ложился, поэтому проводочки только. Спасибо, а второй конденсатор обычный на 100 нанофарад? диод который уже у меня есть, его можно оставить? А код через арудино также заливать?
×
×
  • Создать...