реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Подавление дребезга контактов, Алгоритм подавления,реализация
Axxel
сообщение Mar 28 2007, 08:12
Сообщение #1


Частый гость
**

Группа: Новичок
Сообщений: 140
Регистрация: 31-01-07
Из: Челябинск
Пользователь №: 24 896



Привет всем!

Написал небольшой кусочек кода для
подавления дребезга контактов, IMHO данный
код должен "фильтровать" ложные срабатывания
менее заданного периода.
Но почему-то не покидает ощущение того, что
в коде могут оказаться грабли smile.gif

Какие еще есть правильные методы,
либо можно это сделать проще или красивее?

Пример для одного бита порта ввода:

#define BOUNCE_CANCELLATION_PERIOD 20


unsigned char BITcounter=0; //счетчик состояний бита
bit BITstate=0; //используемое (устойчивое) состояние бита (более 20 мсек)
bit BITmemory=0; // промежуточная переменная, запоминающаяя предыдущее состояние бита
bit toggled=0; //флаг,указывающий на изменение состояния бита

interrupt Timer0() //возникает 1 раз в мсек
{
if(BITmemory^BITn){if(toggled){BITcounter=0;} toggled=1;}
if(toggled ){BITcounter++;}
if(BITcounter==BOUNCE_CANCELLATION_PERIOD){BITstate=BITn;BITcounter=0;toggled=0;
}
BITmemory=BITn; //чтение с порта
}



Вот, примерно так...

Сообщение отредактировал Axxel - Mar 28 2007, 08:34


--------------------
Если боишься - не говори. если сказал - не бойся. ©
Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Mar 28 2007, 08:50
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 920
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709



Давно и хорошо работающий код. Обслуживает несколько клавиш.

unsigned long int debounced_state = 0,debounced_stateOld = 0;
unsigned long int A = 0x0;
unsigned long int B = 0x0;
unsigned long int C = 0x0;

void debounce(unsigned long int new_sample)
{
unsigned long int delta;

delta = new_sample ^ debounced_state; //Find all of the changes

/* clock_A ^= clock_B; //Increment the counters
clock_B = ~clock_B;*/

A = A^(B&C);
B = B^C;
C = ~C;

A &= delta; //Reset the counters if no changes
B &= delta; //were detected.
C &= delta;

//Preserve the state of those bits that are being filtered and simultaneously
//clear the states of those bits that are already filtered.
debounced_state &= (A|B|C);
//Re-write the bits that are already filtered.
debounced_state |= (~(A|B|C) & new_sample);
}
Go to the top of the page
 
+Quote Post
NVade
сообщение Mar 28 2007, 09:54
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 71
Регистрация: 7-07-06
Из: Новосибирск
Пользователь №: 18 652



а я просто опрашиваю клавиатуру с интервалом большим, чем максимальное время дребезга. Скажем в первом примере вместо прерывания каждую 1 мс делать опрос раз в 20-50мс. Человек такую задержку не чувствует
Go to the top of the page
 
+Quote Post
IEC
сообщение Mar 28 2007, 10:08
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 22-03-05
Из: г. Харьков, Украина
Пользователь №: 3 598



Контролировать один раз нажатие клавиши (совет NVade) глупо, т.к. любой дребезг вызовет событие нажатия.

По хорошему необходимо контролировать время первого удержания клавиши (состояния порта) и через контрольный тайм-аут, если состояние ни разу не изменилось, принимать решение о нажатии клавиши. После этого необходимо переходить на другой этап и контролировать время отпускания. Через определенный тайм-аут принимать решение об завершении работы с клавишей.
И уже после всего этого можно переходить к повторному ожиданию нажатия клавиши.
Go to the top of the page
 
+Quote Post
Axxel
сообщение Mar 28 2007, 10:36
Сообщение #5


Частый гость
**

Группа: Новичок
Сообщений: 140
Регистрация: 31-01-07
Из: Челябинск
Пользователь №: 24 896



По хорошему необходимо контролировать время первого удержания клавиши (состояния порта) и через контрольный тайм-аут, если состояние ни разу не изменилось, принимать решение о нажатии клавиши. После этого необходимо переходить на другой этап и контролировать время отпускания. Через определенный тайм-аут принимать решение об завершении работы с клавишей.
И уже после всего этого можно переходить к повторному ожиданию нажатия клавиши.
[/quote]


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

Вопрос: нормально ли для этого алгоритма использование прерывания от таймера?
Может есть способы без прерываний?


--------------------
Если боишься - не говори. если сказал - не бойся. ©
Go to the top of the page
 
+Quote Post
SergCom07
сообщение Mar 28 2007, 12:07
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 41
Регистрация: 10-05-06
Из: Кожухово
Пользователь №: 16 943



Думаю лучший вариант реализуется при помощи прерываний от линий IO кнопок.
В этом случае изменение состояния линии не пропустишь, а по таймеру только проверять время, прошедшее с момента последнего изменения состояния и через скажем 20 мс фиксировать логическое состояние кнопки (нажата/нет).
Вопрос только в количестве кнопок и аппаратных прерываний, но у последних AVR их много.


--------------------
Дорогу осилит идущий туда
Go to the top of the page
 
+Quote Post
Visor
сообщение Mar 28 2007, 19:56
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 240
Регистрация: 23-03-07
Пользователь №: 26 428



На самом деле достаточно ловить первый фронт изменения состояния и через таймаут проверить сохранилось ли состояние. И не надо ждать когда сигнал перестанет дребезжать, и только потом включать выдержку времени, это бессмысленно. Подумайте. smile.gif
Go to the top of the page
 
+Quote Post
DeXteR
сообщение Mar 29 2007, 19:19
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 319
Регистрация: 2-08-05
Из: Одесса
Пользователь №: 7 287



Цитата(Visor @ Mar 28 2007, 20:56) *
На самом деле достаточно ловить первый фронт изменения состояния и через таймаут проверить сохранилось ли состояние. И не надо ждать когда сигнал перестанет дребезжать, и только потом включать выдержку времени, это бессмысленно. Подумайте. smile.gif


Если неждать то кто даст гарантию что после принятия решения о нажатой кнопке не происходит дребезга
А с дребезгом при отжатии как быть ??

По моему мнению самый верный способ - запускать програмный таимер по нажатию
Делать +1 если нажата и -1 если отжата
Ограничить нулем и числом А снизу и сверху
И принимать решение о точ что нажата кнопка когда таимер достигнет А

Заодно можно и блительное нажатие обрабатывать
Go to the top of the page
 
+Quote Post
rezident
сообщение Mar 29 2007, 19:32
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



На всех форумах одни и те же вопросы задаются smile.gif
http://www.telesys.ru/wwwboards/mcontrol/1...es/202772.shtml
Go to the top of the page
 
+Quote Post
Axxel
сообщение Mar 30 2007, 04:58
Сообщение #10


Частый гость
**

Группа: Новичок
Сообщений: 140
Регистрация: 31-01-07
Из: Челябинск
Пользователь №: 24 896



У меня примерно так:
Эскизы прикрепленных изображений
Прикрепленное изображение
 


--------------------
Если боишься - не говори. если сказал - не бойся. ©
Go to the top of the page
 
+Quote Post
Visor
сообщение Mar 31 2007, 19:06
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 240
Регистрация: 23-03-07
Пользователь №: 26 428



Цитата(DeXteR @ Mar 30 2007, 00:19) *
Если неждать то кто даст гарантию что после принятия решения о нажатой кнопке не происходит дребезга
А с дребезгом при отжатии как быть ??

Либо я не ясно выразился, либо одно из двух. smile.gif
Ловим фронт изменения входа (не важно какой), запоминаем новое состояние, ждем время достаточное чтоб дребезг успокоился, проверяем вновь состояние входа, если совпало, его и принимаем за текущее. Обрабытывается таким образом и вкл и выкл.
Go to the top of the page
 
+Quote Post
Axxel
сообщение Apr 2 2007, 05:12
Сообщение #12


Частый гость
**

Группа: Новичок
Сообщений: 140
Регистрация: 31-01-07
Из: Челябинск
Пользователь №: 24 896



А если произойдет такое?
Эскизы прикрепленных изображений
Прикрепленное изображение
 


--------------------
Если боишься - не говори. если сказал - не бойся. ©
Go to the top of the page
 
+Quote Post
Visor
сообщение Apr 2 2007, 06:09
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 240
Регистрация: 23-03-07
Пользователь №: 26 428



Цитата(Axxel @ Apr 2 2007, 10:12) *
А если произойдет такое?

Объясните пожалуйста, как такое возможно?
Go to the top of the page
 
+Quote Post
=AK=
сообщение Apr 2 2007, 06:25
Сообщение #14


pontificator
******

Группа: Свой
Сообщений: 3 015
Регистрация: 8-02-05
Из: страны Оз
Пользователь №: 2 483



Я проще делаю. В 8-битный сдвиговый регистр каждые 10 мс вдвигаю текущее состояние кнопки. Если в сдвиговом регистре все '1', то кнопка нажата, выходной сигнал устанавливаю в '1'. Если все '0', то кнопка отжата, выходной сигнал устанавливаю в '0'. Все другие комбинации игнорируются и не меняют состояние вых. сигнала.

При опроcе каждые 10 мс и 8-ми битах время получается 80 мс, это отлично работает со всеми обычными кнопками, в т.ч. с мембранными клавами. Для массивных контактов, которые могут дребезжать с малой частотой (контактор какой-нибудь, например), время опроса можно увеличить до 20..30 мс.
Go to the top of the page
 
+Quote Post
Axxel
сообщение Apr 2 2007, 07:28
Сообщение #15


Частый гость
**

Группа: Новичок
Сообщений: 140
Регистрация: 31-01-07
Из: Челябинск
Пользователь №: 24 896



Цитата(Visor @ Apr 2 2007, 09:09) *
Объясните пожалуйста, как такое возможно?


Помехи например, ложные срабатывания от датчиков, ведь такое IMHO может быть

Цитата(=AK= @ Apr 2 2007, 09:25) *
Я проще делаю. В 8-битный сдвиговый регистр каждые 10 мс вдвигаю текущее состояние кнопки. Если в сдвиговом регистре все '1', то кнопка нажата, выходной сигнал устанавливаю в '1'. Если все '0', то кнопка отжата, выходной сигнал устанавливаю в '0'. Все другие комбинации игнорируются и не меняют состояние вых. сигнала.

При опроcе каждые 10 мс и 8-ми битах время получается 80 мс, это отлично работает со всеми обычными кнопками, в т.ч. с мембранными клавами. Для массивных контактов, которые могут дребезжать с малой частотой (контактор какой-нибудь, например), время опроса можно увеличить до 20..30 мс.


Можно кусочек кода?

И еще вопрос: используя прерывания от аппаратного таймера для подавления
дребезга, с какой частотой целесообразнее всего устраивать эти прерывания?
И каков риск что пользовательская функция-обработчик не успеет обработаться
до возникновения следующего прерывания?


--------------------
Если боишься - не говори. если сказал - не бойся. ©
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th November 2017 - 12:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.01388 секунд с 7
ELECTRONIX ©2004-2016