- LiTime Speicher und Akkus         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: 4*4 Tastatur (Matrix) an tiny2313

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    14.03.2008
    Ort
    Oldenburg
    Beiträge
    84

    4*4 Tastatur (Matrix) an tiny2313

    Anzeige

    Praxistest und DIY Projekte
    HI
    habe mir gedacht, ich hänge jetzt mal eine alte 4*4 Matrix Tastatur an meinen Tiny2313 und gebe die Zeichen dann mit der LCD Library von Peter Fleury auf meinem Disply aus.

    Meine ersten Überlegungen:
    Ich habe gehört, dass man diese Tastaturen mit einer Schleife Zeile für Zeile abfragen muss. Also habe ich mir folgendes überlegt.
    Ich lege die 4 Zeilen auf jeweils einen Pin des Tinys (mit 470ohm Widerstand) und definiere sie als Ausgang. Das selbe mach ich mit den 4 Spalten und definiere sie als Eingang.
    Jetzt setze ich zu Anfang der Abfrage die erste Zeile auf high und die anderen Zeilen auf low. Jetzt überprüfe ich ob an einem der Eingänge (Spalten) ein high Signal ankommt. Ist dies der Fall, kann ich das zeichen zuordnen und gebe es auf meinem Display aus. Sonst setze ich die Spalte auf low, setze die nächste auf high und schaue ob dort ein Eingang auf high schaltet.
    So durchlaufe ich dann die Tastatur (die ganze Zeit).

    Funktioniert das so? oder gibt es da noch Tipps oder bessere Ansätze?
    Danke
    Achja, nachdem der Ansatz fertig ist mache ich mich an den Code und liefere ihn zur überprüfung nach (optimale vorgehensweise, fehler usw)

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Das grundsätzliche Prinzip stimmt. Im Detail aber verbesserungswürdig.

    Jetzt setze ich zu Anfang der Abfrage die erste Zeile auf high und die anderen Zeilen auf low.
    Würde ich auf keinen Fall so machen. Wenn es nämlich eine sehr einfache Matrix ohne Dioden ist, kannst du dann durch Drücken von zwei Tasten sehr leicht einen Kurzschluss zwischen einem High- und einem Low-Ausgang produzieren. Deine Serienwiderstände verhindern dann zwar Schlimmeres, aber du hast an den Spalteneingängen keinen eindeutigen Pegel mehr.
    Besser:
    Alle Zeilenausgänge standardmäßig hochohmig (also als Eingang konfigurieren), und dann immer nur eine Zeile zur Zeit auf Ausgang stellen.

    Noch zu beachten:
    An den Spalteneingängen brauchst du zwingend Pull-Up/Down-Widerstände, weil die Eingänge ohne gedrückte Taste sonst "in der Luft hängen" würden.

    Wie ich es machen würde:
    Serienwiderstände an den Ausgängen weglassen. An den Eingängen die internen Widerstände nutzen. Da das Pull-Ups sind, muss der eine "eingeschaltete" Ausgang auf Low sein, und die Eingänge sind dann auch auf Low zu prüfen.
    MfG
    Stefan

  3. #3
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Nachtrag:

    So durchlaufe ich dann die Tastatur (die ganze Zeit).
    Auch das würde ich so nicht machen. Zum Entprellen der Tasten wäre es das Beste, die Tastenabfrage nicht die ganze Zeit durchlaufen zu lassen, sondern nur in größeren Zeitabständen (z.B. alle 50 ms).
    MfG
    Stefan

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    14.03.2008
    Ort
    Oldenburg
    Beiträge
    84
    danke für deine hilfe
    macht sinn, allerdings glaube ich, dass cih noch nicht alles genau verstanden habe

    daher nochmal:
    So, ich schalte erstmal alle meine Zeilen auf Eingang (ohne Widerstände), dann meine Spalten auch auf Eingang (mit internen Widerständen).
    Nun fängt meine Schleife an und es wird die erste Zeile zuerst auf Ausgang und low gesetzt, wenn nun eine Taste gedrückt wird bekomme ich einen low auf dem "geschalteten" Eingang und kann so meine Taste identifizieren.
    Sonst schalte ich die Zeile wieder auf Eingang und die nächste auf Ausgang.

    So habe ich es jetzt verstanden, allerdings bin ich ein bisschen irritiert, da ja nirgends Strom fließt
    danke nochmals

  5. #5
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    So habe ich es jetzt verstanden,
    Jap, genau so.

    allerdings bin ich ein bisschen irritiert, da ja nirgends Strom fließt
    Aber klar doch. Bei gedrückter Taste fließt Strom von VCC über den internen Pull-Up des Spalteneingangs in den Low-Zeilenausgang hinein nach GND.
    MfG
    Stefan

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    14.03.2008
    Ort
    Oldenburg
    Beiträge
    84
    okay danke

    jetzt habe ich dazu mal einen Code aufgesetzt
    die Spalten sind PD0 bis PD3 und die Zeilen sind PD4 bis PD6 (momentan nur 4*3 Matrix)

    wäre nett, wenn da mal jemand drüberschaut (noch nicht getestet, compiliert aber fehlerfrei)
    vllt fällt ja was auf oder es gibt vorschläge zur optimierung

    Code:
    void tastaturabfrageLow()
    {
    	DDRD = 0x00; 									/* PD als Eingaenge */
    	//DDRA &= ~(1<<PA1) ;  							
    	PORTD |= (1<<PD4) | (1<<PD5) | (1<<PD6);      /* Interne Pull-Up einschalten */
    	//PORTA |= (1<<PA1);
    	
    	while(1)
    	{
    		//Zeile A
    		DDRD &= ~( 1 << DDD3 );			//alten Ausgang wieder auf Eingang schalten
    		PORTD |= (1<<PD3);					//Widerstand aktivieren
    		DDRD = (1 << DDD0);				//neuen Ausgang definieren
    		PORTD &= ~(1<<DDD0);				//neuen Ausgang auf low schalten
    		
    		if ( !(PIND & (1<<PINB4)) ) 		// Spalte 1 prüfen
    		{
    		lcd_clrscr();
            lcd_puts("7");
    		}
    		if ( !(PIND & (1<<PINB5)) ) 		// Spalte 2 prüfen
    		{
    		lcd_clrscr();
            lcd_puts("8");
    		}
    		if ( !(PIND & (1<<PINB6)) ) 		// Spalte 3 prüfen
    		{
    		lcd_clrscr();
            lcd_puts("9");
    		}	
    
    		//Zeile B
    		DDRD &= ~( 1 << DDD0 );			//alten Ausgang wieder auf Eingang schalten
    		PORTD |= (1<<PD0);					//Widerstand aktivieren
    		DDRD = (1 << DDD1);				//neuen Ausgang definieren
    		PORTD &= ~(1<<DDD1);				//neuen Ausgang auf low schalten
    		
    		if ( !(PIND & (1<<PINB4)) ) 		// Spalte 1 prüfen
    		{
    		lcd_clrscr();
            lcd_puts("4");
    		}
    		if ( !(PIND & (1<<PINB5)) ) 		// Spalte 2 prüfen
    		{
    		lcd_clrscr();
            lcd_puts("5");
    		}
    		if ( !(PIND & (1<<PINB6)) ) 		// Spalte 3 prüfen
    		{
    		lcd_clrscr();
            lcd_puts("6");
    		}		
    		
    		//Zeile C
    		DDRD &= ~( 1 << DDD1 );			//alten Ausgang wieder auf Eingang schalten
    		PORTD |= (1<<PD1);					//Widerstand aktivieren
    		DDRD = (1 << DDD2);				//neuen Ausgang definieren
    		PORTD &= ~(1<<DDD2);				//neuen Ausgang auf low schalten
    		
    		if ( !(PIND & (1<<PINB4)) ) 		// Spalte 1 prüfen
    		{
    		lcd_clrscr();
            lcd_puts("1");
    		}
    		if ( !(PIND & (1<<PINB5)) ) 		// Spalte 2 prüfen
    		{
    		lcd_clrscr();
            lcd_puts("2");
    		}
    		if ( !(PIND & (1<<PINB6)) ) 		// Spalte 3 prüfen
    		{
    		lcd_clrscr();
            lcd_puts("3");
    		}	
    		
    		//Zeile D
    		DDRD &= ~( 1 << DDD2 );			//alten Ausgang wieder auf Eingang schalten
    		PORTD |= (1<<PD2);					//Widerstand aktivieren
    		DDRD = (1 << DDD3);				//neuen Ausgang definieren
    		PORTD &= ~(1<<DDD3);				//neuen Ausgang auf low schalten
    		
    		if ( !(PIND & (1<<PINB4)) ) 		// Spalte 1 prüfen
    		{
            lcd_puts("0");
    		}
    		if ( !(PIND & (1<<PINB5)) ) 		// Spalte 2 prüfen
    		{
            lcd_puts(".");
    		}
    		if ( !(PIND & (1<<PINB6)) ) 		// Spalte 3 prüfen
    		{
    		lcd_clrscr();
    		}	
    	}
    }
    lcd_puts() und lcd_clrscr() sind von der LCD lib

    Danke

  7. #7
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    In die Funktion eine Endlosschleife zu legen ist keine so gute Idee. Du bist sehr viel flexibler, wenn die Funktion nur einmal die Tasten abfragt. Wenn das dann unbedingt in einer ungebremsten Endlosschleife geschehen soll, dann lege sie außen rum, also z.B. in main:
    Code:
    while (1)
        tastaturabfrageLow();
    Ich weise allerdings nochmal darauf hin, dass du so einige Probleme mit prellenden Tasten haben wirst. Außerdem beinhaltet dein Programm im Augenblick ein sehr schnelles Autorepeat (zusätzlich zum Prellen). Also Taste 7 einmal kurz gedrückt und gleich 10mal (oder so) eine '7' auf dem Display.

    Da ich eigentlich gerade Lust zum Programmieren habe, mache ich mir mal ein paar Gedanken und vielleicht später dann einen Alternativvorschlag.
    MfG
    Stefan

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    14.03.2008
    Ort
    Oldenburg
    Beiträge
    84
    danke
    sehr nett von dir

    habe den gerade getestet, läuft super

    allerdings muss ich die taste kurz über 1 sek gedrückt halten bis die zahl auf dem bildschirm erscheint

    liegt aber wohl dadran, dass ich in jeden spaltenwechsel 2 delays von 20ms eingefügt habe

  9. #9
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Also Taste 7 einmal kurz gedrückt und gleich 10mal (oder so) eine '7' auf dem Display.
    Sorry, stimmt natürlich nicht, da du jedesmal das LCD löscht.

    liegt aber wohl dadran, dass ich in jeden spaltenwechsel 2 delays von 20ms eingefügt habe
    Falscher Platz für Delays.
    MfG
    Stefan

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    14.03.2008
    Ort
    Oldenburg
    Beiträge
    84
    hatte ich bei den punkten und der 0 aber auch nicht
    und die wurden nicht gelöscht

    auf jeden fall wollte ich gerade eine version ohne delays und lcd löschvorgang testen

    mal schauen

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus