помогите опросить кнопочку

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Опытный кот
Сообщения: 768
Зарегистрирован: Сб ноя 08, 2008 18:32:36

Сообщение vovik15 »

доброго времени суток,у меня небольшая проблемка,вот недввно начал разбираться с контроллерами,и возниклв проблема опроса кнопки,помогите пожалуйста!
PS
пытаюсь учиться програмировать на языке си
благодарен за любую оказанную помощ :))
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

#define knopka PINA.0
.
.
if(knopka)
{
//делаем то, что надо при нажатой кнопке
}
else
{
//делаем то, что надо при ненажатой кнопке
}
Docendo discimus
Контактная информация:
Реклама
Потрогал лапой паяльник
Сообщения: 397
Зарегистрирован: Ср сен 19, 2007 09:21:04

Сообщение chief »

vovik15 писал(а):пытаюсь учиться програмировать на языке си
На каком компиляторе работаешь?
Вымогатель припоя
Сообщения: 584
Зарегистрирован: Чт янв 07, 2010 16:58:11

Сообщение b612 »

vovik15 писал(а):благодарен за любую оказанную помощ :))
проверяешь состояние кнопки 20-50 раз в секунду
если состояние кнопки изменилось (не важно нажали или отпустили) делаешь то, что нужно при нажатии(отпускании). и перестаёшь опрашивать примерно на 0.1-0.2 секунды
через 0.1-0.2 секунды возобновляешь опрос.

приостановка опроса нужна для подавления дребезга контактов и дрожания пальцев

обязательно нужно использовать флаг прошлого состояния кнопки чтобы сравнивать вновь считаное с тем, что было до этого
и обязательно одинаково реагировать (делать паузу 0.1-0,2сек) и при нажатии и при отпускании
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Опытный кот
Сообщения: 768
Зарегистрирован: Сб ноя 08, 2008 18:32:36

Сообщение vovik15 »

спосибо,работаю в компиляторе
codevision avr
Контактная информация:
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 316
Зарегистрирован: Пт апр 17, 2009 22:45:42
Откуда: Minsk

Сообщение maglev »

b612 писал(а):
vovik15 писал(а):благодарен за любую оказанную помощ :))
проверяешь состояние кнопки 20-50 раз в секунду
если состояние кнопки изменилось (не важно нажали или отпустили) делаешь то, что нужно при нажатии(отпускании). и перестаёшь опрашивать примерно на 0.1-0.2 секунды
через 0.1-0.2 секунды возобновляешь опрос.
Правильно делать по-другому. В цикле непрерывно читаешь кнопку, если состояние изменилось - счетчик в ноль. Если состояние не меняется N циклов, то считаем его стабильным и обрабатываем. N зависит от частоты опроса, длительность те самые 0.1-0.2с. Величина N - обычно десятки.
Контактная информация:
Реклама
Мявтор!
Аватара пользователя
Сообщения: 384
Зарегистрирован: Ср май 17, 2006 18:39:01
Откуда: Москва

Сообщение Pavel V. »

Вот красивый способ подавления дребезга контактов, который я уже давно использую:

Код: Выделить всё

/* Key Accumulator */
static uint16_t KeyAcc = 0;

/* Key State */
static uint16_t Key = 0;

/*
 * Read Key
 */
void ReadKey() {
	KeyAcc = KeyAcc << 1;
	KeyAcc |= !(KEYPORT & KEYPIN);
	if(KeyAcc == 0xFFFF) Key = 1;
	if(KeyAcc == 0) Key = 0;
}
Для кучи кнопок, соответственно, используем массивы: KeyAcc[X], Key[X].
Контактная информация:
Потрогал лапой паяльник
Сообщения: 392
Зарегистрирован: Сб дек 12, 2009 02:15:45

Сообщение neon-f »

Подскажите, вот так нормально опрашивать кнопки и подавлять дребезг. Три кнопки подключены к портам PD3, PD4, PD5.

unsigned char button ;

******
void Code_key (void)
{
button=0x00;
if (PIND>>3<<5!=0b11100000) {button=PIND>>3<<5; delay_ms(100);}
while (PIND>>3<<5==button) {}
delay_ms(50);
}

на выходе переменная button имеет код нажатой кнопки, или равна 0 если кнопки не нажаты.
и ещё, как различать кратковременное нажатие кнопки, и долгое удержание.
Вымогатель припоя
Аватара пользователя
Сообщения: 690
Зарегистрирован: Вс мар 04, 2007 01:17:12

Сообщение Alexeus »

кратковременное и долгое удержание кнопок нужно с помощью таймера распознавать. настраиваешь таймер на какой то период и в прерывании таймера увеличиваешь переменную. в основной программе сравниваешь сколько накопилось в переменной. чем дольше держишь, тем большее число копится в переменной. после обработки нажатия клавиши переменную обнуляешь.
Мявтор!
Аватара пользователя
Сообщения: 384
Зарегистрирован: Ср май 17, 2006 18:39:01
Откуда: Москва

Сообщение Pavel V. »

neon-f писал(а):Подскажите, вот так нормально опрашивать кнопки и подавлять дребезг. Три кнопки подключены к портам PD3, PD4, PD5.
Нет, ненормально. Вообще желательно сразу забыть про delay_ms(100);
Максимум где могут применяться задержки в циклах - это инициализация периферийных устройств.

В основном же цикле никаких задержек быть не должно.

Чем не устраивает мой пример?
Контактная информация:
Потрогал лапой паяльник
Сообщения: 392
Зарегистрирован: Сб дек 12, 2009 02:15:45

Сообщение neon-f »

Pavel V. писал(а):Чем не устраивает мой пример?
честно? - много незнакомых букв. я еще совсем зеленый в программировании. У меня опрос кнопок сделан в виде функции, т.е. когда мне нужно прочесть состояние кнопок, я обращаюсь к функции опроса, один раз опрашиваю и возврвщаюсь в основную программу. К тому же если не одна из кнопок не нажата, то задержка вообще не используется
_noise писал(а):Основной цикл - сам по себе задержка,
Я тоже так подумал, поэтому на отпускание кнопки поставил delay_ms(50), а на нажатие delay_ms(100);
_noise писал(а):приколоться: основной цикл = делай_мс() и опрос кнопок только, а все полезные действия по прерываниям?
а по моему реальный вариант......
Мявтор!
Аватара пользователя
Сообщения: 384
Зарегистрирован: Ср май 17, 2006 18:39:01
Откуда: Москва

Сообщение Pavel V. »

Код: Выделить всё

/* Key Accumulator */
static uint16_t KeyAcc = 0; // Глобальная переменная для хранения последовательности состояний кнопки (аккумулятор)

/* Key State */
static uint16_t Key = 0; // Глобальная переменная состояния кнопки (после подавления дребезга)

/*
* Функция опроса состояния кнопки
*/
void ReadKey() {
   KeyAcc = KeyAcc << 1; // Сдвигаем аккумулятор влево на 1 бит
   KeyAcc |= !(KEYPORT & KEYPIN); // читаем состояние ножки KEYPIN на порту KEYPORT и добавляем новое значение к аккумулятору
   if(KeyAcc == 0xFFFF) Key = 1; // если 16 раз подряд на ножке лог. 0, то кнопка нажата
   if(KeyAcc == 0) Key = 0; // если 16 раз подряд на ножке лог. 1, то кнопка отпущена
}
Функцию ReadKey() необходимо вызывать либо из главного цикла, либо по прерыванию таймера. В основном цикле обрабатывать флаг Key.

Код: Выделить всё

if(Key) { // Кнопка нажата
    делаем что-то;
}
Контактная информация:
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»