Обсуждаем контроллеры компании Atmel.
Ответить

Опрос матричной клавиатуры.

Чт июл 21, 2022 16:09:19

Доброе время суток. Есть код опроса матричной клавиатуры и вывода данных на LCD дисплей. У автора он работал. Я внёс не большое изменения, переключил строки на другой порт и теперь как бы я не старался, код не работает. С автором связаться не смог так как статья 24.08.2013 года. Может кто поможет понять ошибку? Сам код и схема :


Изображение

Добавил файлы проекта.
Вложения
key4x4.zip
(18.74 KiB) Скачиваний: 60
Последний раз редактировалось azerhud Пт июл 22, 2022 09:30:37, всего редактировалось 2 раз(а).

Re: Опрос матричной клавиатуры.

Чт июл 21, 2022 19:39:09

Проект вместе с протеусом сюда, в архив zip, иначе ни кто вам этот код разбирать не будет.

Re: Опрос матричной клавиатуры.

Чт июл 21, 2022 21:55:42

char portStateC[4]= {0xEF,0xDF,0xBF,0x7F}; здесь смещение нуля в старших разрядах, но в схеме подключено к младшим.
char inputStateD[4]={0x01,0x02,0x04,0x08}; здесь смещение единицы в младших разрядах, но в схеме подключено к старшим.
PORTD=portStateC[i] здесь к D происходит подключение того, что для C, и 1это вроде бы делает логичным нелогичное выше, но нелогично в целом.
if(((PIND&inputStateD[j])==0) && (PINC&inputStateD[j])) - inputStateD как бы намекает, что это для сравнения с D как со входом... но: выше уже всё было перепутано, а тут внезапно сравнивается и PIND и PINC...

И всё это вообще неважно: по схеме порт D является входом для сигнала с порта C. В порту C в младших четырёх разрядах должна бегать единичка, притом, цикл из 4 итераций не нужен, лучше поднять частоту срабатывания таймера. И массив для перемещения единичким тоже не нужен, есть прекрасные короткие сдвиги. А в программе всё наоборот и в кашу

Re: Опрос матричной клавиатуры.

Пт июл 22, 2022 06:30:48

Здесь подправил.
Код:
char portStateC[4]= {0xFE,0xFD,0xFB,0xF7};
char inputStateD[4]={0x01,0x20,0x40,0x80};

//...

interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
    for(i=0; i<4; i++)
    {
       PORTC=portStateC[i];
       for(j=0; j<4; j++)
       {
          if(((PIND&inputStateD[j])==0) && (PINC&inputStateD[j]))
          {
             while((PIND&inputStateD[j])!=inputStateD[j]){};
             lcd_putchar(mass2[i][j]);                                     
          }
       }                         
    }
}
//...


Но похоже опять я сделал что то не так
Последний раз редактировалось azerhud Пт июл 22, 2022 13:59:44, всего редактировалось 1 раз.

Re: Опрос матричной клавиатуры.

Пт июл 22, 2022 09:48:02

А я тоже ошибся, в логике. Прошу прощения.
Сканирующим портом всё-таки является порт D и там должен бегать лог. 0 - тогда при нажатии двух и более кнопок исключается закорачивание выходов, если бы сканирование было на порту С

то есть, скан должен быть так (как и было в самом начале, за исключением несовпадающих по логике наименований):
Код:
char portStateD[4]= {0xEF,0xDF,0xBF,0x7F};
char portStateD[4]= {0xEF,0xDF,0xBF,0x7F};
//...
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
    for(i=0; i<4; i++)
    {
       PORTD=portStateD[i];
       for(j=0; j<4; j++)
       {
          //...
       }                         
    }
}


то есть, осталось всего лишь правильно определить во втором цикле, где на порту С образовался 0.
Кстати, порт С должен обязательно быть сконфигурирован с внутренней подтяжкой к питанию.
например, так:
Код:
char portStateD[4]= {0xEF,0xDF,0xBF,0x7F};
//...
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
    for(i=0; i<4; i++)
    {
       PORTD=portStateD[i];
       for(j=0; j<4; j++)
       {
          if(!(PORTС & (1 << j))
          {
                   //здесь получили координаты i и j кнопки
           }
       }                         
    }
}

Re: Опрос матричной клавиатуры.

Пт июл 22, 2022 10:05:53

Не совсем понял этот момент.
...
то есть, скан должен быть так (как и было в самом начале, за исключением несовпадающих по логике наименований):
Код:
char portStateD[4]= {0xEF,0xDF,0xBF,0x7F};
char portStateD[4]= {0xEF,0xDF,0xBF,0x7F};
//...
   


мне нужно дважды задать этот массив?
Код:
har portStateD[4]= {0xEF,0xDF,0xBF,0x7F};
char portStateD[4]= {0xEF,0xDF,0xBF,0x7F};


Весь код.

Re: Опрос матричной клавиатуры.

Пт июл 22, 2022 11:47:49

Вам же дали готовую процедуру
Вот так попробуйте
Код:
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
  for(i = 0; i < 4; i++) {
    PORTD = portStateD[i];
    for(j = 0; j < 4; j++) {
     if((!(PINC) & (1 << j)))
       lcd_putchar(mass2[i][j]);
    }
  }
}

char portStateD[4] = {0xEF, 0xDF, 0xBF, 0x7F}; //только один раз, конечно нужно объявлять
char inputStateC[4] = {0x01, 0x02, 0x04, 0x08}; // в предлагаемом варианте вообще не нужен

И да, вам еще сказали, что младшие линии порта опроса (PORTC) должны быть настроены на вход с подтяжкой. И посмотрите, как у вас. Чтобы не путаться, избегайте магических цифр, или хотя бы дополняйте их подробным комментарием, куда, что и как настраивается. Хотя бы как визард это делает:
Код:
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=P State6=P State5=P State4=P State3=P State2=P State1=P State0=P
PORTB=0xFF;
DDRB=0x00;

Re: Опрос матричной клавиатуры.

Пт июл 22, 2022 13:23:17

Уже не знаю что делать, вроде перепробовал все Ваши варианты.


Опишу проблему. Исходная статья по адресу http://avr-start.ru/?p=1244&cpage=1#comments
Всё работает отлично, но мне нужно подключить клавиатуру 4х5 и передавать символы нажатой кнопки по UART. Для этого я и решил разделить строки и столбцы. Но как бы я не пытался не удаётся мне запустить программу. Может найдётся человек который напишет мне рабочую программу с подробным описанием. Готов заплатить. Бюджет не большой :(

У самого уже мозги кипят. :(

Re: Опрос матричной клавиатуры.

Пт июл 22, 2022 14:19:49

Re: Опрос матричной клавиатуры.

Пт июл 22, 2022 15:33:13

Dimon456, Огромное СПАСИБО за помощь

Re: Опрос матричной клавиатуры.

Пт июл 22, 2022 15:37:29

azerhud писал(а): DDRC = 0x0F; // Единица младших разрядах, порт настроен как выход,
   PORTC = 0xFF; // Включаем подтягивающие резисторы

metan писал(а):И да, вам еще сказали, что младшие линии порта опроса (PORTC) должны быть настроены на вход с подтяжкой. И посмотрите, как у вас.

Dimon456 писал(а): DDRC = 0x00;
   PORTC = 0xFF;

Re: Опрос матричной клавиатуры.

Пт июл 22, 2022 18:28:51

metan, Dimon456, Спасибо. Пытаюсь поставить плюс но мне сообщают что менять карму ещё рано.

Добавлено after 1 hour 9 minutes 44 seconds:
Вроде всё получилось благодаря Вам.
Схема проекта.
Изображение

Код проекта:

Если не трудно, проверьте пожалуйста, нет ли ошибок и недочётов.

;)

Re: Опрос матричной клавиатуры.

Пт июл 22, 2022 20:33:07

Начнем наверное, как уже выше подметили, с включения подтягивающих резисторов там где это необходимо
Переменная temp должна быть объявлена как volatile, так как изменяется в прерывании, да и не зачем ее int делать, то есть volatile char , если переменная будет принимать значение 0 и 1, то достаточно ее объявить как volatile bit
Код:
volatile bit temp = 0;
Какой смысл проверять key?
Код:
if ((key) && (temp == 1))
Вы с key дальше ни чего не делаете.
Достаточно проверить
Код:
if (temp == 1)
У вас массив mass2 объявлен как тип char, соответственно функция USART_SendChar() должна так же принимать тип char
Код:
void USART_SendChar(char sym)
С MAX487 я не работал, не знаю как правильно, подскажут другие.

Re: Опрос матричной клавиатуры.

Ср июл 27, 2022 15:25:37

Всё что смог на данный момент:
Изображение

Вложения
key201_main.zip
(32.59 KiB) Скачиваний: 54

Re: Опрос матричной клавиатуры.

Ср июл 27, 2022 23:41:12

for(j = 0; j < 5; j++) можно переписать так, что inputStateC станет лишним, а значит, и тройное обращение к нему в условиях - тоже.

Re: Опрос матричной клавиатуры.

Чт июл 28, 2022 09:08:37

Martian писал(а):for(j = 0; j < 5; j++) можно переписать
Это конечно, так, но это пустяки по сравнению с конскими задержками внутри прерывания, как мне кажется :)
Я бы перенес проверку значения key внутрь главного цикла.

Re: Опрос матричной клавиатуры.

Сб июл 30, 2022 18:58:45

Пока только так смог:

Re: Опрос матричной клавиатуры.

Чт авг 04, 2022 10:08:49

azerhud, вот такой код, поиграйся

Re: Опрос матричной клавиатуры.

Пт авг 12, 2022 20:59:32

вот такой код, поиграйся

Спасибо. Применил Ваш код.
Но боюсь вновь намудрил.

Re: Опрос матричной клавиатуры.

Пт авг 12, 2022 21:56:00

azerhud писал(а):Но боюсь вновь намудрил.
Да уж, намудрили так намудрили.
Особенно Функцию задержки, откуда вы это только берете?
У avr-gcc и так нормальный delay.
Ответить