Problem beim Auslesen einer 3x4 Tastaturmatrix

OP #1902393
Lesenswert?

Ich möchte eine 3x4 Tastenmatrix auslesen und das Ergebnis am Port C 
darstellen. Wenn ich den Code schrittweise durchsteppe, funktioniert 
alles.

Im Betrieb erhalte ich folgende Ergebnisse:
Ausgabe bei Tastendruck in der 1. Zeile = 1
Ausgabe bei Tastendruck in der 2. Zeile = 4
Ausgabe bei Tastendruck in der 3. Zeile = 7
Ausgabe bei Tastendruck in der 4. Zeile = 10

Ich habe da nun keine Idee mehr und bitte um Eure Hilfe!

Hier der C-Code:
1
/****************************************************************
2
* Einlesen der Tasten einer 3x4 Tastenmatrix          *
3
* Controller: ATMEL 90PWM316                  *
4
* Portanschlüsse der Tastenmatrix:                *
5
* Spalten:  row1=PD6, row2=PB2, row3=PB5            *
6
* Zeilen:  col1=PD5, col2=PD4, col3=PD2, col4=PD1        *
7
****************************************************************/
8

9
#include <avr/io.h>
10
#include <util/delay.h>
11

12
#define NOP();  asm volatile("nop"::);
13

14
uint8_t KeyMap[] =        // Korrektur der Tastenergebnisse
15
    { 0,                  // Anpassung an die Tastatur
16
      1, 4, 7, 10,        // 1   2   3
17
      2, 5, 8, 11,        // 4   5   6
18
      3, 6, 9, 12         // 7   8   9
19
    };                    // 10  11  12
20

21
uint8_t keyscan( void )
22
{
23
    _delay_ms(30);
24

25
  uint8_t col = 0, row = 0;
26

27
  //**** Spalten = output + low, Zeilen = input + pull up ****
28
  DDRB  =  (1<<PB2)|(1<<PB5);
29
  DDRD  =  (1<<PD6);
30
  PORTB  &=  ((0<<PB2)|(0<<PB5));
31
  PORTD  &=  (0<<PD6);
32
  PORTD    |=  (1<<PD1)|(1<<PD2)|(1<<PD4)|(1<<PD5);
33

34
    NOP();                              // wait until inputs sampled
35
  _delay_us(20);
36
    if(!(PIND & (1<<PIND5)))          // if column 1 = low
37
    {
38
      col = 4;
39
  }
40
    else if(!(PIND & (1<<PIND4)))    // if column 2 = low
41
    {
42
      col = 3;
43
  }
44
    else if(!(PIND & (1<<PIND2)))    // if column 3 = low
45
    {
46
      col = 2;
47
  }
48
    else if(!(PIND & (1<<PIND1)))    // if column 4 = low
49
    {
50
      col = 1;
51
  }
52
    
53
  if( col )                           // if column found, check row
54
  {
55
  //**** Spalten = input + pull up, Zeilen = output + low ****
56
    DDRB  &=  ((0<<PB2)|(0<<PB5));
57
    DDRD  &=  (0<<PD6);
58
    PORTB  =  (1<<PB2)|(1<<PB5);
59
    PORTD  =  (1<<PD6);
60
    DDRD  |=  (1<<PD1)|(1<<PD2)|(1<<PD4)|(1<<PD5);
61
    PORTD    &=  ((0<<PD1)|(0<<PD2)|(0<<PD4)|(0<<PD5));
62

63
      NOP();                          // wait until inputs sampled
64
    _delay_us(20);
65
      if(!(PIND & (1<<PIND6)))    // if row 1 = low
66
    {
67
         row = 5;
68
      }
69
      else if(!(PINB & (1<<PINB2)))  // if row 2 = low
70
    {
71
          row = 9;
72
      }
73
      else if(!(PINB & (1<<PINB5)))  // if row 3 = low
74
    {
75
          row = 13;
76
      }
77
    }                                   // 0 = no key
78

79
  return KeyMap [row - col];
80
}
81

82
int main (void)
83
{
84
  DDRC = 0xFF;            
85
  while(1)
86
  {
87
    PORTC = keyscan();
88
  }
89
}
Persönliche Seite #1902714
Lesenswert?

Wie ist die Matrix angeschlossen?

Klassisch macht man das anders. Man gibt zyklisch eine Spalte oder 
Zeile vor (Ausgabe) und schaut, welcher Pin (Eingabe) gedrückt ist. Wenn 
man dann noch die Entprellung berücksichtigt, wird's perfekt.

http://www.mikrocontroller.net/forum/codesammlung?filter=matrix*
http://www.mikrocontroller.net/forum/codesammlung?filter=tasten*

=>

Beitrag "Tasten-Matrix entprellen" (Umschreiben auf AVR!)
Beitrag "Tastenmatrix auslesen über nur 2 Leitungen" (über ADC, für 
Fortgeschrittene)
#1902733
Lesenswert?

Hallo ledi,

ich finde die Lösung klasse.
Mir ist nur aufgefallen, dass du den PortD im oberen Bereich nicht auf 
Eingang gestellt hast. Somit bleibt dieser auf Ausgang und liefert immer 
falsche Werte. Es wird somit nur beim ersten Aufruf funktionieren.

DDRD  &=  ((1<<PD1)|(1<<PD2)|(1<<PD4)|(1<<PD5));


Gruß
Guido

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren