Forum: Mikrocontroller und Digitale Elektronik Tastaturmatrix: inkonsistente Abfrage


von Fabian B. (fanick)


Lesenswert?

Hallo,

ich habe ein Problem mit einer Tastenmatrix an einem Atmega16.
Ich nutze einen angepassten Code von Peter Dannegger:
1
uint8_t keyscan( void )
2
{
3
  uint8_t col = 0, row = 0;
4
5
  KEY_PORT |= 0x7F;                     // all pullups on
6
  KEY_DDR = (KEY_DDR & 0x80) | 0x78;    // pin 6..3 = output
7
  KEY_PORT &= 0x87;                     // pin 6..3 = output low
8
  NOP();                                // wait until inputs sampled
9
  if( ~KEY_PIN & 1<<0 )                 // if pin 0 = low
10
    col = 3;
11
  NOP();
12
  if( ~KEY_PIN & 1<<1 )
13
    col = 2;
14
  NOP();
15
  if( ~KEY_PIN & 1<<2 )
16
    col = 1;
17
  row = col;
18
  if( col ){                            // if column found, check row
19
    KEY_PORT |= 0x7F;                   // all pullups on
20
    KEY_DDR = (KEY_DDR & 0x80) | 0x07;  // pin 2..0 = output
21
    KEY_PORT &= 0xF8;                   // pin 2..0 = output low
22
    NOP();                              // wait until inputs sampled
23
    if( ~KEY_PIN & 1<<3 )
24
    row = 4;
25
    if( ~KEY_PIN & 1<<4 )
26
    row = 7;
27
    if( ~KEY_PIN & 1<<5 )
28
    row = 10;
29
    if( ~KEY_PIN & 1<<6 )
30
    row = 13;
31
  }                                     // 0 = no key
32
  return row - col;                     // 1..12 = key
33
}

Wenn ich das so direkt ohne entprellen usw. zum Testen nutze 
funktionieren die Spalten 1 und 2 nur sehr seltsam. In der Zeile 1 und 2 
wird mir immer Spalte 2 gedrückt angezeigt, in der Zeile 3 und 4 wird 
alles korrekt erkannt.

Ich habe nun NOPs vor den Abfragen eingebaut:
1
uint8_t keyscan( void )
2
{
3
  uint8_t col = 0, row = 0;
4
5
  KEY_PORT |= 0x7F;                     // all pullups on
6
  KEY_DDR = (KEY_DDR & 0x80) | 0x78;    // pin 6..3 = output
7
  KEY_PORT &= 0x87;                     // pin 6..3 = output low
8
  NOP();                                // wait until inputs sampled
9
  if( ~KEY_PIN & 1<<0 )                 // if pin 0 = low
10
    col = 3;
11
  NOP();
12
  if( ~KEY_PIN & 1<<1 )
13
    col = 2;
14
  NOP();
15
  if( ~KEY_PIN & 1<<2 )
16
    col = 1;
17
  row = col;
18
  if( col ){                            // if column found, check row
19
    KEY_PORT |= 0x7F;                   // all pullups on
20
    KEY_DDR = (KEY_DDR & 0x80) | 0x07;  // pin 2..0 = output
21
    KEY_PORT &= 0xF8;                   // pin 2..0 = output low
22
    NOP();                              // wait until inputs sampled
23
    if( ~KEY_PIN & 1<<3 )
24
      row = 4;
25
    NOP();
26
    if( ~KEY_PIN & 1<<4 )
27
      row = 7;
28
    NOP();
29
    if( ~KEY_PIN & 1<<5 )
30
      row = 10;
31
    NOP();
32
    if( ~KEY_PIN & 1<<6 )
33
      row = 13;
34
  }                                     // 0 = no key
35
  return row - col;                     // 1..12 = key
36
}
Damit funktioniert es teilweise auch in Zeile 1 und 2.
Als nächsten Schritt hatte ich 2 NOPs getestet, damit funktioniert es 
fast immer! Die Spalten und Zeilen einzeln habe ich natürlich getestet, 
dort hat sich alles wie geplant verhalten.

Wie kann ich mir sowas erklären? Und wie kann ich den Fehler finden? 
Welche Informationen muss ich noch angeben? :S

Vielen Dank für eure Hilfe!

Fabian

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Die Setzzeit der Spalten wird einfach zu klein sein. Die internen 
Pullups sind nicht die stärksten und da dauert es einen kleinen Moment, 
bis die Leitungen stabil sind. Ich schlage vor, die Strategie ein wenig 
abzuwandeln: Du liest zuerst aus und setzt vor dem Verlassen der Routine 
die Spalten für den nächsten Durchlauf. Da ist dann vermutlich genug 
Zeit für die Leitungen, sich zu setzen, vor allem, wenn das in einer 
Timerrunde passiert.

: Bearbeitet durch User
von Fabian B. (fanick)


Lesenswert?

Vielen vielen Dank! :-)

Das wars!


Viele Grüße,
Fabian

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.