|
Обработка прерывания кнопки |
|
|
|
Aug 22 2011, 02:25
|
Местный
  
Группа: Участник
Сообщений: 235
Регистрация: 20-11-10
Пользователь №: 61 032

|
Кто запрещает что-то другое делать, пока задержка. Почему обязательно всё это время висеть в прерывании. Кто разрешил делать предположения о принципиальной возможности других подходов к. Цитата Не нашел. Длительность импульсов в "дребезге контактов" например заголовок, простой и логичный.
|
|
|
|
|
Aug 22 2011, 04:20
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Примерно лет шесть делаю так: CODE // в .h-файле: // кол-во времени до события "длинное нажатие" #define TIMER_COUNT 250 // кол-во кнопок #define KEY_COUNT 4 // время автоинкремента #define TIMER_SCROLL 20
// состояние кнопки enum {KN_DOWN =0, KN_UP =1, KN_PRESS=2 }; // тип функции кнопки typedef byte(KeyFunc)(void);
// структура хранящая набор переменных для каждой кнопки typedef struct key_struct__ { byte state; // состояние кнопки byte mask; // маска клавиши byte pins; // буфер значений с клавиши byte count; // счетчик нажатий KeyFunc * exec_down; KeyFunc * exec_up; KeyFunc * exec_pres; }key_struct;
// в .c-файле: //***************************************************************************** // Драйвер кнопок // назначение кнопок // 1- MiNUS 2-PLUS 3- Select 4- Enter //*****************************************************************************
//============================================================================= // состояния кнопок static key_struct key_mass [KEY_COUNT] = { //state mask pins count exec_down exec_up exec_pres {KN_UP, PIN_KEY_MINUS, 0xFF,0x00, kn_empty, kn_minus_up ,kn_minus_up } ,{KN_UP, PIN_KEY_PLUS, 0xFF,0x00, kn_empty, kn_plus_up ,kn_plus_up } ,{KN_UP, PIN_KEY_SELECT, 0xFF,0x00, kn_empty, kn_select_up ,kn_empty } ,{KN_UP, PIN_KEY_ENTER, 0xFF,0x00, kn_empty, kn_empty ,kn_enter_press } }; //=============================================================================
ISR(TIMER1_COMPA_vect) { #define Sta key->state #define Pin key->pins #define Cnt key->count #define Msk key->mask #define Down key->exec_down #define Up key->exec_up #define Pres key->exec_pres
key_struct * key = key_mass; for(byte i=0; i< KEY_COUNT ; i++) { Pin *=2; // * or << if(KEY_PIN & Msk) Pin |= 0x01;
if(Sta == KN_UP) { if(!Pin) // начало счета - нажатие { Down(); Sta = KN_DOWN; Cnt = 0x00; } } else // down or press { if(Pin==0xFF) // отпустили { if(Sta == KN_DOWN) Up(); Sta = KN_UP; } else// удерживаем { if(Cnt <= TIMER_COUNT) ++Cnt; if(Cnt == TIMER_COUNT) // длительное удержание - попадаем один раз!! { if(Pres()) Cnt = TIMER_COUNT - TIMER_SCROLL; else Sta = KN_PRESS; } } } key++; } }
Таймер в CTC-режиме на порядка 5....15 мсек
Сообщение отредактировал alexeyv - Aug 22 2011, 04:22
|
|
|
|
|
Aug 22 2011, 10:06
|
Участник

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

|
Цитата(Nikitoc @ Aug 22 2011, 13:19)  Спасибо всем за ответы. Прокомментируйте, пожалуйста, следующий вариант обработки нажатия кнопки: по нажатию на кнопку устанавливаем в обработчике флаг соотв. кнопки и запускаем таймер (и выходим из прерывания), по прерыванию от которого проверяем состояние кнопки (чей флаг предварительно был установлен) и устанавливаем флаг нажатия кнопок, который (в паре с флагом соотв. кнопки) обрабатываем в основной программе.
P.S. Учитывая пост Sserge добавляем запрещение соотв. прерывания в первом обработчике и разрешение во втором. Возможно, заработает. Возможно, будет даже немного лучше чем вообще без антидребезга. Возможно... По хорошему алгоритм в следующем: Опрос кнопки в прерывании от таймера, раз в 0.5-5мс Счетчик - от 0 до N, где N задает время антидребезга (порядка 10-200мс) Буфер - состояние кнопки после антидребезга. 1. Если кнопка нажата и счетчик меньше максимума - прибавляем счетчик 2. Если кнопка отжата и счетчик больше нуля - убавляем счетчик 3. Если счетчик в максимуме, устанавливаем буфер в '1' 4. Если счетчик в нуле, устанавливаем буфер в '0' 5. По переходу буфера '0' -> '1' или '1' -> '0' делаем вывод о нажатии/отжатии кнопки.
|
|
|
|
|
Aug 23 2011, 04:57
|
Участник

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

|
Цитата(ILYAUL @ Aug 22 2011, 16:36)  Запускаешь АЦП и никаких тебе дребезгов и задержек очена подходит к случаю описанному alexeyv Что-то я не совсем понял каким боком тут АЦП оказалось и как оно поможет с кнопкой.
Сообщение отредактировал whiteTigr - Aug 23 2011, 04:59
|
|
|
|
|
Aug 23 2011, 07:47
|
Участник

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

|
Цитата(ILYAUL @ Aug 23 2011, 11:43)  А я не понял , что не понятного? Зачем целый АЦП выделять под кнопку?
|
|
|
|
|
Aug 23 2011, 07:59
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Цитата(whiteTigr @ Aug 23 2011, 11:47)  Зачем целый АЦП выделять под кнопку? А почему под кнопку? Я написал для кого проекта это удобно использовать. Цитата Запускаешь АЦП и никаких тебе дребезгов и задержек очена подходит к случаю описанному alexeyv И к тому же один канал на 8 кнопок. Если уж очень постараться то и 12 кнопок влезут. Учитывая , что каналы (8 шт.) можно переключать во время работы и никто не запрещал менять настройки АЦП , во время работы, то проще выделить просто один канал под кнопки , а с отальными I/O делать , что душе угодно. В том числе и просто как входы -выходы
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Aug 23 2011, 12:54
|

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

|
вообще не понимаю, зачем для столь низкоприоритетного процесса, как работа с кнопками, задействовать прерывания или таймеры. в большинстве обычных ситуаций обработка кнопок премило делается в основном цикле путем поллинга с традиционными программными задержками - а вот фоновые процессы пусть крутятся в прерываниях.
прерывание требуется для обеспечения немедленной реакции на внешнее событие, причем "немедленно" - по меркам микроконтроллера, а не человека. назовите хотя бы какую-то ситуацию, где действительно необходимо реагировать на кнопку за 5-10 микросекунд. кстати - даже если придумаете, это будет бесполезно, т.к. подавление дребезга все равно заставит затянуть процесс до 10-15 миллисекунд, т.е. примерно в 1000 раз.
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|