У меня есть аппаратная кнопка, которую я подключил к прерыванию, но моя проблема в том, что она немного отскакивает, делая нажатие кнопки ненадежным. Я думаю, что многие из этих проблем будут решены с помощью выборки в основном цикле, но это технически неверно.
Являются ли прерывания более подходящими для внутрисхемной связи или же прерывания также подходят для аппаратных коммутаторов? Если да, то какие методы дебадинга я могу использовать?
Я попытался сохранить переменную таймера и сравнить ее с текущим временем, задержками и другими методами. Кажется, что отскоки настолько быстрые, что это не имеет значения.
interrupts
button
sampling
OneChillDude
источник
источник
Ответы:
Debouncing это часто задаваемые вопросы. Вы должны быть в состоянии найти ... почти неограниченное количество веб-страниц по этой теме. Смит также прокомментировал широко читаемый PDF Джек Гэнсл по этой теме. И со всеми этими ответами у вас есть как аппаратные, так и программные методы.
Я немного добавлю к этой «литературе», говоря в основном об идеях, которые еще недостаточно освещены. Но прежде чем я сделаю, один или два вопроса:
Поскольку я упомянул растяжение импульса с помощью 74121, а Джек Гэнсл не упоминает об этом, и никто из них здесь еще не упоминал, я могу также предоставить эту дополнительную ссылку в качестве дополнительного предлагаемого прочтения об использовании 74121 или 555 в качестве однократного таймер для устранения помех переключателей.
Теперь перейдем к наблюдению с помощью микроконтроллера.
Я обычно использую конечный автомат для обработки разбора. Это почти всегда вызывается обычным таймером "пульса", который я установил на8РС , где возможно. (Обычно я НЕ использую события прерывания, инициируемые фронтом, по нескольким причинам.)
Конечный автомат выглядит так:
смоделировать эту схему - схема, созданная с использованием CircuitLab
Значение DEBOUNCED для коммутатора может принимать значения «неактивно», «активно» и «неизвестно». Таким образом, вы можете убедиться, что ваше программное обеспечение ожидает, пока значение инициализации не установится после инициализации. Но обычно я не беспокоюсь об этом. Я заменяю «неизвестное» значение некоторым значением по умолчанию и просто использую систему двоичных значений.
Конечный автомат вводится, сначала устанавливая дебазированное значение по умолчанию, а затем переходя в состояние «ИЗМЕНЕНИЕ» конечного автомата. На каждом временном интервале (обычно8РС если мне это удастся), я прочитаю текущее значение переключателя и выполню обновление текущего состояния и, возможно, отклоненного значения. Тогда я просто ухожу. Код высокого уровня затем получает доступ только к отклоненному состоянию.
Если это имеет значение для меня, я также могу сохранить ранее обсужденное состояние. В этих случаях при обновлении самого дебазированного состояния я сначала скопирую это состояние в «ранее дебазированное состояние». Затем я могу использовать пару значений, чтобы определить, произошел ли отклоненный переход. Иногда меня не волнуют переходы. Иногда я делаю. Так что это зависит. Но во всех случаях я хочу знать только о переходах, которые были обсуждены. Меня никогда не волнуют грубые переходы. Код высокого уровня никогда не использует внутреннее состояние, которое конечный автомат использует для своей работы.
Одна из приятных особенностей этого метода заключается в том, что я могу сразу отменить весь порт коммутаторов. И я могу сделать это без единой ветви в коде прерывания тоже. Это означает очень быстрый и короткий отладочный код для ширины порта микроконтроллера (обычно шириной 8 бит). Пример из Atmel AT90 показывает, как это достигается с помощью события прерывания Timer0:
Теперь этот пример показывает полную сделку, включая предыдущие и текущие дебутированные значения переключателя. И он выполняет все необходимые переходы состояний, а также. Я не показываю инициализацию этого кода. Но вышеизложенное дает представление о том, как легко работает конечный автомат и как мало кода требуется для этого. Это довольно быстро и просто и не требует ветвления (что иногда включает в себя дополнительные циклы, а также дополнительное пространство кода).
Я предпочитаю использовать8РС время, потому что долгое, долгое тестирование с различными людьми, использующими оборудование, над которым я работал в прошлом, привело меня туда. Я пробовал более длительные периоды, и когда я делаю это, я начинаю заставлять людей говорить мне, что «отзывчивость» недостаточно «оживленная». (В наши дни, когда дети растут, работая в режиме реального времени в играх «стреляй», я мог бы даже сократить их еще больше. Они будут горько жаловаться на даже небольшие задержки, вызванные современными цифровыми телевизорами при настройке и отображении кадра.)
Некоторые люди будут иметь очень четкие представления о том, насколько четкой и отзывчивой должна быть система. Свежий и отзывчивый означает выборку чаще, а не меньше. Но лично я нахожу20РС Сроки наблюдения приемлемы. ( Хотя я не нахожу более продолжительные времена достаточно хорошими даже для меня.)
Обратите внимание, что упомянутый мной конечный автомат должен сначала войти в состояние SETTLED, а затем остаться там еще на один раз, прежде чем значение DEBOUNCED будет обновлено. Поэтому нажатие кнопки и ее удержание даже в самых лучших обстоятельствах потребует следующих действий:
Таким образом, новое состояние требует противодребезговой защиты как минимум 3-х выборок периодов времени для достижения.
Нажатие кнопки потребует не менее 6 раз для перехода из неактивного состояния в активное и затем обратно в неактивное состояние.
Я упомянул вышеупомянутые детали, так что совершенно ясно, что время выборки8РС означает, что это где-то между 16мс <t≤24РС перейти от неактивного к признанному активному обсуждаемому результату. И это займет другое24РС прежде чем государство может вернуться в неактивное состояние. Это минимум40мс <t≤48РС пройти весь цикл нажатия кнопки.
Использование более длительного времени выборки будет иметь соответственно более длительные периоды. С использованием20РС Я упомянул как «приемлемый» для меня уже тогда означает где-то вокруг 100мс <t≤120РС для всего цикла кнопки. И это становится прямо вверх в область , где люди действительно склонны замечать. Мне, конечно, не нравится «чувствовать», если оно длится дольше.
Если вы идете по этому пути, не будьте осторожны с использованием более длительного времени выборки. Если вы должны, то я думаю, что вы также должны сделать много испытаний с пользователями / потребителями.
А если вы разрабатываете код для клавиатуры для набора текста, используйте более короткие сроки. Рекорд для машинистки был установлен десятилетия назад на 217 оборотах в минуту. Это приводит к примерно одному ключу каждый45РС , Такие машинистки нажимают несколько клавиш в контролируемом порядке. Чтобы получить хорошую производительность для очень быстрых машинисток, использующих ртутно-смачиваемую герконовую систему переключения, я обнаружил, что2РС работал хорошо.
источник
Отключение может быть сделано в программном обеспечении, маскируя IRQ на время отскока, или аппаратно, добавляя удерживающий конденсатор с вашим временем отскока RC = T> в диапазоне от 1 до 15 мс в зависимости от размера переключателя.
источник
Для отмены отскока ПО запишите метку времени текущего события и проверьте задержку от последнего действительного события:
UPD: с небольшими изменениями вы можете зарегистрировать двойной клик:
источник
Прерывания также отлично подходят для аппаратных коммутаторов. Используя прерывания, вы избегаете большой траты ресурсов и, возможно, энергии, особенно если вы работаете с устройствами с питанием от батареи.
Кроме того, по мере того, как ваш код становится все больше и больше, вы увидите, что реализовать прерывания для кнопок еще проще, чем опросить их в основном цикле.
Что касается вашего опровержения, это, вероятно, проблема кодирования. Я обычно использую таймер ~ 10 мс для устранения неполадок при проверке на отпускание кнопки. Не забудьте также временно отключить прерывание кнопки во время его отмены, чтобы процедура прерывания не выполнялась несколько раз.
Если у вас все еще есть проблемы, опубликуйте код здесь, чтобы мы могли помочь.
источник
Это очень похоже на «Ответ Тони Стюарта», но я думаю, что его можно немного расширить.
Верхняя схема предназначена для прерывания на низком или на падающем фронте. Нижняя схема предназначена для прерывания на высокой или нарастающей границе.
смоделировать эту схему - схема, созданная с использованием CircuitLab
лично, учитывая стоимость конденсатора, мне стоит просто использовать его, а не беспокоиться о том, что мой программный сбой содержит ошибки.
Обратите внимание, что, как сказал Тони Стюарт, постоянная времени в этой цепи составляет 10 мс( R ∗ C или 10 к Ω * 1 μ F) , Это займет где-то от трех до пяти постоянных времени (в зависимости от чувствительности вашего микроконтроллера к кнопке, чтобы сбросить себя, поэтому, если у вашего микроконтроллера есть проблемы с повторением функции прерывания, это может быть причиной, и вам может потребоваться отрегулируйте колпачок / резистор, чтобы прерывание не происходило несколько раз (то есть, только если ваше прерывание настроено на работу с высоким или низким сигналом, а не с нарастающим или падающим фронтом.
Связанный с аппаратным устранением неполадок
источник
Люди медлительны, нам не нужно немедленное внимание микро, которое находится в диапазоне микросекунд.
Это, конечно, не единственный и не правильный способ всегда делать это, но я считаю, что в целом более разумно настроить таймер (многие микросхемы имеют системные тики), чтобы запускать прерывание через фиксированные интервалы и сдвигать состояние вывода в переменная для кода, чтобы рассмотреть позже. Вы в конечном итоге с вар, который полон пепла во время подпрыгивания
10010110 золы
но в определенные моменты времени вы получите эти 4 значения:
01111111 только что отклоненный
передний фронт 11111111 кнопка в устойчивом состоянии вверх
10000000 передний край только что отклоненный
00000000 кнопка в устойчивом состоянии вниз
Однако в большинстве случаев я просто использую счетчик, который сбрасывается во время подпрыгивания. Это быстро, проверено и легко сделать.
Если это не удается, тогда я пытаюсь сделать что-то более умное из документа Гансле, предложенного другими!
источник