Подсчет количества нажатий кнопок
- Сообщения: 18
- Зарегистрирован: Сб дек 22, 2012 09:47:33
Доброго время суток. Помогите пожалуйста начинающему. Задача такая. Есть две кнопки. Нажимается кнопка 1, после отпускания - кнопка 2. Переменная увеличивается на едуницу. При нажатии сначала кнопки 2, а затем кнопку 1, переменная уменьшается на еденицу. Когда переменная равна 0 выходной порт меняет свое значение. Язык Си, CodeVision. Помогите с алгоритмом плиз.
- Реклама
Вы же его только что сами описали.Помогите с алгоритмом плиз.
Чем конкретно помочь, что не получается ?
- Сообщения: 18
- Зарегистрирован: Сб дек 22, 2012 09:47:33
Не могу разделить два цикла, нажатие кнопки 1, а затем кнопки 2 - одно событие, а наоборот - другое.
- Сообщения: 18
- Зарегистрирован: Сб дек 22, 2012 09:47:33
На увеличение значения переменной работает
while (PIND.0==1){}
if (PINB.0==1)
{PORTB.0=0;}
else
{PORTB.0=1}
while (PIND.0==0){}
while (PIND.1==1){}
if (PINB.0==1)
{PORTB.0=0;}
else
{PORTB.0=1}
while (PIND.1==0){}
n++;
Кнопки - PORTD, вых. PORTB
Как использоавать те же кнопки,но с нажатием в обратном порядке на уменьшение значения переменной?
while (PIND.0==1){}
if (PINB.0==1)
{PORTB.0=0;}
else
{PORTB.0=1}
while (PIND.0==0){}
while (PIND.1==1){}
if (PINB.0==1)
{PORTB.0=0;}
else
{PORTB.0=1}
while (PIND.1==0){}
n++;
Кнопки - PORTD, вых. PORTB
Как использоавать те же кнопки,но с нажатием в обратном порядке на уменьшение значения переменной?
- Сообщения: 18
- Зарегистрирован: Сб дек 22, 2012 09:47:33
- Реклама
- Сообщения: 310
- Зарегистрирован: Пт дек 17, 2010 14:41:25
Никто не мешает сохранить предыдущую нажатую кнопку в переменной. А потом судя по ее значении и работать.
словами:
если нажата кнопка, то:
словами:
если нажата кнопка, то:
- если пред_кнопка = 0 то запоминаем нажатую кнопку
- если пред_кнопка = 1(первая кнопка)(значение может быть другое) то если нажата кнопка 2 - переменная++ пред_кнопка=0
- если пред_кнопка = 2(первая кнопка)(значение может быть другое) то если нажата кнопка 1 - переменная-- пред_кнопка=0
(ждем отпускания кнопки)
(другие действия)
- Сообщения: 18
- Зарегистрирован: Сб дек 22, 2012 09:47:33
- Сообщения: 310
- Зарегистрирован: Пт дек 17, 2010 14:41:25
Да, именно
Код: Выделить всё
switch(var)
{
case 0:
{//do something;}
break;
default:
break;
}Как то эти нажатия смахивают на обработку энкодера.
А насчет кнопок есть отдельная тема.
Могу еще подсказать насчет энкодера
Код еще не проверял.
А насчет кнопок есть отдельная тема.
Могу еще подсказать насчет энкодера
Код: Выделить всё
#define LEFT (1<<0)
#define RIGHT (1<<1)
#define PIN_MASK (LEFT|RIGHT)
status =!PINB&PIN_MASK;
switch (status){
case 0x00:case PIN_MASK :old_status =status;break;
case LEFT: case RIGHT: change=old_status^status;break;
}
switch (change){case LEFT: n--;break;
case RIGHT:n++;break;}
change=0;
- Сообщения: 7
- Зарегистрирован: Пн дек 24, 2012 11:25:45
diotec
Добрый день!
Советую почитай основы тут ->
Затем тут, и практическая реализация тут в первой части и тут во второй части.
Потратив 15 минут, Вы спокойненько сможете реализовать задуманное.
Добрый день!
Советую почитай основы тут ->
Затем тут, и практическая реализация тут в первой части и тут во второй части.
Потратив 15 минут, Вы спокойненько сможете реализовать задуманное.
- Сообщения: 18
- Зарегистрирован: Сб дек 22, 2012 09:47:33
- Сообщения: 18
- Зарегистрирован: Сб дек 22, 2012 09:47:33
Все таки не получается. Вот кусок:
#include <mega8.h>
#include <delay.h>
// Declare your global variables here
unsigned int n;
unsigned int m;
void plus (void) // Функция увеличения переменной на 1
{
if (PINB.1==0)
delay_ms(10);
while (PINB.1==1){}
if (PINB.2==0)
delay_ms(10);
while (PINB.2==1){}
n++;
}
void minus (void)//Функция уменьшения переменной на 1
{
if (PINB.2==0)
delay_ms(10);
while (PINB.2==1){}
if (PINB.1==0)
delay_ms(10);
while (PINB.1==1){}
n--;
}
void main(void)
PORTB=0x0E;
DDRB=0x01;
// Port C initialization
// Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTC=0x00;
DDRC=0xFF;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0xFF;
while (1)
{
if (PINB.1==0)//Кнопка 1
m=0;
if (PINB.2==0)//Кнопка 2
m=1;
switch(m)
{
case 0: plus();break;
case 1: minus();break;
}
if (n==1) PORTD.0=1; //Проверка значения переменной
if (n==2) PORTD.1=1;
if (n==3) PORTD.2=1;
if (n==4) PORTD.3=1;
};
}
Кнопка 1 - PORTB.1
Кнопка 2 - PORTB.2
Помогите мне пожалуйста.
#include <mega8.h>
#include <delay.h>
// Declare your global variables here
unsigned int n;
unsigned int m;
void plus (void) // Функция увеличения переменной на 1
{
if (PINB.1==0)
delay_ms(10);
while (PINB.1==1){}
if (PINB.2==0)
delay_ms(10);
while (PINB.2==1){}
n++;
}
void minus (void)//Функция уменьшения переменной на 1
{
if (PINB.2==0)
delay_ms(10);
while (PINB.2==1){}
if (PINB.1==0)
delay_ms(10);
while (PINB.1==1){}
n--;
}
void main(void)
PORTB=0x0E;
DDRB=0x01;
// Port C initialization
// Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTC=0x00;
DDRC=0xFF;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0xFF;
while (1)
{
if (PINB.1==0)//Кнопка 1
m=0;
if (PINB.2==0)//Кнопка 2
m=1;
switch(m)
{
case 0: plus();break;
case 1: minus();break;
}
if (n==1) PORTD.0=1; //Проверка значения переменной
if (n==2) PORTD.1=1;
if (n==3) PORTD.2=1;
if (n==4) PORTD.3=1;
};
}
Кнопка 1 - PORTB.1
Кнопка 2 - PORTB.2
Помогите мне пожалуйста.
Непонятны махинации с определением нажатия у вас нажатая кнопка 0 или 1?
Тут лишний switch
Код: Выделить всё
f (PINB.1==0)
delay_ms(10);
while (PINB.1==1){}// <<---Тут может зависнуть насовсем, если нажатая кнопка 0
if (PINB.2==0)
delay_ms(10);
while (PINB.2==1){}
n++;
Код: Выделить всё
{
if (PINB.1==0)//Кнопка 1
/*m=0;*/plus();
if (PINB.2==0)//Кнопка 2
/*m=1;*/minus();
//switch(m)
//{
//case 0: plus();break;
//case 1: minus();break;
//}
Последний раз редактировалось vitalik_1984 Ср дек 26, 2012 20:28:11, всего редактировалось 1 раз.
- Сообщения: 535
- Зарегистрирован: Вт авг 28, 2012 22:21:33
Я не знаю, что там конкретно не работает, но хочу сказать несколько слов по поводу вышеприведенного способа реализации этого всего. Хочу сказать, потому что выглядит это мягко говоря не очень - логика работы размазана по всему коду, особенно бросается в глаза куча циклов во всех местах, хотя можно обойтись одним-двумя.
Исходя из имеющихся на данный момент условий задачи я вижу следующий вариант решения:
0. Выполняем инициализацию периферии.
1. Сканируем нажатые кнопки. Если какая-либо кнопка нажата, то переходим в 2, иначе в 1.
2. Обрабатываем нажатие на кнопку, и соотв. образом изменяем значение переменной.
3. В зависимости от значения переменной выполняем нужное действие.
4. Переходим в 1.
Отсюда уже должно быть видно, что достаточно всего одного цикла, максимум двух. Но это, наверное, не самое интересное. Намного интереснее организация пункта 2 без кучи циклов. Чтобы понять это - необходимо знать хотя бы что-нибудь про конечные автоматы и их программную реализацию, в том числе на языке Си. Вот тут вполне доходчивое описание и пример, как раз с кучей циклов.
В нашем конкретном случае у нас будет автомат с тремя состояниями. Условно назовем их начальным состоянием (0), состоянием увеличения переменной (1), и состоянием уменьшения переменной (2). Логику работы автомата можно описать следующим образом:
Состояние 0.
- Если нажата кнопка 1, то переходим в Состояние 1.
- Если нажата кнопка 2, то переходим в Состояние 2.
Состояние 1.
- Если нажата кнопка 1, то ничего не делаем.
- Если нажата кнопка 2, то увеличиваем значение переменной и переходим в Состояние 0.
Состояние 2.
- Если нажата кнопка 1, то уменьшаем значение переменной и переходим в Состояние 0.
- Если нажата кнопка 2, то ничего не делаем.
Чтобы избежать переполнения переменной нужно проверять ее значение, перед уменьшением - не равно ли оно нулю, а перед увеличением - не достигло ли оно максимума. Так же, при сканировании нажатий кнопок нужно фильтровать дребезг, если конечно не используется какая-нибудь аппаратная фильтрация. На этом, пожалуй, все.
Конечно, можно было просто дать готовый кусок кода, но я все же надеюсь ты пойдешь путем настоящего джедая. Если нет - забудь все, что я тут написал, кто-нибудь да выложит рабочий код, который можно будет использовать особо в него не вникая. Если да - то пробуй и показывай, что получается.
Исходя из имеющихся на данный момент условий задачи я вижу следующий вариант решения:
0. Выполняем инициализацию периферии.
1. Сканируем нажатые кнопки. Если какая-либо кнопка нажата, то переходим в 2, иначе в 1.
2. Обрабатываем нажатие на кнопку, и соотв. образом изменяем значение переменной.
3. В зависимости от значения переменной выполняем нужное действие.
4. Переходим в 1.
Отсюда уже должно быть видно, что достаточно всего одного цикла, максимум двух. Но это, наверное, не самое интересное. Намного интереснее организация пункта 2 без кучи циклов. Чтобы понять это - необходимо знать хотя бы что-нибудь про конечные автоматы и их программную реализацию, в том числе на языке Си. Вот тут вполне доходчивое описание и пример, как раз с кучей циклов.
В нашем конкретном случае у нас будет автомат с тремя состояниями. Условно назовем их начальным состоянием (0), состоянием увеличения переменной (1), и состоянием уменьшения переменной (2). Логику работы автомата можно описать следующим образом:
Состояние 0.
- Если нажата кнопка 1, то переходим в Состояние 1.
- Если нажата кнопка 2, то переходим в Состояние 2.
Состояние 1.
- Если нажата кнопка 1, то ничего не делаем.
- Если нажата кнопка 2, то увеличиваем значение переменной и переходим в Состояние 0.
Состояние 2.
- Если нажата кнопка 1, то уменьшаем значение переменной и переходим в Состояние 0.
- Если нажата кнопка 2, то ничего не делаем.
Чтобы избежать переполнения переменной нужно проверять ее значение, перед уменьшением - не равно ли оно нулю, а перед увеличением - не достигло ли оно максимума. Так же, при сканировании нажатий кнопок нужно фильтровать дребезг, если конечно не используется какая-нибудь аппаратная фильтрация. На этом, пожалуй, все.
Конечно, можно было просто дать готовый кусок кода, но я все же надеюсь ты пойдешь путем настоящего джедая. Если нет - забудь все, что я тут написал, кто-нибудь да выложит рабочий код, который можно будет использовать особо в него не вникая. Если да - то пробуй и показывай, что получается.
menzoda, молодчик подошел с аналитической точки зрения 
Я то глупец, сразу готовый код пихнул. Сырой, правда.
Тут еще важный момент, если эти кнопки не бывают нажатыми обе одновременно и только последовательное нажатие приводит к смене состояния, то нужно еще предусмотреть таймаут для исключения ложных срабатываний.
Например нажали одну,вторую, потом опять первую и ушли,
Далее нужно в другую сторону двигать, нажимаем на вторую и получается снова сработает.
Я то глупец, сразу готовый код пихнул. Сырой, правда.
Тут еще важный момент, если эти кнопки не бывают нажатыми обе одновременно и только последовательное нажатие приводит к смене состояния, то нужно еще предусмотреть таймаут для исключения ложных срабатываний.
Например нажали одну,вторую, потом опять первую и ушли,
Далее нужно в другую сторону двигать, нажимаем на вторую и получается снова сработает.
- Сообщения: 535
- Зарегистрирован: Вт авг 28, 2012 22:21:33
vitalik_1984
Да, насчет этого можно подумать, просто автор не указал, как ему хотелось бы реагировать на такие ситуации.
Да, насчет этого можно подумать, просто автор не указал, как ему хотелось бы реагировать на такие ситуации.
- Сообщения: 310
- Зарегистрирован: Пт дек 17, 2010 14:41:25
Похоже, что ТС нашел готовый код. Очередной бой проигран, увы...
- Сообщения: 535
- Зарегистрирован: Вт авг 28, 2012 22:21:33
М-да

Спойлер



