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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Подавление дребезга контактов, Алгоритм подавления,реализация
rezident
сообщение Apr 2 2007, 07:50
Сообщение #16


Гуру
******

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



Цитата(Axxel @ Apr 2 2007, 10:28) *
И еще вопрос: используя прерывания от аппаратного таймера для подавления
дребезга, с какой частотой целесообразнее всего устраивать эти прерывания?

Прерывания для опроса кнопок должны следовать с периодом превышающим дребезг клавиш. Частота следования от 3Гц до 100Гц. Меньше 3Гц неудобно для пользователя, слишком медленная реакция на клавиши. Выше 100Гц не имеет смысла, никакая супер-пупер машинистка-профессионалка не сможет в таком темпе печатать, это раз. А во-вторых, дребезг многих широкораспространенных тактовых и мембранных кнопок составляет как раз порядка 10мс.
Цитата(Axxel @ Apr 2 2007, 10:28) *
И каков риск что пользовательская функция-обработчик не успеет обработаться
до возникновения следующего прерывания?

А в чем состоит риск-то? Во вложенных прерываниях? Дык можно их не допускать. А если вложенные прерывания разрешены, то обходите повторный вызов функции и всех делов-то.
Код
__interrupt void TimerISR(void)
{ static unsigned Cntr=0;
   Cntr+=1;
   __enable_interrupt();
   if (Cntr<2) key_scan_func(); // вызов функции сканирования клавиатуры, только если не было вложенного прерывания
   ...
   Cntr-=1;
}
Go to the top of the page
 
+Quote Post
Visor
сообщение Apr 2 2007, 07:55
Сообщение #17


Местный
***

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



Цитата(Axxel @ Apr 2 2007, 12:28) *
Помехи например, ложные срабатывания от датчиков, ведь такое IMHO может быть

Сигналы конечно в природе возможны всякие, но мы вроде обсуждаем сабж!
Go to the top of the page
 
+Quote Post
Axxel
сообщение Apr 2 2007, 08:00
Сообщение #18


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

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



Цитата(Visor @ Apr 2 2007, 10:55) *
Сигналы конечно в природе возможны всякие, но мы вроде обсуждаем сабж!


Но ведь неплохо бы фильтровать и ложные срабатывания от немеханических датчиков. smile.gif

Сообщение отредактировал Axxel - Apr 2 2007, 08:01


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


Местный
***

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



Цитата(Axxel @ Apr 2 2007, 12:28) *
И еще вопрос: используя прерывания от аппаратного таймера для подавления
дребезга, с какой частотой целесообразнее всего устраивать эти прерывания?
И каков риск что пользовательская функция-обработчик не успеет обработаться
до возникновения следующего прерывания?

А не надо использовать прерывания от таймера, опрашивайте состояние таймера в общем цикле, спешить некуда.
Цитата(Axxel @ Apr 2 2007, 12:28) *
Но ведь неплохо бы фильтровать и ложные срабатывания от немеханических датчиков.

Универсальность - враг оптимальности.

Сообщение отредактировал Visor - Apr 2 2007, 08:49
Go to the top of the page
 
+Quote Post
Axxel
сообщение Apr 2 2007, 10:56
Сообщение #20


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

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



Универсальность - враг оптимальности.
[/quote]


Так каким же все-таки будет оптимальный код(алгоритм)? smile.gif


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


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Axxel @ Apr 2 2007, 10:56) *
...Так каким же все-таки будет оптимальный код(алгоритм)? smile.gif

СВОЙ! biggrin.gif
А это мой, заведомо хуже laugh.gif
Сервис вставлен в прерывание 1 мс.
Автоповтор.
Ускорение автоповтора.
Обработка комбинаций клавиш (генерируется альтернативный код)
Предделитель для плохих кнопок.
Успехов smile.gif

Код
#define     StartDelay 25
#define     NextDelay 3

const char * const key_name[LastKbdEvent+1]=
    {    "",name1,name2, name3, name4, name5, name6, name7 };


__no_init char kbd_status0;
__no_init char kbd_status1;
__no_init char kbd_status2;
__no_init char kbd_status3;
__no_init char kbd_status4;

__no_init char interrupt_counter;
__no_init char found_events;
__no_init char old_pressed_keys;
__no_init char pressed_counter;
__no_init char pressed_keys;
          char prescaler;

char DnPressed(void)
{   if (pressed_keys==kDn) return 1;
    else return 0;
}
char UpPressed(void)
{   if(pressed_keys==kUp) return 1;
    else return 0;
}
char NoPressed(void)
{   if (!pressed_keys) return 1;
    else return 0;
}


void InitKbd(void)
{
  kbd_status3=kbd_status2=kbd_status1=kbd_status0=0;
  found_events=0;
}


void KbdService(void)    // into timer interrupt 1 ms
{   if (prescaler<4)  { prescaler++; return;}
    prescaler=0;
            switch (interrupt_counter)     // to reduce time of function
    {
    case    0:    interrupt_counter=1;        //refresh statuses
            kbd_status3=kbd_status2;
            kbd_status2=kbd_status1;
            kbd_status1=kbd_status0;
            kbd_status0=Kbd;
            interrupt_counter=interrupt_counter;
            break;

    case    1:    interrupt_counter=2;        //check pressed key every tic
            pressed_keys=kbd_status0&kbd_status1&kbd_status2;
            if (pressed_keys&(~kbd_status3))
                if (bSound==SoundAlwaysOn) Beep(5,1);
            found_events|=pressed_keys&(~kbd_status3);        // found edge
            if ((pressed_keys==kUp+kDn)&&  // now this two keys
                ((~kbd_status3)&(kUp+kDn)))//and before it wasn't so
                {found_events|=kUpDn;    // set new bit
                found_events&=~(kUp+kDn);    break; } //reset usual bits
            if ((pressed_keys==kUp+kSt)&&  // now this two keys
                ((~kbd_status3)&(kUp+kSt)))//and before it wasn't so
                {found_events|=kUpSt;    // set new bit
                found_events&=~(kUp+kSt);    break; }//reset usual bits                
            if ((pressed_keys==kDn+kSt)&&  // now this two keys
                ((~kbd_status3)&(kDn+kSt)))//and before it wasn't so
                {found_events|=kDnSt;    // set new bit
                found_events&=~(kDn+kSt); break; }    //reset usual bits                    
        break;            
                
    case    2:    interrupt_counter=3;        //check if key the same as before
            if ((pressed_keys&kUp)||(pressed_keys&kDn))    //key for repeat
            {    if (pressed_keys==old_pressed_keys) // same key?
                {    if (pressed_counter)         // yes, time over?
                    {pressed_counter--;}      //No
                    else     {    pressed_counter=NextDelay;        //Yes
                            found_events=pressed_keys; }        //reset
                    }
                else                                            // other key
                    {pressed_counter=StartDelay;    
                    }
            };
            old_pressed_keys=pressed_keys;
            break;
    case    3:    interrupt_counter++;
                    break;
    default: interrupt_counter=0;
    }
}


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Axxel
сообщение Apr 2 2007, 12:20
Сообщение #22


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

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



Да,действительно не такая уж и тривиальная это задача... подавление дребезга smile.gif


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


Местный
***

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



Цитата(Axxel @ Apr 2 2007, 15:56) *
Так каким же все-таки будет оптимальный код(алгоритм)? smile.gif

Выбор за вами. Я свой описал достаточно понятно, чтоб реализовать. Причём реализовать его можно очень просто, несколькими логическими инструкциями с байтами, для 8 кнопок сразу.
Go to the top of the page
 
+Quote Post
vaivai
сообщение Apr 2 2007, 21:13
Сообщение #24


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 31-05-05
Пользователь №: 5 579



На Kazus.ru было несколько примеров на асемблере (давненько)-спрашывавшый был очень даволен результатом.
Go to the top of the page
 
+Quote Post
birden
сообщение Apr 3 2007, 05:41
Сообщение #25


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 28-10-06
Из: Новосибирск
Пользователь №: 21 743



Я очень часто использую следующий принцип:
Код
unsigned char keyb;         // глобальная переменная, состояние клавиатуры
unsigned char kcnt;          // счетчик времени события "кнопка нажата"
...
//    Опрос клавиатуры, вызывается из подпрограммы
//    обработки прерывания по таймеру (каждые 4 мс)
//
void rd_keyb(void)  
{
    unsigned char st;
    st = ~PINC;                                              // читаем состояние кнопок
    if (st == 0) kcnt=0; else kcnt++;
    if (kcnt == 20) keyb=st;                            // таймаут антидребезга
    if (kcnt == 120) { keyb=st; kcnt -= 60; }   // автоповтор
}
Go to the top of the page
 
+Quote Post
Axxel
сообщение Apr 3 2007, 08:57
Сообщение #26


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

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



Остановился пока на таком методе:

unsigned char acc=0,state=0;

interrupt Timer0()
{
acc=acc<<1;
acc|=Pinx;
if(acc==0){state=0;}
if(acc==255){state=1;}
}

Всем респект! cheers.gif


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


Знающий
****

Группа: Свой
Сообщений: 961
Регистрация: 28-11-05
Пользователь №: 11 489



Ну вы и нагородили, на пустом месте. Достаточно 20-30 раз в секунду опрашивать матрицу кнопок и ВСЁ. Дребезг не влияет ни на что. Можно считать что его нет.


--------------------
В действительности всё не так, как на самом деле.
Go to the top of the page
 
+Quote Post
Axxel
сообщение Apr 3 2007, 10:34
Сообщение #28


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

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



Цитата(slog @ Apr 3 2007, 12:20) *
Достаточно 20-30 раз в секунду опрашивать матрицу кнопок



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

Конечно, в принципе я понимаю что хватит и двух устойчивых состояний для
принятия нажатия, но... мало ли что может произойти.





To =AK=
О таком методе шла речь?
(с битовым сдвигом,выше)


--------------------
Если боишься - не говори. если сказал - не бойся. ©
Go to the top of the page
 
+Quote Post
=AK=
сообщение Apr 3 2007, 10:40
Сообщение #29


pontificator
******

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



Цитата(Axxel @ Apr 3 2007, 17:04) *
To =AK=
О таком методе шла речь?
(с битовым сдвигом,выше)

Ну так вы же его использовали в своем коде. Я то же самое делал на ассемблере.
Go to the top of the page
 
+Quote Post
Axxel
сообщение Apr 3 2007, 10:43
Сообщение #30


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

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



Цитата(=AK= @ Apr 3 2007, 13:40) *
Ну так вы же его использовали в своем коде. Я то же самое делал на ассемблере.



Вы же мне про него и сказали smile.gif


--------------------
Если боишься - не говори. если сказал - не бойся. ©
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 Текстовая версия Сейчас: 14th July 2025 - 09:29
Рейтинг@Mail.ru


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