Stolbov 0 14 августа, 2018 Опубликовано 14 августа, 2018 · Жалоба Всем добрый вечер! Вообщем, я делаю небольшую поделку на основе микроконтроллера AVR, но так как мне нужно было 6 кнопок, а выводов осталось мало, я решил попробовать "выкрутиться" из этой ситуации таким образом, как это показано на рисунке. PA0 и PA1 - ножки микроконтроллера, на которых постоянно находится высокий уровень. В первый момент времени я устанавливаю на PB0 низкий уровень, и, получается, что когда мы нажимаем кнопку S1 или S4, на одном из входов МК так же установится низкий уровень напряжения. Таким образом, можно отследить, какая кнопка нажата в момент времени. Остальные кнопки опрашиваются по этому же алгоритму (подаём 0 на PB1, а потом на PB2). За сим вопрос: правильно ли я вообще делаю? Когда я проводил эксперимент с одной кнопкой, всё работало, и я с лёгкостью мог отследить её нажатие, но когда я собрал эту схему на макетке, всё пошло крахом: ни одна кнопка не отзывается. Если кто-нибудь сможет разобраться, есть ли у этой схемы шанс заработать, буду премного благодарен. Код опроса этой конструкции так же прилагаю (может быть, его можно было бы сделать изящнее, но получилось вот так). #define STEP1 1 //Метки для атомата #define STEP2 2 #define STEP3 3 //... DDRA |= (0<<PORTA0)|(0<<PORTA1); //Настройка ножек порта А на вход DDRB |= (1<<PORTB0)|(1<<PORTB1)|(1<<PORTB2); //Настройка ножек порта B на выход //.. int button_flag; //Флаг для цикла int button_state; //Для хренения состояния автомата //.. void key_polling() { button_state = STEP1; //Первое состояние button_flag = 1; //Устанавливаем флаг while(button_flag == 1) { switch(button_state) { case STEP1: //Опрашиваем кнопки 1 и 4 PORTB |= (0<<PORTB0)|(1<<PORTB1)|(1<<PORTB2); //На ножке PB0 устанавливаем низкий уровень if((PINA & (1<<PORTA0) == 0)) //Если на PA0 - 0, то... { //Некое действие button_state = STEP2; //Переходим к опрос следующей двойки } else if((PINA & (1<<PORTA1) == 0)) //Если на PA1 - 0, то... { //Что-то делаем button_state = STEP2; } else //Если не получили низкий уровень ни на одной из ножек { button_state = STEP2; } break; case STEP1: //Опрашиваем кнопки 2 и 5 PORTB |= (1<<PORTB0)|(0<<PORTB1)|(1<<PORTB2); //На PB1 устанавливаем низкий уровень //Код, аналогичный блоку STEP1 break; case STEP3: //Опрашиваем кнопки 3 и 6 PORTB |= (1<<PORTB0)|(1<<PORTB1)|(0<<PORTB2); //На PB2 устанавливаем низкий уровень //Код, аналогичный блоку STEP1 button_flag = 0; //Так как все кнопки опросили, обнуляем флаг для выхода из цикла break; } } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
@Ark 3 14 августа, 2018 Опубликовано 14 августа, 2018 · Жалоба Ноги порта PB должны быть первоначально конфигурированы как входы. При опросе, переключаете по одной на выход и устанавливаете низкий уровень. По завершению опроса - снова переключаете на вход. И так - для всех ног порта PB. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 220 14 августа, 2018 Опубликовано 14 августа, 2018 · Жалоба Скорость работы неизвестна, и кнопки фантастические, без дребезга. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vladec 12 15 августа, 2018 Опубликовано 15 августа, 2018 · Жалоба (может быть, его можно было бы сделать изящнее, но получилось вот так). Для шести кнопок в контроллере можно легко обойтись одним входом подключенным к АЦП контроллера. Для этого запитываете цепочку из семи последовательно включенных одинаковых резисторов (последний на землю), после каждого из остальных резисторов ставите кнопку на землю, с последнего резистора сигнал на АЦП контроллера. По измеренному напряжению определяете нажатую кнопку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
@Ark 3 15 августа, 2018 Опубликовано 15 августа, 2018 · Жалоба Для шести кнопок в контроллере можно легко обойтись одним входом подключенным к АЦП контроллера. Для этого запитываете цепочку из семи последовательно включенных одинаковых резисторов (последний на землю), после каждого из остальных резисторов ставите кнопку на землю, с последнего резистора сигнал на АЦП контроллера. По измеренному напряжению определяете нажатую кнопку. Как отследить одновременное нажатие нескольких кнопок? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 15 августа, 2018 Опубликовано 15 августа, 2018 · Жалоба За сим вопрос: правильно ли я вообще делаю? Неправильно если могут быть одновременно нажаты несколько кнопок. Необходимы диоды. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jeelman 0 15 августа, 2018 Опубликовано 15 августа, 2018 (изменено) · Жалоба если не требуется большая защищённость от помех и разрядов то можно сделать наподобие того как во вложении. подпрограмму опроса запускать в прерывании. kb.zip Изменено 15 августа, 2018 пользователем jeelman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 15 августа, 2018 Опубликовано 15 августа, 2018 · Жалоба Неправильно если могут быть одновременно нажаты несколько кнопок. Необходимы диоды. Да можно и без диодов, в общем-то. Сканировать не жесткими Push-Pull-ными '0' и '1', а '0' и 'Hi-Z'. КЗ не случится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 15 августа, 2018 Опубликовано 15 августа, 2018 · Жалоба Если кто-нибудь сможет разобраться, есть ли у этой схемы шанс заработать, буду премного благодарен. Ваше решение - матричная клавиатура. http://cxem.net/mc/book45.php Впрочем, вы почти её и реализовали. Но всё же лучше сделать, как на схеме по ссылке. Поставить подтягивающие резисторы и диоды. Тогда, настроив подтянутые к VCC пины на вход, и подавая "бегущий" ноль на выходы (с диодами), вы можете определить нажатую клавишу. Ну или несколько клавиш (для этого диоды и нужны). С программой, я думаю, справитесь. Там алгоритм не очень сложный. Но это зависит от того, что вы хотите получить. Например, вам нужна задержка перед автоповтором, задержка между автоповтором, но быстрая реакция на нажатие, если клавишу нажали и тут же отпустили? Как в компьютере? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 15 августа, 2018 Опубликовано 15 августа, 2018 · Жалоба Ваше решение - матричная клавиатура. http://cxem.net/mc/book45.php Впрочем, вы почти её и реализовали. Но всё же лучше сделать, как на схеме по ссылке. Поставить подтягивающие резисторы и диоды. Тогда, настроив подтянутые к VCC пины на вход, и подавая "бегущий" ноль на выходы (с диодами), вы можете определить нажатую клавишу. Ну или несколько клавиш (для этого диоды и нужны). С программой, я думаю, справитесь. Там алгоритм не очень сложный. Но это зависит от того, что вы хотите получить. Например, вам нужна задержка перед автоповтором, задержка между автоповтором, но быстрая реакция на нажатие, если клавишу нажали и тут же отпустили? Как в компьютере? Опять же, диоды можно не ставить :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stolbov 0 15 августа, 2018 Опубликовано 15 августа, 2018 · Жалоба haker_fox, мне нужна быстрая реакция на нажатие. Нажал кнопку - произошло некоторое действие. Скорее всего, сделаю так, как Вы и сказали. Я сейчас пробовал делать по совету @Ark'а (он писал про то, что ножки, по которым у меня происходит опрос кнопок, должны быть настроены как входы), но у меня выходит что-то невразумительное, но тут уже, наверное, дело в моих навыках программиста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 15 августа, 2018 Опубликовано 15 августа, 2018 · Жалоба haker_fox, мне нужна быстрая реакция на нажатие. Ну что значит "быстрая?". Вы ведь кнопки обрабатываете. И потом, какое отношение матричная клавиатура имеет к понятию "быстродействие"? Опять же, вам понадобится фильтрация дребезга, если эти кнопки не с волешбной планеты Нибиру (бездребезговые, от слова "совсем"). А подавление дребезга - это уже около 10 - 50 мс. Это быстро для вас или меделенно? Опять же, диоды можно не ставить :rolleyes: Ну кому как нравится) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 15 августа, 2018 Опубликовано 15 августа, 2018 · Жалоба Да можно и без диодов, в общем-то. Сканировать не жесткими Push-Pull-ными '0' и '1', а '0' и 'Hi-Z'. КЗ не случится. Без диодов невозможно корректно сканировать если возможны произвольные одновременные нажатия. От слова - никак. Никакие пуш-пуллы тут не помогут. Ваше решение - матричная клавиатура. http://cxem.net/mc/book45.php Впрочем, вы почти её и реализовали. Но всё же лучше сделать, как на схеме по ссылке. Поставить подтягивающие резисторы и диоды. Тогда, настроив подтянутые к VCC пины на вход, и подавая "бегущий" ноль на выходы (с диодами), вы можете определить нажатую клавишу. Ну или несколько клавиш (для этого диоды и нужны). То что на приведённой Вами схеме, нормально будет работать только с некоторыми одновременными нажатиями. Но не со всеми. При нормальной реализации диоды ставят не так как там, а последовательно с кнопками. Ну кому как нравится) "Нравятся" - это девушки. А схема - или работает или нет. :rolleyes: Приведённая Вами не работает со многими тройными нажатиями. А если поставить диоды правильно, то будет работать с любыми комбинациями нажатий. Это быстро для вас или меделенно? Видимо автор полагает что он умеет нажимать на кнопки с частотой 1кГц. :biggrin: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
@Ark 3 15 августа, 2018 Опубликовано 15 августа, 2018 (изменено) · Жалоба Я сейчас пробовал делать по совету @Ark'а (он писал про то, что ножки, по которым у меня происходит опрос кнопок, должны быть настроены как входы), но у меня выходит что-то невразумительное, но тут уже, наверное, дело в моих навыках программиста. Изначально рабочие порты PB должны быть заданы как входы. Когда надо опросить, например, линию PB0, то переключаете ее временно на выход. Записываете в этот порт "ноль", выдерживаете некоторую паузу, затем, смотрите - что у Вас на входах порта PA. Далее снова переводите порт PB0 на вход. Повторяете так для всех рабочих линий порта PB. P.S. Не нужны вам никакие диоды, эта схема годится. Изменено 15 августа, 2018 пользователем @Ark Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stolbov 0 15 августа, 2018 Опубликовано 15 августа, 2018 · Жалоба haker_fox, я просто не верно выразился по поводу "быстродействия". Я же не собираюсь засекать время между нажатием кнопки и выполнением некоего действия. 10 -50 мс для подавления дребезга - это нормально. У меня проблема сейчас какая: я пока использую свою схему, всё же пытаюсь её "добить", но так как у меня между состояниями опроса кнопок нет никаких пауз + дребезг, моя клавиатура превратилась в генератор случайных чисел. Я пока пытаюсь привести всё в "человеческий" вид, но пока не выходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться