так же, как и у пчёлокBOB51 писал(а):Как под Си...
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
так же, как и у пчёлокBOB51 писал(а):Как под Си...
Здравствуйте, Роман! Я так пробовал, убираешь флаги светодиоды начинают переключаться и не очень четко (см. про переключалку выше) с каждым новом заходом в опрос кнопок. Ведь у меня алгоритм такой, что я при первом нажатии что-то делаю, а потом выставляю флаг, что дело сделано и если что-то на линии - это дребезг, а интервала от первого "круга" до второго 50мс как раз хватает понять, дребезг или нет. В общем по вашему совету в дефолте свитча сейчас добавил условие: если переменная с кнопками равна нулю, то сбрасываем все флаги, иначе выставляем все флаги принудительно. Выглядит так, работает четко. Но я чувствую, что алгоритм кривой...ARV писал(а):по-моему, надо просто убрать все флаги и тупо выполнять в switch-е нужное действие по коду нажатой кнопки. в этом случае надо учитывать и комбинации нажатых кнопок. при необходимости после switch-а дожидаться отпускания кнопок.
Код: Выделить всё
void buttons (void)
{
btns=~PIND; //читаем PIND в переменную и инвертируем прочитанное
btns=btns&((1<<BTN1)|(1<<BTN2)|(1<<BTN3)); //отсекаем лишние разряды, оставляем только кнопки
switch(btns)
{
case (1<<BTN1): //если нажата кнопка 1
if(~flags&(1<<BTN1)) //если флаг первой кнопки не установлен, то
{
flags|=(1<<BTN1); //устанавливаем флаг
toggle(RED); //что-то делаем
}
break; //и на выход
case (1<<BTN2): //если нажата кнопка 2
if(~flags&(1<<BTN2)) //если флаг второй кнопки не установлен, то
{
flags|=(1<<BTN2); //устанавливаем флаг
toggle(YELLOW); //что-то делаем
}
break; //и на выход
case (1<<BTN3): //если нажата кнопка 3
if (~flags&(1<<BTN3)) //если флаг третьей кнопки не установлен, то
{
flags|=(1<<BTN3); //устанавливаем флаг
toggle(GREEN); //что-то делаем
}
break; //и на выход
default: //если не нажата ни одна кнопка или любая другая комбинация
if (btns==0)
{
flags=0; //сбрасываем все флаги
}
else
{
flags=(1<<BTN1)|(1<<BTN2)|(1<<BTN3); //выставляем все флаги
}
break; //и на выход
}
keys=0; //сбрасываем флаг разрешения опроса кнопок
}Не уверен в этом. По крайней мере надо будет отслеживать в данном случае отличается ли код кнопки через 10 мс от предыдущего. Дребезги всякие бывают.Alexeyslav писал(а):Сам опрос каждые 10мс и есть защита от дребезга
Код: Выделить всё
static void key_repeater(char kk){
MAKE_TIMER(TR, 0, 0);
static char old_kk;
if(kk == 0){
timer_stop(&TR);
} else {
if(old_kk != kk){
timer_start(&TR, 1000, 0);
put_message(QUEUE, MSG_KEY, kk, 0);
} else {
if(timeout(&TR)){
timer_start(&TR, 300, 0);
put_message(QUEUE, MSG_KEY, kk, 0);
}
}
}
old_kk = kk;
}Вообще-то этот алгоритм я сочинил для обработки номеронабирателей дисковых телефонов, где-то в начале 90-х. Реализовано это было на ДВК (наша микро-ЭВМ по мотивам PDP-11). Там это была необходимость, а для энкодеров на АВР я его применил, как говорит молодежь, по приколу: увидел осциллограммы того убитого энкодера и вспомнил, что нечто подобное я видел на тех телефонах. Ну, и принял вызов.ARV писал(а):Возможно, для каких-то особо ужасных кнопок это и имеет смысл,
Да не особенно - программа, в общем-то, не сильно большая, расход оперативки - по байту на кнопку. Вот процессорное время оно таки да, кушает с аппетитом. Но, в большинстве случаев, это некритично, если не заниматься на этом же процессоре большими объемами сложных математических вычислений.ARV писал(а):но выглядит как-то уж слишком ресурсоемко.
Вообще-то эти китайские контактные энкодеры при более-менее интенсивной эксплуатации выходят из строя довольно быстро. И, если использовать этот алгоритм, менять их придется намного реже.ARV писал(а):И кто принуждает применять убитые энкодеры?!