Различия между прерываниями и выборкой для аппаратной кнопки?


8

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

Являются ли прерывания более подходящими для внутрисхемной связи или же прерывания также подходят для аппаратных коммутаторов? Если да, то какие методы дебадинга я могу использовать?

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


2
Прочитайте это: ganssle.com/debouncing.pdf
Смит

В основном цикле нет ничего плохого в том, чтобы выполнять выборку, если вы реагируете в основном цикле. Прерывания более уместны, если вы хотите реагировать асинхронно. Иногда да, а иногда нет.
Евгений Рябцев

Лучший способ отменить это простой фильтр нижних частот.
lucas92

Ответы:


8

Debouncing это часто задаваемые вопросы. Вы должны быть в состоянии найти ... почти неограниченное количество веб-страниц по этой теме. Смит также прокомментировал широко читаемый PDF Джек Гэнсл по этой теме. И со всеми этими ответами у вас есть как аппаратные, так и программные методы.

Я немного добавлю к этой «литературе», говоря в основном об идеях, которые еще недостаточно освещены. Но прежде чем я сделаю, один или два вопроса:

  1. Устранение неполадок в аналоговом оборудовании может привести к результатам, которых вы не можете достичь с помощью переключателя, «наблюдаемого» только в цифровой форме на периодической основе, путем опроса или даже событиями аппаратного изменения контактов. Но вы можете сделать «достаточно хорошо» для всех намерений и целей, в цифровом виде. Почти никто в наши дни не использует внешние аналоговые решения для устранения неполадок. Но я использовал все: от импульсного растяжения с использованием одного удара (74121) до техник, упомянутых здесь Джеком Гэнслом .
  2. Для тех, кто занимается только встроенным программированием и совсем не интересуется изучением электроники, дебасинг переключателей, вероятно, является одним из двух основных необходимых навыков. Рабочие светодиоды, вероятно, другой. И под этим я не имею в виду иметь только один навык в этом. Я имею в виду возможность сделать это несколькими способами. Таким образом , вы действительно делаете необходимость в полной мере воспринять то , что Джек Ganssle пишет о, и еще более, в отношении переключателей.

Поскольку я упомянул растяжение импульса с помощью 74121, а Джек Гэнсл не упоминает об этом, и никто из них здесь еще не упоминал, я могу также предоставить эту дополнительную ссылку в качестве дополнительного предлагаемого прочтения об использовании 74121 или 555 в качестве однократного таймер для устранения помех переключателей.


Теперь перейдем к наблюдению с помощью микроконтроллера.

Я обычно использую конечный автомат для обработки разбора. Это почти всегда вызывается обычным таймером "пульса", который я установил на8РС, где возможно. (Обычно я НЕ использую события прерывания, инициируемые фронтом, по нескольким причинам.)

Конечный автомат выглядит так:

схематический

смоделировать эту схему - схема, созданная с использованием CircuitLab

Значение DEBOUNCED для коммутатора может принимать значения «неактивно», «активно» и «неизвестно». Таким образом, вы можете убедиться, что ваше программное обеспечение ожидает, пока значение инициализации не установится после инициализации. Но обычно я не беспокоюсь об этом. Я заменяю «неизвестное» значение некоторым значением по умолчанию и просто использую систему двоичных значений.

Конечный автомат вводится, сначала устанавливая дебазированное значение по умолчанию, а затем переходя в состояние «ИЗМЕНЕНИЕ» конечного автомата. На каждом временном интервале (обычно8РСесли мне это удастся), я прочитаю текущее значение переключателя и выполню обновление текущего состояния и, возможно, отклоненного значения. Тогда я просто ухожу. Код высокого уровня затем получает доступ только к отклоненному состоянию.

Если это имеет значение для меня, я также могу сохранить ранее обсужденное состояние. В этих случаях при обновлении самого дебазированного состояния я сначала скопирую это состояние в «ранее дебазированное состояние». Затем я могу использовать пару значений, чтобы определить, произошел ли отклоненный переход. Иногда меня не волнуют переходы. Иногда я делаю. Так что это зависит. Но во всех случаях я хочу знать только о переходах, которые были обсуждены. Меня никогда не волнуют грубые переходы. Код высокого уровня никогда не использует внутреннее состояние, которое конечный автомат использует для своей работы.

Одна из приятных особенностей этого метода заключается в том, что я могу сразу отменить весь порт коммутаторов. И я могу сделать это без единой ветви в коде прерывания тоже. Это означает очень быстрый и короткий отладочный код для ширины порта микроконтроллера (обычно шириной 8 бит). Пример из Atmel AT90 показывает, как это достигается с помощью события прерывания Timer0:

.equ    SWPORTPINS  =   PINB
.def    SwRawCurr   =   r4
.def    SwRawPrev   =   r5
.def    SwState     =   r6
.def    SwDebCurr   =   r7
.def    SwDebPrev   =   r8

            ; Debounce the input switches.

                mov     SwRawPrev, SwRawCurr
                in      SwRawCurr, SWPORTPINS
                mov     Timer0Tmp1, SwRawCurr
                eor     Timer0Tmp1, SwRawPrev
                mov     Timer0Tmp0, Timer0Tmp1
                or      Timer0Tmp1, SwState
                mov     SwState, Timer0Tmp0
                mov     Timer0Tmp0, Timer0Tmp1
                com     Timer0Tmp0
                and     Timer0Tmp1, SwDebCurr
                and     Timer0Tmp0, SwRawCurr
                or      Timer0Tmp1, Timer0Tmp0
                mov     SwDebPrev, SwDebCurr
                mov     SwDebCurr, Timer0Tmp1

Теперь этот пример показывает полную сделку, включая предыдущие и текущие дебутированные значения переключателя. И он выполняет все необходимые переходы состояний, а также. Я не показываю инициализацию этого кода. Но вышеизложенное дает представление о том, как легко работает конечный автомат и как мало кода требуется для этого. Это довольно быстро и просто и не требует ветвления (что иногда включает в себя дополнительные циклы, а также дополнительное пространство кода).


Я предпочитаю использовать 8РСвремя, потому что долгое, долгое тестирование с различными людьми, использующими оборудование, над которым я работал в прошлом, привело меня туда. Я пробовал более длительные периоды, и когда я делаю это, я начинаю заставлять людей говорить мне, что «отзывчивость» недостаточно «оживленная». (В наши дни, когда дети растут, работая в режиме реального времени в играх «стреляй», я мог бы даже сократить их еще больше. Они будут горько жаловаться на даже небольшие задержки, вызванные современными цифровыми телевизорами при настройке и отображении кадра.)

Некоторые люди будут иметь очень четкие представления о том, насколько четкой и отзывчивой должна быть система. Свежий и отзывчивый означает выборку чаще, а не меньше. Но лично я нахожу20РССроки наблюдения приемлемы. ( Хотя я не нахожу более продолжительные времена достаточно хорошими даже для меня.)

Обратите внимание, что упомянутый мной конечный автомат должен сначала войти в состояние SETTLED, а затем остаться там еще на один раз, прежде чем значение DEBOUNCED будет обновлено. Поэтому нажатие кнопки и ее удержание даже в самых лучших обстоятельствах потребует следующих действий:

  1. изменить с УСТАНОВЛЕНО на ИЗМЕНЕНИЕ
  2. изменить с ИЗМЕНЕНИЯ на УСТАНОВЛЕННЫЙ
  3. остаться в заселенном состоянии, обновление отстает

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

Нажатие кнопки потребует не менее 6 раз для перехода из неактивного состояния в активное и затем обратно в неактивное состояние.


Я упомянул вышеупомянутые детали, так что совершенно ясно, что время выборки 8РС означает, что это где-то между 16РС<T24РСперейти от неактивного к признанному активному обсуждаемому результату. И это займет другое24РСпрежде чем государство может вернуться в неактивное состояние. Это минимум40РС<T48РС пройти весь цикл нажатия кнопки.

Использование более длительного времени выборки будет иметь соответственно более длительные периоды. С использованием20РС Я упомянул как «приемлемый» для меня уже тогда означает где-то вокруг 100РС<T120РСдля всего цикла кнопки. И это становится прямо вверх в область , где люди действительно склонны замечать. Мне, конечно, не нравится «чувствовать», если оно длится дольше.

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

А если вы разрабатываете код для клавиатуры для набора текста, используйте более короткие сроки. Рекорд для машинистки был установлен десятилетия назад на 217 оборотах в минуту. Это приводит к примерно одному ключу каждый45РС, Такие машинистки нажимают несколько клавиш в контролируемом порядке. Чтобы получить хорошую производительность для очень быстрых машинисток, использующих ртутно-смачиваемую герконовую систему переключения, я обнаружил, что2РС работал хорошо.


Время отказов варьируется от 0 для ртутных переключателей до «нескольких» мс для микротактильных переключателей до 30 мс для неуклюжих тумблеров, поэтому 8 мс - хорошее число, учитывая увеличение времени отскока при старении.
Тони Стюарт Sunnyskyguy EE75

@ TonyStewart.EEsince'75 Я решил провести обширное тестирование с пользователями, использующими оборудование с различными типами переключателей, и значение 8 мс является результатом анализа всей этой работы. (Я не особо беспокоился о «теории», поскольку практика создания и изготовления переключателей и их огромное разнообразие делали сбор и анализ этих данных пугающими.) Я всегда использую 8 мс, когда это возможно, так как это кажется быть отличным местом, учитывая многолетний опыт написания программного обеспечения, которое просто работает и когда послепродажные жалобы
стремятся

@ TonyStewart.EEsince'75 Кстати, это тестирование включает в себя использование ртутных реле с смачиванием в качестве части клавишных переключателей, используемых в клавиатурах (которые, я думаю, больше не производятся.) В этих случаях, тем не менее, Я иду к выборке 1-2 мс (зависит от единицы.)
Jonk

Этот лазерный садовый светильник, о котором я упоминал однажды назад ..., имеет тактильные мембранные переключатели дистанционного управления с низким временем отскока, но программист заставил их переключаться с частотой 10 Гц, поэтому их нужно отпустить за <100 мс, иначе питание будет отключено. ?. на другом замечании ... Клавиатура для фортепиано Yamaha чрезвычайно быстрая и поддерживает 10-клавишное переключение клавиш, в то время как только оригинальная клавиатура IBM PC поддерживает истинное переключение на передний край. С тех пор все клавиатуры - 1-ые удары - передний край, а затем опрокидывание заднего края, которое является PITA для плохих навыков ввода текста, как у меня
Тони Стюарт Sunnyskyguy EE75

@ TonyStewart.EEsince'75 Эта область выборки переключателей является больным вопросом. Появление дешевых микросхем с нулевым внешним устранением неполадок и переключателем «кто знает, что», добавленным к незнанию встроенного программиста, привело к тому, что я фактически нахожу проблемы с почти КАЖДЫМ встроенным инструментом с клавиатурой или кнопкой. Они ВСЕ работают ужасно, по моему выбору. И я думаю, что это в основном потому, что у программистов практически нет опыта, просто «подумай и применись» без раздумий. Иногда засоляют свой код даже случайными пунктами опроса. Это фигня. Осадка. Это легко получить право.
января

5

Отключение может быть сделано в программном обеспечении, маскируя IRQ на время отскока, или аппаратно, добавляя удерживающий конденсатор с вашим временем отскока RC = T> в диапазоне от 1 до 15 мс в зависимости от размера переключателя.

  • например, напряжение 100 кОм и 0,1 мкФ на коммутаторе = 10 мс при 63% или ~ 8 мс при 50% Vdd или при использовании триггерного затвора Шмитта при 1,33 В = Vil от 5 В или ~ 73% В + ~ 12 мс

4

Для отмены отскока ПО запишите метку времени текущего события и проверьте задержку от последнего действительного события:

#define DELAY_DEBOUNCE       150

uint32_t    __ts_lastpress = 0;

ISR(some_vector)
{
    uint32_t    now = millis(); // some timer tick counter

    if ( now - __ts_lastpress < DELAY_DEBOUNCE )
        return; // ignore it

    __ts_lastpress = now;
    // do the job here
}

UPD: с небольшими изменениями вы можете зарегистрировать двойной клик:

#define DELAY_DEBOUNCE       150
#define DELAY_DOUBLE_CLICK   600

uint32_t    __ts_lastpress = 0;

ISR(some_vector)
{
    uint32_t    now = millis(); // some timer tick counter

    if ( now - __ts_lastpress < DELAY_DEBOUNCE )
        return; // ignore it

    // do the job here
    if ( now - __ts_lastpress < DELAY_DOUBLE_CLICK )
    {
        // it is double click
    }
    else
    {
        // it is single click
    }

    __ts_lastpress = now;
}

2

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

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

Что касается вашего опровержения, это, вероятно, проблема кодирования. Я обычно использую таймер ~ 10 мс для устранения неполадок при проверке на отпускание кнопки. Не забудьте также временно отключить прерывание кнопки во время его отмены, чтобы процедура прерывания не выполнялась несколько раз.

Если у вас все еще есть проблемы, опубликуйте код здесь, чтобы мы могли помочь.


1

Это очень похоже на «Ответ Тони Стюарта», но я думаю, что его можно немного расширить.

Верхняя схема предназначена для прерывания на низком или на падающем фронте. Нижняя схема предназначена для прерывания на высокой или нарастающей границе.

схематический

смоделировать эту схему - схема, созданная с использованием CircuitLab

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

Обратите внимание, что, как сказал Тони Стюарт, постоянная времени в этой цепи составляет 10 мс (р*С или 10КΩ*1μF), Это займет где-то от трех до пяти постоянных времени (в зависимости от чувствительности вашего микроконтроллера к кнопке, чтобы сбросить себя, поэтому, если у вашего микроконтроллера есть проблемы с повторением функции прерывания, это может быть причиной, и вам может потребоваться отрегулируйте колпачок / резистор, чтобы прерывание не происходило несколько раз (то есть, только если ваше прерывание настроено на работу с высоким или низким сигналом, а не с нарастающим или падающим фронтом.

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


1
Любая версия работает как для + ve, так и для -ve, особенно если вывод прерывания имеет входную характеристику стиля Шмитта (многие это делают). И SW1, и SW2 испытывают скачок тока при закрытии. Некоторые кнопки с карбоновыми кнопками могут давать результаты, отличные от кнопок с металлическим куполом.
glen_geek

1

Люди медлительны, нам не нужно немедленное внимание микро, которое находится в диапазоне микросекунд.

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

10010110 золы

но в определенные моменты времени вы получите эти 4 значения:
01111111 только что отклоненный
передний фронт 11111111 кнопка в устойчивом состоянии вверх
10000000 передний край только что отклоненный
00000000 кнопка в устойчивом состоянии вниз

Однако в большинстве случаев я просто использую счетчик, который сбрасывается во время подпрыгивания. Это быстро, проверено и легко сделать.
Если это не удается, тогда я пытаюсь сделать что-то более умное из документа Гансле, предложенного другими!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.