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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
fantasy
сообщение Jul 10 2006, 15:19
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 69
Регистрация: 17-09-05
Из: Kirov
Пользователь №: 8 659



Внесу свою реплику в дискуссию...

Код
#define _fDreb 5 //защита от дребезга (0.05 сек.)
#define _fRepite 39 //время первого автоповтора (0.4 сек.)
#define _nRepite 10 //время второго и последующего автоповтора (0.1 сек.)

//уровни напряжений для кнопок (_minKey1 > _minKey2 > _minKey3 > _minKey4)
#define _minKey1 ... //минимальный уровень напряжения для кнопки 1
#define _minKey2 ... //минимальный уровень напряжения для кнопки 2
#define _minKey3 ... //минимальный уровень напряжения для кнопки 3
#define _minKey4 ... //минимальный уровень напряжения для кнопки 4
    
unsigned int ADCresult;
unsigned char newHKey, oldHKey, drebCount;
unsigned char _key;

    ADCresult = ...;   //данные с АЦП
    
    //... вызывается с частотой ~100 Гц
    newHKey = 0;
    if(ADCresult>=_minKey1)
    {
newHKey = 0x01; //key1
    }
    else if(ADCresult>=_minKey2)
    {
newHKey = 0x02; //key2
    }
    else if(ADCresult>=_minKey3)
    {
newHKey = 0x04; //key3
    }
    else
    {
newHKey = 0x08; //key4
    };
    if((oldHKey!=newHKey)||(newHKey==0x0))
    {
_key = false;
drebCount = _fDreb;
    }
    else
    {
if((--drebCount)==0)
{
     //расшифровываем нажатие на кнопки
     if(newHKey&0x01)key1=true;
     if(newHKey&0x02)key2=true;
     if(newHKey&0x04)key3=true;
     if(newHKey&0x08)key4=true;
     drebCount = _fRepite;  //предполагаем повторное нажатие
     if(_key==false)drebCount = _nRepite; //устанавливаем ожидание 1-го нажатия
     _key = true;
};
    };
    oldHKey = newHKey;


--------------------
В голове слышался грохот: рушились грандиозные планы...
Go to the top of the page
 
+Quote Post
Labinskiy Nikola...
сообщение Jul 10 2006, 16:36
Сообщение #17


Участник
*

Группа: Новичок
Сообщений: 27
Регистрация: 5-07-06
Из: Украина, Донецк
Пользователь №: 18 606



Всем спасибо за ответы - пойду экспериментировтаь wink.gif


--------------------
If you can't make it good - don't make it look good ;)
Go to the top of the page
 
+Quote Post
dio
сообщение Jul 19 2006, 17:58
Сообщение #18


Участник
*

Группа: Новичок
Сообщений: 40
Регистрация: 4-06-06
Пользователь №: 17 766



Понимаю что вопрос тупой, но всё таки ...
Упростил пример до невозможного, а он опять не работает blink.gif


Цитата
int main( void )
{
byte t1,t2;
DDRB=0x0F; // b0-b3 : outputs b4-b7 : inputs
DDRD=0xFF; // d0-d7 output

PORTB=0x01;;
for(;;)
{
__delay_cycles(160000); // Пихните куда надо
t1=PORTB;
t2=0x10;
t1=t1 & t2;

if (t1==t2) PORTD=0xFF;
else PORTD=0x00;
}
}


Хочу чтоб загорелся диод на PORTD после нажатия клав. "1" на 4x4 клавиатуре.
Помогите плииииис !!!
sad.gif

п.с. Не ругайте снльно.
rolleyes.gif
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 10 2010, 17:48
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



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


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Feb 11 2010, 09:23
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 922
Регистрация: 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
Lexdaw
сообщение Feb 11 2010, 13:24
Сообщение #21


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

Группа: Участник
Сообщений: 87
Регистрация: 5-02-08
Пользователь №: 34 772



А я по опросу входа (кнопки) сдвигаю регистр влево/вправо, до заполнения указателя нулями/единицами.Этакий стрелочный прибор получается.
Go to the top of the page
 
+Quote Post
Corvus
сообщение Feb 11 2010, 13:47
Сообщение #22


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 24-04-08
Из: Зеленоград
Пользователь №: 37 056



А простой инкремент/декремент чем не угодил? rolleyes.gif
Go to the top of the page
 
+Quote Post
Marian
сообщение Feb 11 2010, 13:49
Сообщение #23


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

Группа: Участник
Сообщений: 148
Регистрация: 23-02-07
Пользователь №: 25 618



Цитата(smk @ Feb 10 2010, 19:48) *
Как выяснилось в моем случае, полезно обеспечивать не только устранение дребезга, но и время нечувствительности к повторному нажатию. Иначе сканировать и отрабатывать будет успевать быстрее чем поймет оператор что он нанажимал.

Или следить, когда кнопку отпустили.
Для схемы с одной кнопкой делал типа :

Код
#define Knopka PIND.3
// Knopka podl na PD 3 , vtoraja noga na zemlu
// v portu vklucit podtiagivajushchij rezistor, ili postavit vneshnij k +5 V
// jesli knopka nazata, to "Knopka " budet ravna 0

unsigned char ButtonDownTime(void)
// return TimeLong if long, and TimeShort if short time
{
   unsigned char i;
   while ( Knopka == 1);  
   for(i=0;i<7;i++)
   {
      delay_ms(50);      // zadierzka od drebiezga kontaktow
      if (Knopka == 1)   // odpuscili knopku
      {
         return TimeShort;//short
         goto MEnd; // vyhod s cikla
      }
   }    
   return TimeLong;//long
MEnd:  
}

void WaitButtonUp(void)
{                        
   while (Knopka == 0);
   delay_ms(50);
}

// vyzyvat primerno tak
if (Knopka == 0) //Pervoje nazatije, vhod v menu
{
    WaitButtonUp(); // zhdem otpuskanija knopki
    if (ButtonDownTime() == TimeShort)
   {
      //naprimer uvelichit peremennuju HD++;
      WaitButtonUp();
    }
   else //if (ButtonDownTime() == TimeShort)
  {          
     // perehod na sledushchij punkt menu
  }
}
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 11 2010, 15:53
Сообщение #24


Гуру
******

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



Цитата(smk @ Feb 10 2010, 22:48) *
Иначе сканировать и отрабатывать будет успевать быстрее чем поймет оператор что он нанажимал.
Что-то не то в таком утверждении. cranky.gif То ли вы дребезг не полностью устраняете, то ли оператора каким-то дураком представить пытаетесь.
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 11 2010, 17:08
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Нет, просто события внутри микроконтроллера опережают реакцию оператора. Ну например, сделайте счетчик с отображением на индикаторе. Оператор хочет увеличить на 1, а пока нажал-отпустил насчитало 10. Компьютерная клава тому яркий пример - скорость выдачи при удержании кнопки ограничена.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Feb 11 2010, 17:17
Сообщение #26


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(smk @ Feb 11 2010, 21:08) *
Нет, просто события внутри микроконтроллера опережают реакцию оператора. Ну например, сделайте счетчик с отображением на индикаторе. Оператор хочет увеличить на 1, а пока нажал-отпустил насчитало 10. Компьютерная клава тому яркий пример - скорость выдачи при удержании кнопки ограничена.

Естественно, необходимо кроме антидребезга вводить ещё паузу и период автоповтора.
Никто не сомневается, что контроллер может считать быстрее человека biggrin.gif
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 11 2010, 17:25
Сообщение #27


Гуру
******

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



Цитата(smk @ Feb 11 2010, 22:08) *
Нет, просто события внутри микроконтроллера опережают реакцию оператора. Ну например, сделайте счетчик с отображением на индикаторе. Оператор хочет увеличить на 1, а пока нажал-отпустил насчитало 10.
Извините, но это дурдом какой-то. wacko.gif Переменная открытая для редактирования не может изменяться до окончания процесса редактирования. У вас явно что-то не то в консерваториях. cranky.gif
Цитата(smk @ Feb 11 2010, 22:08) *
Компьютерная клава тому яркий пример - скорость выдачи при удержании кнопки ограничена.
Ну и какой вы делаете из этого вывод? Все верно в компьютерных клавах сделано, я лично на точно таких же принципах реализую клавиатуру в приборах. Задержка перед началом повтора и паузы между выдачей кодов повторного нажатия. Параметры задержки и паузы настраиваемые. Причем повтор обычно разрешен не для всех кнопок, а только для клавиш "навигации": вправо-влево-вверх-вниз.
Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Feb 11 2010, 19:27
Сообщение #28


Знающий
****

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



Товарищ смешивает две задачи, устранения дребезга и частота автоповтора. Для первой задачи я применяю код, приведённый выше, для второй таймер. При поступлении события от таймера, в основном цикле применяю значение, которое даёт антидребезговый код.
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 11 2010, 21:31
Сообщение #29


Гуру
******

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



Цитата(Oleg_IT @ Feb 12 2010, 00:27) *
Товарищ смешивает две задачи, устранения дребезга и частота автоповтора.
Может это я не совсем понимаю или неправильно понимаю суть написанного smk? smile.gif
Поясняю для самого общего случая.
Процедура устранения дребезга требуется для ликвидации недостатков аппаратуры. Единичное нажатие клавиши пользователем аппаратура должна четко определить именно как единичное, а не как 2 или 52 или 152 нажатия. Все! Никаких ограничений на частоту нажатий эта процедура оказывать не должна. Ограничения возникают чисто физиологические. Человек физически не способен нажимать клавиши чаще чем, скажем, 100 раз в секунду. И осмысленно с такой скоростью нажимать их, тем более не способен.
- Я способна набирать 1200 символов в минуту!
- Ну и как, получается?
- Вы знаете, если честно, такая фигня выходит.
(из анекдота) smile.gif
В реальности процедура устранения дребезга конечно тоже налагает ограничение на темп нажатий сверху. Типовое время дребезга механических контактов кнопок составляет порядка 10мс. Если устранение дебезга построено на периодическом опросе, то сверху ограничение в те же 100 нажатий в секунду выходит. Но если клавиатура способна 100 нажатий/с обеспечить, то она обязана их обеспечивать без каких-либо других ограничений.
Теперь про автоповтор. Автоповтор это "фича" клавиатуры, дополнительное удобство т.с. Автоповтор имитирует многократное нажатие пользователем одной и той же клавиши. Но раз он только имитирует действия пользователя (а пользователи-то все разные), то следовательно автоповтор должен иметь настраиваемые или даже (само)адаптируемые параметры. Пример самоадаптируемого изменения скорости автоповтора можно привести на базе паяльной станции с цифровой регулировкой температуры. Одиночные нажатия изменяют регулировку температуры на 1°C. Автоповтор вначале имитирует такую же ступень изменения (на 1°C). Но если удерживать клавишу дольше и изменение произойдет более чем на 10°C, то шаг приращения температуры автоматически увеличивается до 10°C. Впрочем это я немного отвлекся. Суть-то в том, что автоповтор это имитация действий пользователя. Для его (пользователя) удобства. А ведь пользователи все разные, кто-то реально по 20 раз/с способен нажимать кнопки, а кто-то "с ограниченными возможностями" нажимает кнопки локтем (калека) или физически не способен на быстрые движения (старик или с отклонениями в психическом развитии). Соответственно для каждого из них нужны разные задержки для включения функции автоповтора и разный темп имитации нажатий. Если у функции автоповтора есть возможности подстройки этих параметров, то я не представляю ситуации, когда
Цитата("smk")
Оператор хочет увеличить на 1, а пока нажал-отпустил насчитало 10.
laughing.gif Вот где мое недоумение/непонимание возникло.
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 11 2010, 23:02
Сообщение #30


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Stas633 @ Jul 10 2006, 09:45) *
Интересно, каким же алгоритмом пользуются производители автомагнитол?

Не знаю как производители магнитол, а я пользуюсь алгоритмом откладывания события:
Код
const PROGMEM U8 transTab[] =
{
    200, 167, 125, 99, 83, 71, 61, 55,
    49, 44, 40, 37, 35, 32, 30, 28
};

// это задачка, которая запускается с периодом 5ms
// сканирует АЦП канал, и преобразует показания АЦП в индекс от 0x0 до 0xF,
// индекс представляет собой код, где каждый бит соответствует одной нажатой кнопке.
void kbr_ScanTask(void)
{
    U8 val = kbr_AdcChanRead( kbrContext.AdcChan );
    U8 i;
    U8 NewStatus = 0;

    for(i = 0; i < sizeof(transTab); i++)
    {
        if (val > pgm_read_byte_near( transTab +  i ))
        {
            NewStatus = i;
            break;
        }
    }

    if (NewStatus != kbrContext.status)
    {
        kbrContext.status = NewStatus;
        if (NULL != kbrContext.StatusChange_CB)
        { // register keyboard status change handler to be executed after 50 ms (to filter out all false events)
            Kernel_SetTask( kbrContext.StatusChange_CB, 50, TASK_RUN_ONCE );
        }
    }
}


И при изменении статуса клавиатуры (в данном случае 4 кнопки на 1 канал АЦП), сканирующая задачка ставит в очередь на исполнение через __50ms__ "Keyboard Status Change event". За эти 50ms задача сканирует канал АЦП еще 10 раз (т.к. она выполяется раз в 5ms) и если статус будет изменяться (дребезг), то запуск event'a будет откладываться. Когда состояние АЦП установится - т.е. на протяжении 10 следующих подряд сканирований состояние не изменится, event таки отработает.


Это есть, одна из возможных, реализация "Интервального" алгоритма, упомянутого resident'ом
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 Текстовая версия Сейчас: 24th June 2025 - 17:23
Рейтинг@Mail.ru


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