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

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.