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

Подавление Дребезга Клавиш В Прерывании


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

Здравствуйте!

Пишу на С. МК мега16. проблема заключается в том, что когда дребезджит контакт, подающий сигнал на PD2 (INT0), то прерывание вызывается дважды. Пытался решить проблему путем вставкм задержки, но результата это не дало. Как проще всего избавится от такого?

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

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

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

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

Учение - изучение правил. Опыт - изучение исключений.

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

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

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

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

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

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

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

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

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

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

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

Почему нельзя вешать кнопки на вход прерывания?

Нормальное решение, но нужно давить дребезг.

1) В обработчике прерывания запрещаем это прерывание.

2) Включаем отсчёт времени для подавления дребезга (50миллисекунд например, или больше, это дело вкуса )

.....

.....

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

4) разрешаем прерывание.

Всё.

Удачи!

Пока ты жив, надежда есть.

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

Я не спорю что так можно делать но сам факт то что всёравно при подавлении пропускаете прерывание :) Зачем это надо?? Кнопку всёравно быстро не нажмёте и не отпустите.. Если правильно сканировать програмно кнопку - то всё можно обработать в разы проще и главное надёжней!!!

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

С Вовой согласен в смысле бездарного расходования входов внешних интерраптов на примитивные кнопки..., причем один вход - одна кнопка (если без доп.схемотехники)...

戦う前に相手のベルトの色に注目

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

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

Нет, прерывание стоит по возростанию уровня.

Вобщем не раекомендуется на прерывания вешать кнопки

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

очему нельзя вешать кнопки на вход прерывания?

Нормальное решение, но нужно давить дребезг.

1) В обработчике прерывания запрещаем это прерывание.

2) Включаем отсчёт времени для подавления дребезга (50миллисекунд например, или больше, это дело вкуса )

.....

.....

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

4) разрешаем прерывание.

Всё.

Удачи!

О! это как раз то, ято мне нужно (в прерывании итак есть програмная пауза (так надо!))

Как сбросить флажки запроса на прерывание?

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

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

Нельзя такие вещи писать интуитивно - не выйдет...

戦う前に相手のベルトの色に注目

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

Контакты никогда не вешают на прерывания напрямую...

Правда никогда? Даже с целью пробудить проц из глубокого анабиоза?...

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

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

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

Нельзя такие вещи писать интуитивно - не выйдет...

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

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

Bit 6 – INTF0: External Interrupt Flag 0

When an edge or logic change on the INT0 pin triggers an interrupt request, INTF0

becomes set (one). If the I-bit in SREG and the INT0 bit in GICR are set (one), the MCU

will jump to the corresponding interrupt vector. The flag is cleared when the interrupt

routine is executed. Alternatively, the flag can be cleared by writing a logical one to it.

This flag is always cleared when INT0 is configured as a level interrupt.

Для того, чтобы прерывание не повторялось, нужно обнулить бит 6 регистра GIFR?

Я правильно понимаю?

Да, еще, не совсем ясно представляю, как это сделать. Можно ли просто написать:

GIFR=GIFR&0b100000;

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

Иногда, чтобы исправить "небольшой баг" приходится переделывать половину проекта :)

GIFR=GIFR&0b100000;
- вот так точно писать не нужно! таким образом ты только оставишь нужный бит, все остальные обнуляются. тебе надо использовать логическую операцию OR или применить битовую команду.

Кстати говоря, это от дребезга контактов ТОЖЕ НЕ СПАСЕТ. Ведь при отпускании кнопки так же возникает пачка ипульсов, как и при её нажатии! Единственный простой выход в данной ситуации - использовать аппаратный подавитель дребезга в виде одновибратора. Более сложный - отказаться от использования прерывания в этих целях(только для пробудки контроллера).

Учение - изучение правил. Опыт - изучение исключений.

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

При использовании прерываний в обработке дребезга совершенно безразлично какой дребезг подавлять - при нажатии или при отпускании. Разница лишь в том, что при нажатии его факт фиксируется ДО задержки, а при отпускании ПОСЛЕ. Т.е. каждое нажатие (и последующее за ним отпускание приведет к обработке ДВУХ прерываний. Смысл каждого примитивно прост - выключить прерывания по ЭТОМУ ВХОДУ на время дребезга. Для этого не нужно торчать в обработчике, достаточно после первого входа выставить флаг нажатия, запустить таймер на время дребезга, сбросить флаг этого прерывания и мигом вылететь из обработчика. Когда таймер свое отсчитает, снова разрешить эти прерывания и при следующем входе по нему все повторить, но после таймера уже сбросить флаг нажатой кнопки. Сам этот флаг и будет семафором(переключателем) в программе...

При таком раскладе в прерывании мы торчим минимум и программа не блокируется на время дребезга.

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

Изменено пользователем my504

戦う前に相手のベルトの色に注目

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

Да, еще, не совсем ясно представляю, как это сделать. Можно ли просто написать:

GIFR=GIFR&0b100000;

Для сброса бита( сбрасываемый бит равен нулю )

GIFR &= 0b11101111;

Для установки бита ( устанавливаемый бит равен 1 )

GIFR |= 0b10000;

Изменено пользователем mazzi

Пока ты жив, надежда есть.

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

Для сброса бита( сбрасываемый бит равен нулю )

GIFR &= 0b11101111;

Для установки бита ( устанавливаемый бит равен 1 )

GIFR |= 0b10000;

:) Я понял - все наоборот надо делать))) на против тех, что не надо обнулять, ставится 1)))

только у меня номер бита - 6, а здесь, по моему, 4-й обнуляется и выставляется :huh:

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

  • 3 недели спустя...
:) Я понял - все наоборот надо делать))) на против тех, что не надо обнулять, ставится 1)))

только у меня номер бита - 6, а здесь, по моему, 4-й обнуляется и выставляется :huh:

Совершенно верно.

Пока ты жив, надежда есть.

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

  • 1 год спустя...

Прошу помочь с решением сл. задачи:

Имеется 4 кнопки, подключенных к порту мк, опрос провожу в основном цикле + антидребезг, вобщем на выходе имеем регистр с флагами состояния кнопок. Нужно чтобы МК фиксировал нажатие 1 раз: нажали кнопку, мк зафиксировал нажатие, установил флаг кнопки, а при следующем опросе кнопок сбрасывал флаг нажатия, пока кнопка не будет отпущена.

Второй день думаю, ничего толкового не получается. Надеюсь на помощь!

С уважением, Дмитрий

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

Выкладывайте код.

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

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

Учение - изучение правил. Опыт - изучение исключений.

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

То есть сравнение этих двух регистров нужно проводить перед процедурой обработки нажатой кнопки и при состоянии нажато - нажато

просто пропускать эту процедуру? Про дополнительный рег-р думал и даже завел его, понятно что нужно запомнить предидущее состояние и впоследствии сравнивать его сновым, но вот реализовать сам алгоритм никак не получалось... :rolleyes:

Изменено пользователем malecdima

С уважением, Дмитрий

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

  • 2 года спустя...

char

detect_buttons_in_delay(

int

delay)

{

static

char

previous_port = 0xFF;

int

quant_count = delay / 10;

for

(

int

quant_number = 0; quant_number < quant_count;

++quant_number)

{

char

current_port = PIND;

char

buttons = ~current_port & previous_port;

previous_port = current_port;

if

(buttons)

return

buttons;

_delay_ms(10);

}

return

0x00;

} попробуй такой оброботчик кнопки у меня всегда работает без отказно да и еще попробуй конденсатор поставить с кнопкой в парарель

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

ужас-ужас, отлучать за такое надо от церкви. Дребезг же подавляется путем синхронного считывания состояния кнопки с интервалом 1..10мс и больше. Это прекрасно реализуется прерыванием от таймера, или в других частях прошивки где будет гарантировано считывание состояния кнопки не чаще чем 1 раз в 1..10мс.

конденсатор с кнопкой - плохой вариант, конденсатор со временем только усилит износ контактов кнопки, а дребезг не подавит.

Учение - изучение правил. Опыт - изучение исключений.

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

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

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

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

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

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

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

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

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

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

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