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

 
 
> программный антидребезг
krouli18
сообщение Mar 28 2013, 13:44
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 28-03-13
Пользователь №: 76 251



Нужно реализация программного антидребезгу при сканировании клавиатуры
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 13)
kovigor
сообщение Mar 28 2013, 14:47
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(krouli18 @ Mar 28 2013, 17:44) *
Нужно реализация программного антидребезгу при сканировании клавиатуры

Для какого МК ?
В Google введите нечто вроде: "Микроконтроллер подавление дребезга" и поищите готовый исходник, или напишите сами.
Само по себе подавление дребезга мало кому нужно, обычно оно входит в какой-то проект. Или это студенческий курсовой ?
Go to the top of the page
 
+Quote Post
Lmx2315
сообщение Mar 28 2013, 18:01
Сообщение #3


отэц
*****

Группа: Свой
Сообщений: 1 729
Регистрация: 18-09-05
Из: Москва
Пользователь №: 8 684



..фуу, первый успел пролезть в помошники.

Что конкретно надо???
В гугле смотрели??
?


--------------------
b4edbc0f854dda469460aa1aa a5ba2bd36cbe9d4bc8f92179f 8f3fec5d9da7f0
SHA-256
Go to the top of the page
 
+Quote Post
Lotor
сообщение Mar 29 2013, 04:41
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 476
Регистрация: 3-07-07
Из: Санкт-Петербург
Пользователь №: 28 866



Цитата(krouli18 @ Mar 28 2013, 17:44) *
Нужно реализация программного антидребезгу при сканировании клавиатуры

Первое, что Вам нужно - разобраться в склонениях. После этого прислушаться к совету kovigor и попробовать вникнуть в то, что нагуглили. И если будет что-то не понятно - спрашивать на форуме. При этом не надо дублировать темы. Как-то так. =)


--------------------
Ковырял чукча отверткой в ухе, звук в телевизоре и пропал.
Go to the top of the page
 
+Quote Post
редактор
сообщение Mar 29 2013, 06:00
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Алгоритм программного антидребезга может выглядеть примерно так.
Если состояние кнопки изменилось -> начать отсчет времени антидребезга
Иначеsad.gif Если состояние кнопки не менялось)
Если ведется отсчет времени и время истекло -> зафиксировать текущее состояние кнопки. Остановить таймер.

Отсчет времени можно вести по таймеру или по количеству опросов (особенно если они регулярные).
Более детальную реализацию думаю сами осилите.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 29 2013, 06:23
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



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

2. подождать 10-15 миллисекунд


3. считать снова состояние кнопки

4. сравнить это состояние с тем, что запомнено на 1 шаге

5. если состояния РАЗНЫЕ - закончить алгоритм, считая, что кнопка не нажата (либо считая, что состояние кнопки то же самое, что было при прошлом опросе кнопки)

6. если состояния одинаковые, то обработать это состояние (нажато или не нажато)



--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
vladec
сообщение Mar 29 2013, 06:30
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 167
Регистрация: 3-10-05
Из: Москва
Пользователь №: 9 158



Еще более простой алгоритм: опрашивайте клавиатуру считывая состояние кнопок с интервалом 15 - 20 мс (или другое значение, превышающее время дребезга) и используйте считанные значения как истинные.
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 29 2013, 07:08
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(vladec @ Mar 29 2013, 10:30) *
Еще более простой алгоритм: опрашивайте клавиатуру считывая состояние кнопок с интервалом 15 - 20 мс (или другое значение, превышающее время дребезга) и используйте считанные значения как истинные.
недопустимо

доводим до абсурда: опрашиваем кнопку 1 раз в час - ровно в 00 минут и 00 секунд и 00 миллисекунд. а я нажимаю кнопку ровно за 3 миллисекунды до этого момента - в итоге опрос попадает как раз на время, пока кнопка дребезжит, и что при этом "опросится" - не известно


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Mar 29 2013, 08:06
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



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

CODE
//
#include "keyboard.h"
#include "encoder.h"
#include "hardware.h" /* зависящие от процессора функции работы с портами */

enum
{
KBD_BEEP_LENGTH = NTICKS(25), // длительность озвучивания нажатия

KBD_STABIL_PRESS = NTICKS(30), // was 20 время для регистраци нажатия
KBD_STABIL_RELEASE = NTICKS(30), // was 20 время для регистраци отпускания

KBD_MAX_PRESS_DELAY_LONG = NTICKS(600), // время для регистрации удержания кнопки с медленным автоповтором
KBD_PRESS_REPEAT_SLOW = NTICKS(400), // время между символами по медленному автоповтору

//KBD_MED_STAGE1 = NTICKS(200), // моменты, на которых вырабатывается очередной символ клавиши с быстрым автоповтором
//KBD_MED_STAGE2 = NTICKS(300),
//KBD_MED_STAGE3 = NTICKS(400),
//KBD_MED_STAGE4 = NTICKS(500),
KBD_TIME_SWITCH_QUICK = NTICKS(200), // с этого времени начинается быстрый автоповтор
KBD_PRESS_REPEAT_QUICK1 = NTICKS(50), // время между символами по быстрому автоповтору
KBD_PRESS_REPEAT_QUICK2 = NTICKS(5) // время между символами по очень быстрому автоповтору
};

// сделаны по 8 бит - при 200 герц прерываний 600 мс всего 120 тиков.
static uint_fast16_t kbd_press; /* время с момента нажатия */
static uint_fast16_t kbd_release; /* время после отпускания - запрет нового нажатия */

static uint_fast8_t kbd_last; /* последний скан-код (возврат при отпускании кнопки) */
static uint_fast8_t kbd_slowcount; /* количество сгенерированных символов с медленным автоповтором */

static uint_fast8_t kbd_beep; /* время с момента нажатия */

/* получение скан-кода клавиши или 0 в случае отсутствия.
* если клавиша удержана, возвращается скан-код с добавленным битом 0x80
* ОТЛАЖИВАЕТСЯ
*/
static uint_fast8_t
kbd_scan_local(uint_fast8_t * key)
{
const uint_fast8_t chinp = hardware_ged_pressed_key();
const uint_fast8_t notstab = (kbd_press < (KBD_STABIL_PRESS + 1));

if (chinp != KEYBOARD_NOKEY)
{
if (/*kbd_release != 0 && */ ! notstab && (kbd_last != chinp)) // клавиша сменилась в состоянии стабильного нажатия
{
// самое первое нажатие
kbd_last = chinp;
kbd_press = 1;
kbd_release = 0;
kbd_slowcount = 0;
//dbg_putchar('t');
return 0;
}
else if (kbd_release != 0 && ! notstab)
{
// Уже было застабилизировавшееся значение - не меняем ничего.
// kbd_last уже содержит правильное значение
// Нажатие должно исчезнуть когда-то наконец.
//dbg_putchar('k');
}
else if (kbd_press == 0)
{
// самое первое нажатие
kbd_last = chinp;
kbd_press = 1;
kbd_release = 0;
kbd_slowcount = 0;
//dbg_putchar('l');
return 0;
}
else if (notstab && (kbd_last != chinp)) // Ожидание стабилизации кода клавиши
{
kbd_last = chinp;
kbd_press = 1;
kbd_release = 0;
kbd_slowcount = 0;
//dbg_putchar('m');
return 0;
}

kbd_release = KBD_STABIL_RELEASE;

const uint_fast8_t flags = qmdefs [kbd_last].flags;
/* сравнение кодов клавиш, для которых допустим медленный автоповтор при длительном удержании */
if ((flags & KIF_SLOW) != 0) //(is_slow_repeat(kbd_last))
{
// клавиша может работать с медленным автоповтором
switch (++ kbd_press)
{
case KBD_MAX_PRESS_DELAY_LONG + KBD_PRESS_REPEAT_SLOW:
kbd_press = KBD_MAX_PRESS_DELAY_LONG; // позволяем ещё раз сюда попасть.

case KBD_MAX_PRESS_DELAY_LONG:
* key = qmdefs [kbd_last].code;
kbd_release = 0;
return 1;
}
return 0;
}
/* сравнение кодов клавиш, для которых допустим быстрый автоповтор при длительном удержании */
else if ((flags & KIF_FAST) != 0) //(is_fast_repeat(kbd_last))
{
#if KBD_ENCODER
// клавиша может работать с быстрым автоповтором
// Перестройка клавишами вместо валкодера
switch (++ kbd_press)
{
case KBD_TIME_SWITCH_QUICK:
if (kbd_slowcount < 20)
{
++ kbd_slowcount;
kbd_press = KBD_TIME_SWITCH_QUICK - KBD_PRESS_REPEAT_QUICK1;
}
else
kbd_press = KBD_TIME_SWITCH_QUICK - KBD_PRESS_REPEAT_QUICK2;
// формирование символа в автоповторе
encoder_kbdctl(qmdefs [kbd_last].code, 1);
//dbg_putchar('R');
//dbg_putchar('0' + kbd_last);
break;
default:
//dbg_putchar('U');
break;
}
return 0;
#endif
}
else
{
// клавиша может работать с длинным нажатием
if (kbd_press == KBD_MAX_PRESS_DELAY_LONG)
return 0; // lond_press symbol already returned
if (kbd_press < KBD_MAX_PRESS_DELAY_LONG)
{
if (++ kbd_press == KBD_MAX_PRESS_DELAY_LONG)
{
* key = qmdefs [kbd_last].holded; // lond_press symbol
//
return 1;
}
}
}
return 0;

}
else if (kbd_release != 0) // Нет нажатой клавишии - было нажатие
{
if (notstab)
{
kbd_press = 0; // слишком короткие нажатия игнорируем
kbd_release = 0;
//dbg_putchar('J');
return 0;
}
//dbg_putchar('r');
// keyboard keys released, time is not expire.
if (-- kbd_release == 0)
{
// time is expire
if ((qmdefs [kbd_last].flags & KIF_FAST) != 0)
{
#if KBD_ENCODER
// Перестройка клавишами вместо валкодера
//if (kbd_press < KBD_MED_STAGE1)
if (kbd_slowcount == 0)
{
encoder_kbdctl(qmdefs [kbd_last].code, 0);
//dbg_putchar('Q');
//dbg_putchar('0' + kbd_last);
}
//else
// dbg_putchar('F');

kbd_press = 0;
kbd_slowcount = 0;
return 0; // уже было срабатывание по быстрому автоповтору
#endif
}
else if (kbd_press < KBD_MAX_PRESS_DELAY_LONG)
{
* key = qmdefs [kbd_last].code;
kbd_press = 0;
kbd_slowcount = 0;

return 1; // срабатывание по кратковременному нажатию на клавишу.
}
else
{
kbd_press = 0;
kbd_slowcount = 0;
return 0; // уже было срабатывание по автоповтору или по длинному нажатию.
}
}
return 0;

}
else // нет нажатой клавиши и небыло нажатичя перед этим
return 0;
}

static volatile uint_fast8_t kbd_scancode = KBD_CODE_MAX;
static volatile uint_fast8_t kbd_repeat;
static volatile uint_fast8_t kbd_ready;

// вызывается с частотой TICKS_FREQUENCY герц
// после завершения полного цикла ADC по всем входам.
void
kbd_spool(void)
{
uint_fast8_t code;
if (kbd_scan_local(& code) != 0)
{
kbd_beep = KBD_BEEP_LENGTH;
board_keybeep_enable(1); /* начать формирование звукового сигнала */
//if (code != KBD_CODE_BW_AGC)
//{
// dbg_puts_impl("UPS!\n");
// for (;;)
// ;
//}
if (kbd_scancode == code)
++ kbd_repeat;
else
{
kbd_scancode = code;
kbd_repeat = 1;
}
}
else
{
if (kbd_beep != 0 && -- kbd_beep == 0)
board_keybeep_enable(0);
}
kbd_ready = 1;
}

uint_fast8_t
kbd_is_tready(void)
{
#if CPUSTYLE_ATXMEGA
#warning TODO: remove this
return 1;
#endif

uint_fast8_t f;

//disableIRQ();
f = kbd_ready;
//enableIRQ();
return f;
}

/* получение скан-кода клавиши и количества её повторов.
*/
uint_fast8_t kbd_scan(uint_fast8_t * key)
{
disableIRQ();
uint_fast8_t repeat;
if ((repeat = kbd_repeat) != 0)
{
* key = kbd_scancode;
kbd_repeat = 0;
kbd_scancode = KBD_CODE_MAX;
}
enableIRQ();
return repeat;
}

/* Проверка, нажата ли клавиша c указанным флагом
// KIF_ERASE или KIF_EXTMENU
*/
uint_fast8_t kbd_get_ishold(uint_fast8_t flag)
{
uint_fast8_t r;
disableIRQ();
r = (kbd_press != 0) && (qmdefs [kbd_last].flags & flag);
enableIRQ();
return r;
}

/* инициализация переменных работы с клавиатурой */
void kbd_initialize(void)
{
// todo: все присвоения нулями могут быть убраны.

////kbd_press = 0;
////kbd_release = 0;
////kbd_repeat = 0;
//kbd_scancode = KBD_CODE_MAX;


// таймер. Просто тут живёт.
////timer_0p1_s_repeat = 0;
}
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 29 2013, 09:10
Сообщение #10


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Имею три массива для обработки панели управления: массив нового состояния кнопок New, массив предыдущего состояния кнопок Old, массив обработанных кнопок Fix.
Опрашиваю кнопки с разумным интервалом, 64 раза в секунду, сохраняю в массиве New. Сравниваю со старым Old, полученным в прошлом опросе, и обработанными кнопками Fix. Если есть кнопка, состояние которой в New и Old одинаковое (устойчивое, не дребезжит), и отличается от Fix (еще не обработана), то выполняю обработку этой кнопки (посылаю по интерфейсу, в моем случае). После этого меняю состояние в массиве Fix. Дальше можно искать следующую кнопку с такими же свойствами. Ну, и в конце цикла не забываю перенести массив New в Old.
Таким образом, реагирую на любое нажатие или отпускание кнопок в любой комбинации. Для обнаружения изменившегося состояния кнопки мне нужно время (1/64 * 2 = 31 ms). Более частое дребезжание будет игнорировано.
P.S. Автоповтор, если нужно, делаю в программе, куда посылаю состояние кнопок. Пока кнопка нажата, можно с неким интервалом (первый больше) реагировать на кнопку. Когда придет информация, что кнопка отпущена, прекращаю.
Go to the top of the page
 
+Quote Post
Intel4004
сообщение Apr 1 2013, 09:52
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 48
Регистрация: 7-09-07
Из: Наб.Челны
Пользователь №: 30 364



Цитата(ARV @ Mar 29 2013, 11:08) *
недопустимо
доводим до абсурда: опрашиваем кнопку 1 раз в час - ровно в 00 минут и 00 секунд и 00 миллисекунд. а я нажимаю кнопку ровно за 3 миллисекунды до этого момента - в итоге опрос попадает как раз на время, пока кнопка дребезжит, и что при этом "опросится" - не известно

Вполне допустимо. Попали на дребезг сейчас - значит получим правильный результат в следующий опрос. Главное чтобы интервал опроса был заведомо больше времени дребезга и меньше времени реакции человека. 50-70 мсек - оптимум, при 100 уже чувствуется задержка...
Go to the top of the page
 
+Quote Post
ARV
сообщение Apr 2 2013, 03:59
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(Intel4004 @ Apr 1 2013, 13:52) *
Вполне допустимо.
сколько себя помню, все время стараются с дребезгом бороться. а решение-то, оказывается, элементарное! спасибо вам за совет, теперь мир изменится...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
dch
сообщение Apr 6 2013, 03:20
Сообщение #13


Профессионал
*****

Группа: Участник
Сообщений: 1 179
Регистрация: 15-09-04
Из: 141070 г. Королев МО, улица Горького 39-121
Пользователь №: 661



Цитата(ARV @ Apr 2 2013, 07:59) *
элементарное

Дай и я сюда плюну, обнаружители обычно просто строятся, в регистр вдвигается 0,1 (не нажата/нажата),
далее есть критерий обнаружения начала события (нажатия), продолжения (удерживания) и конца события (отпускания клавиши), обычно это столько единичек из столькото отчетов, например для начала нажатия можно
взять 2 единички из 3х отсчетов, аналогично для удержания и отжатия.
Go to the top of the page
 
+Quote Post
ilya-m
сообщение Apr 6 2013, 10:30
Сообщение #14


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

Группа: Свой
Сообщений: 165
Регистрация: 30-06-08
Из: С.-Петербург
Пользователь №: 38 642



Удобный механизм подавления дребезга - вертикальные счетчики.

Почитать о них можно тут -
http://www.compuphase.com/electronics/debouncing.htm
http://www.dattalo.com/technical/software/pic/debounce.html
http://www.electro-tech-online.com/microco...debouncing.html
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 09:31
Рейтинг@Mail.ru


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