Tastaturmatrix: inkonsistente Abfrage

OP #3481972
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
(Firma: matzetronics) #3481992
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.