mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem beim Auslesen einer 3x4 Tastaturmatrix


Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht 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:
/****************************************************************
* Einlesen der Tasten einer 3x4 Tastenmatrix          *
* Controller: ATMEL 90PWM316                  *
* Portanschlüsse der Tastenmatrix:                *
* Spalten:  row1=PD6, row2=PB2, row3=PB5            *
* Zeilen:  col1=PD5, col2=PD4, col3=PD2, col4=PD1        *
****************************************************************/

#include <avr/io.h>
#include <util/delay.h>

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

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

uint8_t keyscan( void )
{
    _delay_ms(30);

  uint8_t col = 0, row = 0;

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

    NOP();                              // wait until inputs sampled
  _delay_us(20);
    if(!(PIND & (1<<PIND5)))          // if column 1 = low
    {
      col = 4;
  }
    else if(!(PIND & (1<<PIND4)))    // if column 2 = low
    {
      col = 3;
  }
    else if(!(PIND & (1<<PIND2)))    // if column 3 = low
    {
      col = 2;
  }
    else if(!(PIND & (1<<PIND1)))    // if column 4 = low
    {
      col = 1;
  }
    
  if( col )                           // if column found, check row
  {
  //**** Spalten = input + pull up, Zeilen = output + low ****
    DDRB  &=  ((0<<PB2)|(0<<PB5));
    DDRD  &=  (0<<PD6);
    PORTB  =  (1<<PB2)|(1<<PB5);
    PORTD  =  (1<<PD6);
    DDRD  |=  (1<<PD1)|(1<<PD2)|(1<<PD4)|(1<<PD5);
    PORTD    &=  ((0<<PD1)|(0<<PD2)|(0<<PD4)|(0<<PD5));

      NOP();                          // wait until inputs sampled
    _delay_us(20);
      if(!(PIND & (1<<PIND6)))    // if row 1 = low
    {
         row = 5;
      }
      else if(!(PINB & (1<<PINB2)))  // if row 2 = low
    {
          row = 9;
      }
      else if(!(PINB & (1<<PINB5)))  // if row 3 = low
    {
          row = 13;
      }
    }                                   // 0 = no key

  return KeyMap [row - col];
}

int main (void)
{
  DDRC = 0xFF;            
  while(1)
  {
    PORTC = keyscan();
  }
}


Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?...
http://www.mikrocontroller.net/forum/codesammlung?...

=>

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

Autor: Guido Scheidat (flintstone)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: H. G. (ledi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das war auch der Fehler!
Die Register vom Port D wurden immer überschrieben.

Autor: Heiko W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Ist in dem oben aufgeführten C-Code die Tasten-Entprellung schon 
mitberücksichtigt?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.