Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Тема закрыта

Re: Обработка нажатия кнопки в AVR...

Ср янв 18, 2012 11:40:38

Мастер Ломастер писал(а):
BerZerK-ku писал(а):Может еще подскажите в какой из библиотек?

а смысл? гуру учить - только себе проблем нажить :)))
Обычный ваш ответ. Простой поиск по содержимому в папке WinAVR говорит о то, что подобного там нет :dont_know:

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

понял, как это работает (плохо) и стал делать по-другому - вы это имели ввиду?

Именно. Главное:
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

Мастер Ломастер писал(а):
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

Мастер Ломастер писал(а):не работает? а почему, вы разобрались? я этот подход применяю в своих программах - работает отлично, почему у вас не работает? ;) мне за вас всю программу написать?

подсказку последнюю помните? про то, что надо как-то дожидаться отпускания кнопки или что-то подобное делать, чтобы быстро-быстро не делать кучу действий на одно нажатие, помните? попробуйте теперь, с учетом новых знаний сделать - получится или нет?


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

Re: Обработка нажатия кнопки в AVR...

Ср янв 18, 2012 12:17:17

у вас не хватает желания подумать самому. во всех строчках. для смеху сделайте вот такой код, от которого затем пляшите:
Код:
while(1) PORTB = get_key_pressed();
разумеется, на PORTB поставьте 8 светодиодов с резисторами. или в протеусе нариссуйте, что проще и безопаснее.

Re: Обработка нажатия кнопки в AVR...

Ср янв 18, 2012 12:31:25

Мастер Ломастер писал(а):у вас не хватает желания подумать самому. во всех строчках. для смеху сделайте вот такой код, от которого затем пляшите:
Код:
while(1) PORTB = get_key_pressed();
разумеется, на 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;
}

схема в протеусе:
Изображение
Вложения
proteus.zip
проект в протеусе
(15.36 KiB) Скачиваний: 259

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

Кхм-кхм, т.е. тут преобразование типов виновато
Код:
 Было:
key = ~(PIND & ANY_KEY);
Стало:
key = ~PIND & ANY_KEY
?
Спешу огорчить, виновата как раз неправильная последовательность действий. А-ля, ставлю в скобки все что вижу :)))

Re: Обработка нажатия кнопки в AVR...

Ср янв 18, 2012 13:25:17

давайте миритесь уже и пиво пить идемте...
спасиб товарищи) вроде как выходит каменный цветок

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

:))) Опять появился какой-то мифический код, которого небыло ранее.
Мастер Ломастер писал(а):да, век живи - век учись моя вина: сам всех учу правилам преобразования типов, и сам же попал на это правило. код функции опроса кнопок надо чуть-чуть видоизменить:
Код:
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

:))) да здравствует правда. Как итог рабочий код, причем приведен он вами же, но почему-то вы же от него и открестились:
Код:
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

К сожалению все появилось во время написания моего поста, до этого оно было не все :)

Re: Обработка нажатия кнопки в AVR...

Ср янв 18, 2012 16:43:34

BerZerK-ku писал(а):К сожалению все появилось во время написания моего поста, до этого оно было не все :)
умная мысля приходит опосля: когда я понял, что мои слова могут быть поняты не так, я исправил и дополнил пост.

Re: Обработка нажатия кнопки в AVR...

Ср янв 18, 2012 16:47:08

Не знаю что там можно понять не так. Вы говорили о каком-то преобразовании типов, которое всему мешает, а ошибка крылась в другом месте :dont_know:
Тема закрыта