Forum: Mikrocontroller und Digitale Elektronik Matrixtastatur in Assembler


von Martin Nopper (Gast)


Lesenswert?

hallo,
ich habe mit zwei leuten in der schule ein projekt begonnen. die idee
war ein kleiner taschenrechner mit einem ATMEL µC (AT89S8252) einem
2x16 LCD display, und einer matrixtastatur als zahleneingabe (3x4), die
rechenzeichen (+-*/) sollen über 4 taster eingegeben werden. mit dem lcd
display kommen wir schon ganz gut klar, auf die taster mit dem
entsprechenden rechenzeichen zu reagieren werden wir auch noch
hinbekommen, aber für die matrixtastatur finden wir keine lösung.

die tastatur ist Low Aktiv, mit den bekannten 4 ausgängen, und 3
eingängen, aber wie bekomme ich aus den kombinationen die entsprechende
zahl, also die zuordnung.
die programmierung müsste in Assembler sein

wenn jemand ein beispielproramm zum auslesen einer solchen tastatur
hätte wäre ich extrem dankbar.


vielen dnak bereits jetzt

von Andi (Gast)


Lesenswert?

Hi!

Mit 3x4 (12) Tasten kommst Du nicht hin wenn es eine reine
Matrix-Tastatur sein soll.
Da brauchst Du schon 4x4 (16) Tasten für den Rechner.
Also 10 (0 - 9) + 4 (+, -, * und /) und 2 (C und AC).

Angesteuert wird das dann über einen kompletten 8Bit-Port.
An Pin 0 - 3 die Zeilen der Matrix und an 4 - 7 die Spalten
anschließen.

   0-1-2-3-------
   | | | |       |
   4-5-6-7-----  |
   | | | |     | |
   8-9-A-B---  | |
   | | | |   | | |
   C-D-E-F-  | | |
   | | | | | | | |
   | | | | | | | |
   7 6 5 4 3 2 1 0

Pin 0 - 3 als Input mit Pullups und Pin 4 - 7 ohne Pullups einstellen.
Evtl. an den Pins 4 - 7 Pulldown-Widerstände anschließen damit die Pins
0 - 3 low werden bei Tastendruck.
Wird keine Taste gedrückt hat der Port den Binär-Wert 00001111.
Drückt man nun z. B. die Taste "6" wird Pin 1 low und Pin 5 high und
man liest 00101101 aus dem Port aus.
A = 00101011
8 = 10001011
3 = 00011110
usw...
Der Port sollte dann zyklisch alle paar Millisekunden abgefragt werden.
In der Main die Tastenauswertung Keycode -> ASCII machen.

MfG
Andi

von ...HanneS... (Gast)


Lesenswert?

Ich würde sie multiplexen.
Z.B. die Zeilen als Ausgang, die Spalten als Eingang.
Reiherum eine der 4 Zeilen auf L, die anderen auf H, dann durch
Einlesen der Spalten prüfen, ob eine Taste dieser Zeile gedrückt war.

Die Tasten sollten auch mit Dioden entkoppelt sein.

...

von Andi (Gast)


Lesenswert?

Wieso Multiplexen?
Ist doch bei den paar Tasten nicht nötig mit Pullups an den Zeilen und
Pulldowns an den Spalten.
Multiplexen würde ich erst ab einer gewissen Anzahl von Tasten mit
einem externen Schiebebaustein oder Decoder (4 Bit auf 16).
Klar, man könnte jetzt mit nur einer Leitung und einem Transistor und
etwas anders verschaltet die Anzahl der Tasten verdoppeln.
Das einfache, obige Beispiel verwenden heutzutage die
Keyboardcontroller in PC-Keyboards und Notebooks.
Die haben halt dann 22 Leitungen, 11 x 11 = 121 Tasten.

MfG
Andi

von Peter D. (peda)


Lesenswert?


von ...HanneS... (Gast)


Lesenswert?

Ich meinte keine Schieberegister oder andere externe Hardware. Das würde
doch nur die Schaltung (Platine) unnötig verkomplizieren.

Ich meinte das Aktivieren jeweils einer Zeile (L) und das darauf
folgende Einlesen der Spalten. Und das reiherum. Und Dioden nur, wenn
die Tasten metallische Kontakte haben. Bei Gummimatten sind diese nicht
unbedingt erforderlich, da der Tastenwiderstand zu hoch ist um einen
Kurzschluss der als Ausgang geschalteten Ports zu bewirken.

Wenn ich alle 8 Pins der Matrix als Eingänge sehe, dann gibt es keine
sauberen Pegel. Bei Pull-Ups an den Zeilen und Pull-Downs an den
Spalten würde bei gedrückter Taste eine Reihenschaltung aus Pull-Up und
Pull-Down (über geschlossene Taste) entstehen, also ein Spannungsteiler,
der beiden Portpins weder H noch L liefert, sondern irgendwas
dazwischen. Dies soll nun der Zeilenpin als L erkennen, der Spalten-Pin
aber als H (beide sind ja bei geschlossenem Taster identisch)? Das kann
ich nicht nachvollziehen.

Ich bin ziemlich sicher, dass auch bei einer PC-Tastatur die Matrix
zeilenweise (oder spaltenweise) abgefragt wird. Dabei wird eine Seite
der Matrix (also Zeile oder Spalte) als Ausgang geschaltet, die andere
Seite als Eingang eingelesen. Und die Ausgänge erhalten ein Bitmuster,
bei dem immer nur ein Pin L ist, die anderen sind H.

So war es schon beim Homecomputer Commodore Plus/4 (8x8-Matrix) und
beim PC wird es auch nicht anders sein, da das die effektivste Lösung
ist, eine Tastenmatrix einzulesen.

Gruß...
...HanneS...

von Peter D. (peda)


Lesenswert?

@...HanneS...

die 8051-er haben open drain Ausgänge, da brauchts keine Dioden.

Aber auch andere µCs (AVR) können open drain Ausgänge realisieren,
indem man nur das DDRx-Bit umschaltet und das PORTx-Bit konstant low
läßt.


Peter

von Andi (Gast)


Lesenswert?

@Hannes: Ich habe die Erfahrung gemacht, das ein Pin als Input mit
Pullup auch als Ausgang mit Hi-Pegel gesehen werden kann.
Die internen Pullups im AVR haben einen Widerstand von ca. 36KOhm
(137µA bei 5V).
Wird dieser Strom über einen gedrückten Taster, Pulldown (evtl. 40KOhm)
und hochohmigen Input-Pin ohne Pullup weggeleitet geht der Input-Pin mit
Pullup auf low und wegen dem höheren Pulldown auf GND bleibt am
hochohmigen Input-Pin noch genügend für eine high-Erkennung übrig.

MfG
Andi

von ...HanneS... (Gast)


Lesenswert?

@Peter:

Danke für die Hinweise.

Da ich recht langsam lese und schreibe, habe ich deinen Beitrag erst
hinterher gesehen. Mit 8051 kenne ich mich zwar nicht aus, aber ich
konnte sehen, dass die Matrix in Ausgänge und Eingänge aufgeteilt ist,
was ja der "springende Punkt" der Diskussion ist.

Dass man die AVR-Ports als open-drain nutzen kann ist mir bekannt.
Jedoch nutz das nix wenn bei Anfängern die Gefahr der Programmierfehler
besteht. ;-)
Außerdem gibt es gelegentlich billige Taster mit eingebauter Diode.

Eine 3x4-Matrix-Tastatur kombiniert mit einer dreistelligen
7-Segmentanzeige (LED-Didplay) funktioniert bei mir auf einem AT90S1200
wunderbar. Heute weiß ich, dass ich mit einer 2x6-Matrix noch einen Pin
gespart hätte, aber dann hätte man keine (optionale) fertige
Folientastatur benutzen können. Die Tastenabfrage ist in den
Multiplexzyklus der Anzeige integriert.

Beste Grüße...
...HanneS...

von ...HanneS... (Gast)


Lesenswert?

@Andi:

Ich halte das für Quick&Dirty, das kann vielleicht funktionieren, muss
aber nicht. Darauf würde ich mich nicht verlassen. Digitalen Eingängen
gebe ich lieber definierte H- oder L-Pegel.

Gruß...
...HanneS...

von Andi (Gast)


Lesenswert?

Und was macht der Pulldown an dem Eingangs-Pin (Spalte) wenn die Taste
nicht gedrückt wird?
Er zieht den Pin "definitiv" auf GND.
Genau so am Ausgangs-Pin der Pullup.
Der hält den Pin bei nicht drücken sauber auf +5V.

Mittels Bitmasken-Vergleich und Ringbuffer müßte Softwaretechnisch auch
das erkennen mehrerer, gleichzeitig gedrückter Tasten machbar sein.

MfG
Andi

von ...HanneS... (Gast)


Lesenswert?

Ja sicher, bei losgelassener Taste gibt es saubere Pegel. Bei gedrückter
Taste aber nicht, da gibt es für beide Pins den Wert des
Spannungsteilers, im Idealfall Vcc/2. Dies soll nun 1 Pin als H
erkennen, der andere als L. Mag ja sein, dass das funktioniert, wenn
der eine Pin den Pull-Up aktiviert hat, der andere nicht (und externen
Pull-Down). Ich werde es aber auf diese Weise nicht tun und auch
niemandem empfehlen.

Beste Grüße...
...HanneS...

von Andi (Gast)


Lesenswert?

@Hannes: Lang hats gedauert aber jetzt hab ich´s begriffen.
Habe das obige Beispiel von mir in Multisim aufgebaut, mit Pullups und
Pulldowns, und es läuft kacke (sorry für den Ausdruck).
Also, das untere Nibble als Ausgang low-aktiv.
Das obere Nibble als Eingang. Zur Stabilisierung mit internen (oder
externen) Pullups.
Im Timer dann Ausgang 3 auf low, alle anderen auf high.
Ist Eingang 0 (Bit 4) low ist die Taste F gedrückt.
Ist Eingang 3 (Bit 7) low ist die Taste C gedrückt.
Im nächsten Timer Ausgang 3 high und Ausgang 2 low (2. Zeile von
unten).
Ist Eingang 1 (Bit 5) low ist die Taste A gedrückt.
Ist Eingang 2 (Bit 6) low ist die Taste 9 gedrückt.
Und so weiter...
Und das ganze bei 4 Spalten mit einem Timer von 400Hz (4 Zeilen * 100
Abfragen/Sekunde).
Da müßte eine Entprellung von 10mS inklusive sein wenn ich das richtig
sehe?
Und wenn man mehrere Tasten gleichzeitig gedrückt erfassen möchte läßt
sich das mit 4 Bitprüfungen (And-Verknüpfungen + Zeilen-Nibble) je
Timer-Durchlauf erfassen.

Gedanklicher Ablauf:

Timer-ISR:
 Tastenport einlesen
 Gedrückte Tasten einer Zeile herausfiltern
 Ausgang umschalten (Schieberegister mit einer einzigen 0 im Ausgang-
 Nibble nach rechts über Carry schieben, Bit 3 erhält den Wert des
 Carry-Bit)
Timer-Ende

MfG
Andi

von Andi (Gast)


Lesenswert?

@Peter: In Deinem Beispiel hast Du mit 4 Zeilen nur 3 an den µC
angeschlossen und eine Zeile permanent mit GND verbunden (Zeile 0).
Wenn man nun Zeile 1 bis 3 auf high setzt können es nur Tasten in Zeile
0 sein, die gedrückt werden, klar.
Aber wie ist das, wenn Zeile 1 abgefragt wird und in Spalte 0/Zeile 1
und in Spalte 1/Zeile 1 eine Taste gedrückt wird?
Meint der µC nicht dann, das diese beiden Tasten in Zeile 1 gedrückt
werden?

MfG
Andi

von Andi (Gast)


Lesenswert?

Grrrr....
Also nochmal:
@Peter: Aber wie ist das, wenn Zeile 1 abgefragt wird und in Spalte
0/Zeile 0 und in Spalte 1/Zeile 1 eine Taste gedrückt wird?
Meint der µC nicht dann, das diese beiden Tasten in Zeile 1 gedrückt
werden?

MfG
Andi

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.