Перейти к содержанию
    

динамический опрос кнопок

http://www.embedded.com/columns/breakpoint...equestid=203518

 

Вот! Прелестнейшая антидребезговая утилита от Jack Ganssle

 

По таймеру это ей жирно, я решил. Дергаю из мэйнлупа -- справляется на отлично.

// Service routine called by a timer interrupt

bool_t DebounceSwitch2()

{

static uint16_t State = 0; // Current debounce status

State=(State<<1) | !RawKeyPressed() | 0xe000;

if(State==0xf000)return TRUE;

return FALSE;

}

 

Подробное описание, в статье на английском. Если есть необходимость, переведу.

 

Необходимость есть, переведи! :help:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Необходимость есть, переведи! :help:

 

Эх... :)

Там статья то объемненькая :)

 

У меня щас есть время только функцию описать.

 

State = (State<<1) | !RawKeyPressed() | 0xe000;

оно же в двоичном виде: (State<<1) | !RawKeyPressed() | 1110 0000 0000 0000;

 

State изначально = 16 ноликов.

На этом шаге мы сдвигаем State влево, а на место нулевого бита ставим 0 если кнопка нажата, иначе 1.

При этом старшие три бита всегда единички.

Дергаем нашу функцию каждые 10мс.

 

Тогда при нажатии кнопки (если она была отпущена) State с каждым шагом будет меняться так:

1111 1111 1111 1111 -- кнопка отпущена

1111 1111 1111 1110 -- нажали кнопку

1111 1111 1111 1100 -- держим

1111 1111 1111 1001 -- пошел дребезг

1111 1111 1111 0010

...

1111 1110 1010 1101 -- вот сколько дребезга дофига было :)

1111 1101 0101 1010 -- вот тут контакты успокоились и пошли к нам нолики ровным строем

1111 1010 1011 0100

...

1111 1101 0000 0000 -- вот сколько уже ноликов пришло и продолжают идти...

 

Это первая часть алгоритма. А вторая -- это условие

if(State==0xf000)return TRUE;

То есть сравниваем State с 1111 0000 0000 0000.

А состояние 1111 0000 0000 0000 означает, что кнопка нажата уже 12 ноликов подряд, и перед этими 12-ю шагами она как минимум один шаг была не нажата (единичка в 13-м разряде).

 

Ну вот собственно когда условие выше описанное выполняется регистрируем нажатие кнопки: возвращаем true.

 

Это все можно заточить под себя меняя 0xe000 и 0xf000.

 

И вообще алгоритм простой и быстрый, функцию можно по всякому модифицировать. Вот например я так сделал:

//------------------------------------------------------

//--- Debounce switch action

//--- function operate on external debounce-state variable

// работает с внешней переменной состояния чтоб сразу несколько кнопок опрашивать

int DebouncePress(int RawButtonPressed(char), char button, unsigned int *state){

*state = (*state<<1) | !(RawButtonPressed(button)) | 0xe000;

if(*state == 0xf000) return 1; // Pressed Нажата

if(*state == 0xefff) return 0; // Released Отпущена

return -1; // Unstable Идет дребезг

}

//-------------------------------------------------------

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ух, ты!

В данном алгоритме кнопка одним концом сидит на выводе МК, а вторым на "земле"?

 

 

 

Смотрел, но ваш мне показался излишне громоздким. А что значит "не пошёл"? Там же 5 операторов. Идея то понятна? Посмотрите где я хомутнул. Если вечером время будет, то сам гляну.

 

Индикация то работает надеюсь?

 

Мой код громоздкий из-за маленького опыта, но он работает.

Индикация работает!

Вы объявили в структуре Int_Key, а как её используете7

Изменено пользователем Anjey_N

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ух, ты!

В данном алгоритме кнопка одним концом сидит на выводе МК, а вторым на "земле"?

 

Если вопрос ко мне, то кнопка чисто гипотетическая.

А гипотетическая функция RawKeyPressed() возвращает 1, если контакт замкнут, иначе 0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы объявили в структуре Int_Key, а как её используете7

Просто попытался портировать из своей же библиотеки

http://electronix.ru/forum/index.php?showt...0934&st=120

пост 125

 

При таком числе кнопок возможно применение нединамического опроса. Правда гашение дребезга всё равно требуется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эх... :)

Там статья то объемненькая :)

 

У меня щас есть время только функцию описать.

 

State = (State<<1) | !RawKeyPressed() | 0xe000;

оно же в двоичном виде: (State<<1) | !RawKeyPressed() | 1110 0000 0000 0000;

 

State изначально = 16 ноликов.

На этом шаге мы сдвигаем State влево, а на место нулевого бита ставим 0 если кнопка нажата, иначе 1.

При этом старшие три бита всегда единички.

Дергаем нашу функцию каждые 10мс.

 

Тогда при нажатии кнопки (если она была отпущена) State с каждым шагом будет меняться так:

1111 1111 1111 1111 -- кнопка отпущена

1111 1111 1111 1110 -- нажали кнопку

1111 1111 1111 1100 -- держим

1111 1111 1111 1001 -- пошел дребезг

1111 1111 1111 0010

...

1111 1110 1010 1101 -- вот сколько дребезга дофига было :)

1111 1101 0101 1010 -- вот тут контакты успокоились и пошли к нам нолики ровным строем

1111 1010 1011 0100

...

1111 1101 0000 0000 -- вот сколько уже ноликов пришло и продолжают идти...

 

Это первая часть алгоритма. А вторая -- это условие

if(State==0xf000)return TRUE;

То есть сравниваем State с 1111 0000 0000 0000.

А состояние 1111 0000 0000 0000 означает, что кнопка нажата уже 12 ноликов подряд, и перед этими 12-ю шагами она как минимум один шаг была не нажата (единичка в 13-м разряде).

 

Ну вот собственно когда условие выше описанное выполняется регистрируем нажатие кнопки: возвращаем true.

 

Это все можно заточить под себя меняя 0xe000 и 0xf000.

 

И вообще алгоритм простой и быстрый, функцию можно по всякому модифицировать. Вот например я так сделал:

//------------------------------------------------------

//--- Debounce switch action

//--- function operate on external debounce-state variable

// работает с внешней переменной состояния чтоб сразу несколько кнопок опрашивать

int DebouncePress(int RawButtonPressed(char), char button, unsigned int *state){

*state = (*state<<1) | !(RawButtonPressed(button)) | 0xe000;

if(*state == 0xf000) return 1; // Pressed Нажата

if(*state == 0xefff) return 0; // Released Отпущена

return -1; // Unstable Идет дребезг

}

//-------------------------------------------------------

 

А как Вы используете переменную char button ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как Вы используете переменную char button ?

 

Это параметр функции RawButtonPressed(char). Код кнопки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это параметр функции RawButtonPressed(char). Код кнопки.

 

Меня вводит в заблуждение фраза int DebouncePress(int RawButtonPressed(char), char button, unsigned int *state) Здесь нет ошибки7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...