Страница 5 из 15
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 11:40:38
BerZerK-ku
Мастер Ломастер писал(а):BerZerK-ku писал(а):Может еще подскажите в какой из библиотек?
а смысл? гуру учить - только себе проблем нажить

Обычный ваш ответ. Простой поиск по содержимому в папке WinAVR говорит о то, что подобного там нет

Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 11:41:07
AR_AROV
AR_AROV писал(а):Мастер Ломастер писал(а):как минимум потому, что вы не читали, как надо опрашивать кнопку - а я для вас подробно все описывал. категорически недопустимо работать с кнопкаи, опрашивая 1 раз пин порта! сколько раз еще надо повторить?!
а сколько раз надо опрашивать? я делал так как вы писали, но у меня не получилось
как надо делать правильно?
я после условия поставил задержу-антидребезг в 50 мс, вроде вышло и работает
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 11:42:51
Мастер Ломастер
AR_AROV писал(а):как надо делать правильно?
я после условия поставил задержу-антидребезг в 50 мс, вроде вышло и работает
всё, я пас

Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 11:43:25
ploop
понял, как это работает (плохо) и стал делать по-другому - вы это имели ввиду?
Именно. Главное:
1. Понял
2. Догадался, что надо по другому.
3. Догадался как надо по другому.
А то получается - делай так, и будет те щааастье... а как работает не понимаем...
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 11:47:45
Мастер Ломастер
ploop писал(а):А то получается - делай так, и будет те щааастье... а как работает не понимаем...
обижаешь, начальник!

я всегда объясняю, почему надо делать так, как я советую:
Мастер Ломастер писал(а):не можете поймать нажатие кнопки? поступайте, как я вам рассказывал

итак, задача: есть порт МК, к которому на землю подключено до 8 кнопок. надо отловить их нажатия. как поступить? заранее настроить порт на ввод с встроенными подтяжками, тогда чтение порта с ненажатыми кнопками вернет единицы во всех разрядах байта, а если будет что-то нажато - в том месте будет ноль. кнопка может "дребезжать", т.е. некоторое время (10-25 мс) не иметь постоянного контакта - этого нужно избежать. как? опрашиваем порт, запоминаем результат. ждем 10-25 мс и снова опрашиваем порт, сравнивая результат с запомненным: если они совпали, значит, дребезг уже закончился (или не начинался) и считаны именно данны о нажатых кнопках. теперь, когда на словах разобрались с алгоритмом, опишем его на языке Си, вспоминая ранее данные рекомендации о кодах кнопок:
Код: Выделить всё
#define KEY_1 (1<<PB0)
#define KEY_2 (1<<PB1)
// и так далее хоть все 8 кнопок
#define ANY_KEY (KEY_1 | KEY_2) /* тут надо перечислить все существующие кнопки, и не слушайте тех, кто скажет, что скобки лишние */
#define NO_KEY 0
// настройка порта на ввод с подтяжками - делается где-то в начале main()
DDRB &= ~ANY_KEY;
PORTB |= ANY_KEY;
// функция получения кода нажатых кнопок
unsigned char get_key_pressed(void){
unsigned char key;
key = ~(PINB & ANY_KEY);
delay_ms(15); // задержка для подавления дребезга
if(key == ~(PINB & ANY_KEY))
return key;
else
return NO_KEY; // если дребезг - вернем 0, что будет означать: не нажата ни одна кнопка
}
разумеется, лучше кодам кнопок давать более осмысленные имена, например не KEY_1, а NEXT_EFFEKT_KEY и т.п. - это позволит получить более читабельную программу.
вопросы?

но заставлять-то не могу - вот и делают все "вроде работает", а через 5 минут снова вопросы...
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 11:56:38
AR_AROV
Мастер Ломастер писал(а):ploop писал(а):А то получается - делай так, и будет те щааастье... а как работает не понимаем...
обижаешь, начальник!

я всегда объясняю, почему надо делать так, как я советую:
Мастер Ломастер писал(а):не можете поймать нажатие кнопки? поступайте, как я вам рассказывал

итак, задача: есть порт МК, к которому на землю подключено до 8 кнопок. надо отловить их нажатия. как поступить? заранее настроить порт на ввод с встроенными подтяжками, тогда чтение порта с ненажатыми кнопками вернет единицы во всех разрядах байта, а если будет что-то нажато - в том месте будет ноль. кнопка может "дребезжать", т.е. некоторое время (10-25 мс) не иметь постоянного контакта - этого нужно избежать. как? опрашиваем порт, запоминаем результат. ждем 10-25 мс и снова опрашиваем порт, сравнивая результат с запомненным: если они совпали, значит, дребезг уже закончился (или не начинался) и считаны именно данны о нажатых кнопках. теперь, когда на словах разобрались с алгоритмом, опишем его на языке Си, вспоминая ранее данные рекомендации о кодах кнопок:
Код: Выделить всё
#define KEY_1 (1<<PB0)
#define KEY_2 (1<<PB1)
// и так далее хоть все 8 кнопок
#define ANY_KEY (KEY_1 | KEY_2) /* тут надо перечислить все существующие кнопки, и не слушайте тех, кто скажет, что скобки лишние */
#define NO_KEY 0
// настройка порта на ввод с подтяжками - делается где-то в начале main()
DDRB &= ~ANY_KEY;
PORTB |= ANY_KEY;
// функция получения кода нажатых кнопок
unsigned char get_key_pressed(void){
unsigned char key;
key = ~(PINB & ANY_KEY);
delay_ms(15); // задержка для подавления дребезга
if(key == ~(PINB & ANY_KEY))
return key;
else
return NO_KEY; // если дребезг - вернем 0, что будет означать: не нажата ни одна кнопка
}
разумеется, лучше кодам кнопок давать более осмысленные имена, например не KEY_1, а NEXT_EFFEKT_KEY и т.п. - это позволит получить более читабельную программу.
вопросы?

но заставлять-то не могу - вот и делают все "вроде работает", а через 5 минут снова вопросы...
вот так не работает ведь, я уже делал (((
Код: Выделить всё
#define KEY_1 (1<<PIND0)
#define KEY_2 (1<<PIND1)
#define KEY_3 (1<<PIND2)
#define KEY_4 (1<<PIND3)
#define KEY_5 (1<<PIND4)
#define ANY_KEY (KEY_1 | KEY_2 | KEY_3 | KEY_4 | KEY_5 )
#define NO_KEY 0
// функция получения кода нажатых кнопок
unsigned char get_key_pressed(void)
{
unsigned char key;
key = ~(PIND & ANY_KEY);
delay(15); // задержка для подавления дребезга
if(key == ~(PIND & ANY_KEY))
return key;
else
return NO_KEY; // если дребезг - вернем 0, что будет означать: не нажата ни одна кнопка
}
int main( void )
{
char del;
int i;
PORTB = 0xFF;
DDRB = 0xFF;
DDRD &= ~ANY_KEY;
PORTD |= ANY_KEY;
while(1)
{
//PORTB = PIND;
switch(get_key_pressed()) // при помощи функции get_key_pressed получаем код нажатой кнопки
{
case KEY_5:
// след.эффект
effect++;
if (effect>3) effect = 0;
break;
}
switch(effect)
{
case 0:
PORTB=0x00;
break;
case 1:
PORTB=0xFF;
break;
case 2:
PORTB=0xFF;
del = 5 / delitel;
i = interval * del ;
delay(i);
PORTB=0x00;
i = interval * (1/del);
delay(i);
break;
}
}
return 0;
}
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 12:00:04
Мастер Ломастер
не работает? а почему, вы разобрались? я этот подход применяю в своих программах - работает отлично, почему у вас не работает?

мне за вас всю программу написать?
подсказку последнюю помните? про то, что надо как-то дожидаться отпускания кнопки или что-то подобное делать, чтобы быстро-быстро не делать кучу действий на одно нажатие, помните? попробуйте теперь, с учетом новых знаний сделать - получится или нет?
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 12:12:34
AR_AROV
Мастер Ломастер писал(а):не работает? а почему, вы разобрались? я этот подход применяю в своих программах - работает отлично, почему у вас не работает?

мне за вас всю программу написать?
подсказку последнюю помните? про то, что надо как-то дожидаться отпускания кнопки или что-то подобное делать, чтобы быстро-быстро не делать кучу действий на одно нажатие, помните? попробуйте теперь, с учетом новых знаний сделать - получится или нет?
не надо писать за меня, прошу указать в какой строчке чего у меня не хватает...
я выложил весь код
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 12:17:17
Мастер Ломастер
у вас не хватает желания подумать самому. во всех строчках. для смеху сделайте вот такой код, от которого затем пляшите:
разумеется, на PORTB поставьте 8 светодиодов с резисторами. или в протеусе нариссуйте, что проще и безопаснее.
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 12:31:25
AR_AROV
Мастер Ломастер писал(а):у вас не хватает желания подумать самому. во всех строчках. для смеху сделайте вот такой код, от которого затем пляшите:
разумеется, на PORTB поставьте 8 светодиодов с резисторами. или в протеусе нариссуйте, что проще и безопаснее.
ничего не загорается, ни в схеме ни в протеусе (((
int main( void )
{
char del;
int i;
PORTB = 0xFF;
DDRB = 0xFF;
DDRD &= ~ANY_KEY;
PORTD |= ANY_KEY;
while(1)
{
PORTB = get_key_pressed();
}
return 0;
}
схема в протеусе:

Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 13:00:51
Мастер Ломастер
AR_AROV писал(а):ничего не загорается, ни в схеме ни в протеусе (((
да, век живи - век учись

моя вина: сам всех учу правилам преобразования типов, и сам же попал на это правило. код функции опроса кнопок надо чуть-чуть видоизменить:
Код: Выделить всё
unsigned char get_key_pressed(void){
unsigned char key;
key = ~PIND & ANY_KEY;
delay(15);
if(key == (~PIND & ANY_KEY))
return key;
else
return NO_KEY;
}
извините, оплошал...
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 13:22:08
BerZerK-ku
Кхм-кхм, т.е. тут преобразование типов виновато
Код: Выделить всё
Было:
key = ~(PIND & ANY_KEY);
Стало:
key = ~PIND & ANY_KEY
?
Спешу огорчить, виновата как раз неправильная последовательность действий. А-ля, ставлю в скобки все что вижу

Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 13:25:17
AR_AROV
давайте миритесь уже и пиво пить идемте...
спасиб товарищи) вроде как выходит каменный цветок
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 16:11:20
Мастер Ломастер
BerZerK-ku писал(а):Кхм-кхм, т.е. тут преобразование типов виновато
Код: Выделить всё
Было:
key = ~(PIND & ANY_KEY);
Стало:
key = ~PIND & ANY_KEY
?
Спешу огорчить, виновата как раз неправильная последовательность действий. А-ля, ставлю в скобки все что вижу

эх, гуру, гуру... слона-то вы и не приметили. то, на что вы обратили внимание - это ЛЕЧЕНИЕ, а преобразование типов в другом месте мешало. даю подсказку.
вот так
НЕ РАБОТАЛО:
Код: Выделить всё
unsigned char get_key_pressed(void){
unsigned char key;
key = ~(PIND & ANY_KEY);
delay(15);
if(key == ~(PIND & ANY_KEY))
return key;
else
return NO_KEY;
}
а вот так -
РАБОТАЛО:
Код: Выделить всё
unsigned char get_key_pressed(void){
unsigned char key;
unsigned char key2;
key = ~(PIND & ANY_KEY);
delay(15);
key2 = ~(PIND & ANY_KEY);
if(key == key2)
return key;
else
return NO_KEY;
}
понимаете теперь, где собака порылась, гуру?
P.S. кстати, гуру - это слово какого рода? а то иной раз хочется сказать "эта гура" или "это гуру"...
P.P.S. признаюсь честно: мало того, что первоначальный код был с ошибкой преобразования типа, но и скобки я поставил тоже зря. поспешил, однако. вышеприведенные 2 примера работали и не работали для кода
PORTB = get_key_pressed(); - для других применений первая версия была бы непригодна, к сожалению... она, конечно, работала бы в последнем варианте, но возвращала бы не совсем те значения, что ожидались. спешка до добра не доводит

Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 16:32:56
BerZerK-ku

Опять появился какой-то мифический код, которого небыло ранее.
Мастер Ломастер писал(а):да, век живи - век учись моя вина: сам всех учу правилам преобразования типов, и сам же попал на это правило. код функции опроса кнопок надо чуть-чуть видоизменить:
Код:
unsigned char get_key_pressed(void){
unsigned char key;
key = ~PIND & ANY_KEY;
delay(15);
if(key == (~PIND & ANY_KEY))
return key;
else
return NO_KEY;
}
извините, оплошал...
Немного отличается от приведенного выше, не правдо ли?
Код: Выделить всё
unsigned char get_key_pressed(void){
unsigned char key;
unsigned char key2;
key = ~(PIND & ANY_KEY);
delay(15);
key2 = ~(PIND & ANY_KEY);
if(key == key2)
return key;
else
return NO_KEY;
}
Мне уже даже интересно, ваш последний пример, который "РАБОТАЛО" где работало? оно изначально НЕ РАБОТАЛО. Оно может РАБОТАЛО, только если внести еще несколько поправок.
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 16:35:07
BerZerK-ku

да здравствует правда. Как итог рабочий код, причем приведен он вами же, но почему-то вы же от него и открестились:
Код: Выделить всё
unsigned char get_key_pressed(void){
unsigned char key;
key = ~PIND & ANY_KEY;
delay(15);
if(key == (~PIND & ANY_KEY))
return key;
else
return NO_KEY;
}
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 16:36:15
Мастер Ломастер
BerZerK-ku писал(а):пример, который "РАБОТАЛО" где работало?
прочтите внимательно все
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 16:37:29
BerZerK-ku
К сожалению все появилось во время написания моего поста, до этого оно было не все

Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 16:43:34
Мастер Ломастер
BerZerK-ku писал(а):К сожалению все появилось во время написания моего поста, до этого оно было не все

умная мысля приходит опосля: когда я понял, что мои слова могут быть поняты не так, я исправил и дополнил пост.
Re: Обработка нажатия кнопки в AVR...
Добавлено: Ср янв 18, 2012 16:47:08
BerZerK-ku
Не знаю что там можно понять не так. Вы говорили о каком-то преобразовании типов, которое всему мешает, а ошибка крылась в другом месте
