Pfad: Home => AVR-DE => Anwendungen => Schalter und Tasten am ADC => Tastenfelder   This page in English: Flag EN Logo
Tastenfeld Anwendungen von
AVR-Einchip-Mikrokontrollern AT90S, ATtiny, ATmega und ATxmega
Tastenfelder an einem ADC-Eingang

Anschluss einer 12-er-Tastatur an einen AVR

Diese Seite zeigt, wie eine handelsübliche 12-er-Tastatur an einen AVR angeschlossen und per Assembler-Software ausgelesen werden kann. Die Abschnitte:
  1. Funktionsweise der Tastatur
  2. AVR: I/O-Anschlussmatrix einzeln
  3. AVR: Anschluss an einen ADC mit Widerstands-Matrix

1. Funktionsweise der Tastatur

12-er-Tastatur-Matrix 12-er-Tastaturen sind Schalter, die über eine Matrix von Zeilen (Rows) und Spalten (Columns) miteinander verbunden sind. Wird die Taste "1" gedrückt, dann ist die Spalte 1 mit der Zeile 1 verbunden, ist "2" gedrückt, dann Spalte 2 mit Reihe 1, usw..

Irgendeine Taste feststellen Um herauszufinden, ob irgendeine der 12 Tasten gedrückt ist, würde es reichen, die drei Spalten mit Null Volt zu verbinden und die vier Zeilen zu verbinden und über einen Pull-Up-Widerstand von z.B. 10 kΩ mit Plus zu verbinden. Der Output hat ohne gedrückte Taste Plus-Potential. Jede gedrückte Taste bewirkt dann, dass der Output auf Null Volt gezogen wird.

Um auch noch fest zu stellen, welche der 12 Tasten gedrückt ist, wären z.B. nacheinander die drei Spaltenanschlüsse auf Null Volt zu bringen (die beiden anderen jeweils auf Plus) und das Ergebnis an den vier Zeilenanschlüssen abzulesen. Ist einer der vier Zeilenanschlüsse auf Null, muss die Maschinerie anhalten und den aktuellen Spaltenanschluss sowie das Ergebnis der Zeilenanschlüsse in den Code einer gedrückten Taste umwandeln. Etwa so:
SpalteZeileTaste
Spalte 1Spalte 2Spalte 3Zeile 1Zeile 2 Zeile 3Zeile 4ZeichenBinärcode
0001111 (Keins)1111
0110111 10001
1010111 20010
1100111 30011
0111011 40100
1011011 50101
1101011 60110
0111101 70111
1011101 81000
1101101 91001
0111110 *1010
1011110 00000
1101110 #1011
Um eine solche Tastatur mit diskreten Bauteilen auslesbar zu machen, braucht es mindestens: Oder ein fertiges IC, das das alles macht (aber das man gar nicht im Versandhandel kriegt). Oder eben einen Mikrokontroller.

An den Seitenanfang

2. AVR: I/O-Anschlussmatrix einzeln

Tastaturmatrix an I/O-Port Eine Tastaturmatrix kann so direkt und ohne weitere Bauteile an einen Mikrokontroller angeschaltet werden.

Im Beispiel sind dies die unteren sieben I/O-Pins des Ports B. Andere Ports lassen sich ebenso verwenden.

Die Portpins PB4..PB6 werden als Ausgänge definiert und liefern die Spalten-Nullen. Die Portpins PB0..PB3 dienen zum Einlesen der Zeilenergebnisse. Die Pull-Up-Widerstände der Ports PB0..PB3 werden per Software zuschaltet (DDRn = 0, PORTn = 1), externe Widerstände sind unnötig.

Das folgende Software-Beispiel zeigt zunächst das Initiieren der Ports. Sie wird nur ein Mal zu Beginn des AVR-Programms ausgeführt.

2.1 Init-Routine


;
; Init Keypad-I/O
;
.DEF rmp = R16 ; ein Hilfsregister definieren
; Ports definieren
.EQU pKeyOut = PORTB ; Ausgabe und Pull-Ups
.EQU pKeyInp = PINB  ; Tastatur lesen 
.EQU pKeyDdr = DDRB  ; Datenrichtungsregister
; Init-Routine
InitKey:
	ldi rmp,0b01110000 ; Datenrichtungsregister
	out pKeyDdr,rmp    ; des Keyports setzen
	ldi rmp,0b00001111 ; Pull-Up-Widerstände
	out pKeyOut,rmp    ; an den Eingängen 

2.2 Tastendruck feststellen

Die folgende Routine stellt zunächst fest, ob irgendeine der Tasten gedrückt ist. Sie wird im Programmverlauf regelmäßig wiederholt, z.B. in einer Verzögerungsschleife oder Timer-gesteuert.

;
; Check any key pressed
;
AnyKey:
	ldi rmp,0b00001111 ; PB4..PB6=Null, pull-Up-Widerstände
	out pKeyOut,rmp    ; an den Eingängen PB0..PB3
	in rmp,pKeyInp     ; Tastaturport lesen
	ori rmp,0b11110000 ; alle oberen Bits auf Eins
	cpi rmp,0b11111111 ; alle Bits = Eins?
	breq NoKey         ; ja, keine Taste gedrückt

2.3 Gedrückte Taste feststellen

Ist irgendeine der Tasten gedrückt, ist jetzt der Auslesevorgang am dransten. Nacheinander werden PB6, PB5 und PB4 Null gesetzt und PB0..PB3 auf Nullen geprüft. Das Registerpaar Z (ZH:ZL) zeigt dabei auf eine Tabelle mit den Tastencodes. Es zeigt am Ende auf den identifizierten Tastencode, der mit der Instruktion LPM aus dem Flash-Memory in das Register R0 gelesen wird.

;
; Identifiziere gedrueckte Taste
;
ReadKey:
	ldi ZH,HIGH(2*KeyTable) ; Z ist Zeiger auf Tastencode
	ldi ZL,LOW(2*KeyTable)
	; read column 1
	ldi rmp,0b00111111 ; PB6 = 0
	out pKeyOut,rmp
	in rmp,pKeyInp ; lese Zeile
	ori rmp,0b11110000 ; obere Bits maskieren
	cpi rmp,0b11111111 ; ein Key in dieser Spalte?
	brne KeyRowFound ; Spalte gefunden
	adiw ZL,4 ; Spalte nicht gefunden, Z vier Keys weiter
	ldi rmp,0b01011111 ; PB5 = 0
	out pKeyOut,rmp
	in rmp,pKeyInp ; wieder Zeile lesen
	ori rmp,0b11110000 ; obere Bits maskieren
	cpi rmp,0b11111111 ; ein Key in dieser Spalte?
	brne KeyRowFound ; Spalte gefunden
	adiw ZL,4 ; Spalte nicht gefunden, Z vier Keys weiter
	ldi rmp,0b01101111 ; PB4 = 0
	out pKeyOut,rmp
	in rmp,pKeyInp ; letzte Zeile lesen
	ori rmp,0b11110000 ; obere Bits maskieren
	cpi rmp,0b11111111 ; ein Key in dieser Spalte?
	breq NoKey ; wider Erwarten auch hier nicht gefunden
KeyRowFound: ; Spalte ist gefunden, identifiziere Zeile
	lsr rmp ; schiebe Bit 0 in das Carry-Flag
	brcc KeyFound
	adiw ZL,1 ; zeige auf naechsten Tastencode
	rjmp KeyRowFound ; weiter schieben
KeyFound:
	lpm ; lese keycode nach R0
	rjmp KeyProc ; hier weiter mit Key-Verarbeitung
NoKey:
	rjmp NoKeyPressed ; keine Taste gedrueckt
;
; Tabelle fuer Code Umwandlung
;
KeyTable:
.DB 0x0A,0x07,0x04,0x01 ; Erste Spalte, Tasten *, 7, 4 und 1
.DB 0x00,0x08,0x05,0x02 ; Zweite Spalte, Tasten 0, 8, 5 und 2
.DB 0x0B,0x09,0x06,0x03 ; Dritte Spalte, Tasten #, 9, 6 und 3

2.4 Entprellen

In den Routinen KeyProc und NoKeyPressed muss natürlich noch ein Entprellen der Tasten erfolgen. Also z.B. muss in der KeyProc-Routine eine Tastenoperation erst dann ausgeführt werden, wenn die gleiche Taste 50 Millisekunden lang gedrückt ist. In der NoKeyPressed-Routine kann der dazu verwendete Zähler zurück gesetzt werden. Da das Timing der Entprellung auch noch von anderen Bedürfnissen abhängig sein kann, ist es hier nicht eingearbeitet.

2.5 Hinweise, Nachteile

In den Software-Beispielen ist zwischen der Ausgabe der Spalten-Adresse und dem Einlesen der Zeilen-Information nur ein Takt Zeit gelassen. Bei hohen Taktfrequenzen und/oder langen Leitungen zwischen Tastatur und Prozessor ist es notwendig, zwischen den Out- und In-Instruktionen mehr Zeit zu lassen (z.B. durch Einfügen von NOP-Instruktionen).
Die internen Pull-Ups liegen bei Werten um 50 kΩ. Bei langen Leitungen und in hoch feldverseuchter Umgebung (bei Funkamateurs zu Hause) kann es unter Umständen zum Fehlansprechen der Tastatur kommen. Wer es weniger sensibel haben will, kann noch externe Pull-Ups dazu schalten.

Der Nachteil der Schaltung ist, dass sie sieben Port-Leitungen exklusiv benötigt. Die Lösung über einen AD-Wandler-Kanal und ein Widerstands-Netzwerk (Abschnitt 3) ist da viel sparsamer.


An den Seitenanfang

3. Anschluss an einen ADC mit Widerstands-Matrix

Die meisten Tiny- und Mega-AVR-Typen haben heutzutage AD-Wandler an Bord. Sie sind daher ohne größere Klimmzüge dazu in der Lage, Analogspannungen zu messen und mit bis zu 10 Bits Genauigkeit aufzulösen (Genauigkeit ca. 1 Promille). Wer also I/O-Ports sparen will (oder muss), muss die Tastatur nur dazu bringen, ein Analogsignal zu liefern. Das macht z.B. eine Widerstandsmatrix.

3.1 Widerstandsmatrix

Tastenfeld mit Widerstandsmatrix Hier ist eine solche Widerstandsmatrix abgebildet. Die Spalten sind über drei Widerstände auf Masse geführt, die Zeilen über vier Widerstände auf die Betriebsspannung (z.B. 5V). Der AD-Wandler-Eingang ist noch mit einem Folienkondensator von 1 nF abgeblockt, da der ADC absolut keine Hochfrequenz mag, die da über die Tasten, die Widerstände und die Zuleitungen eingestreut werden könnte.
Wird jetzt z.B. die Taste "5" gedrückt, dann entsteht ein Spannungsteiler: Bei 5 Volt Betriebsspannung gelangen dann

UADC = 5 * 1,82 / (1,82 + 4,16) = 1,522 Volt

an den AD-Wandler-Eingang. Rechnen wir noch 5% Toleranz der Widerstände mit ein (jeweils nach unten und oben), dann liegt die Spannung irgendwo zwischen 1,468 und 1,627 Volt. Der AD-Wandler macht daraus bei 5 V Betriebs- und Referenzspannung einen Wert zwischen 300 bis 333. Verwenden wir nur die oberen 8 Bit des AD-Wandler-Ergebnisses (Teilen durch vier oder Linksjustieren des Wandlers), gibt das 74 bis 78.

3.2 Spannungswerte der Widerstandsmatrix

Die Matrix verwendet Widerstände der E12-Reihe, die überall erhältlich sind. Daher rühren einerseits die krummen Werte.

Die unterschiedlichen Widerstandswerte, aus denen die Matrix aufgebaut ist, resultieren aus der Anforderung, dass die Spannungen, die sich aus der Teilung ergeben, den verfügbaren Spannungsbereich mögklichst gleichmäßig auf die zwölf Tasten verteilen sollen, so dass sich für jede Taste eine spezifische Spannung ergibt, die möglichst viel Abstand zur nächsten und vorherigen Taste aufweist. Die hier verwendeten Widerstandswerte machen dies.

Noch ein Hinweis für diejenigen, die immer glauben, die Welt lasse sich mit ein paar wenigen Formeln beschreiben und Herumprobieren sei unnötig: an diesem Problem werdet Ihr Euch die Zähne gehörig ausbeißen. 12 Unbekannte, und die auch noch ausschließlich aus der E12-Reihe, und dann noch 5% Toleranz, das dürfte auch den gewieftesten Formelcracker in die Verzweiflung treiben.

Hier ist die Tabelle für die Matrix mit den dargestellten Widerstandswerten. In der ersten Spalte die gedrückte Taste, in der zweiten Spalte der Widerstandswert, der sich nach Masse hin ergibt. In der dritten Spalte der Widerstandswert, der sich nach Plus ergibt.

Die Spannung, die aus den jeweiligen Teilern resultiert, ergibt sich aus der Formel

U = Uref * RMasse / (RMasse + RPlus)


Da die käuflichen Widerstände eine Toleranz von +/-5% haben, muss noch die minimale und die maximale Spannung berechnet werden. Das Minimum ergibt sich, wenn die Widerstände nach Masse alle 5% unter ihrem Nominalwert liegen und gleichzeitig alle Widerstände nach Plus 5% über ihrem Nominalwert haben. Das ist zwar nicht realistisch, aber wir wollen ja nicht alle Widerstände einzeln aussuchen und bei Sommer- und Wintertemperaturen ausmessen.
WiderstandsteilerSpannungenADC-Wandlerwerte
TasteWiderstand
nach Masse
Ohm
Widerstand
nach Plus
Ohm
U Nominell
@5V
U Min
@5V
U Max
@5V
N Nom
@8Bit
N Min
@8Bit
N Max
@8Bit
11000191600,2480,2250,273131114
21820191600,4340,3960,475222025
32820191600,6410,5880,700333036
4100041600,9690,8931,050504554
5182041601,5221,4181,630787284
6282041602,0201,9012,14210397110
710008602,6882,5632,812138131144
818208603,3963,2853,503174168180
928208603,8323,7403,919196191201
*10001804,2374,1704,300217213221
018201804,5504,5074,589233230235
#28201804,7004,6714,727241239243
Die den Tasten zugeordneten Spannungswerte mit den jeweiligen Toleranzbereichen sind in der Grafik dargestellt.

Spannungsbereiche

Wie zu sehen ist, macht sich die Toleranz der Widerstände nur bei den mittleren Tasten bemerkbar.

Ergänzt ist die Tabelle noch um diejenigen Werte, die sich beim Messen mit dem AD-Wandler ergeben. Da alle Wertebereiche ausreichend weit auseinander liegen, reicht dazu ein 8-Bit-Wandler.

12-er-Tastatur mit vertikalen Widerständen 16-er-Tastatur mit vertikalen Widerständen Diese beiden Schaltungen sind etwas anders gestrickt: die unteren vier Widerstände (im Bild links) an den vier Reihen der Tastatur sind gestapelt geschaltet, während die oberen drei bzw. vier Spalten über einzelne Widerstände nach Plus führen. Dasselbe Prinzip, nur addieren sich die oberen Widerstände nicht.

Näherung bei der 12-er-Tastatur Bei der 12-er-Tastatur ergeben sich mit 5%-E12-er Widerständen die gezeigten Näherungsergebnisse: es gibt keine Überlappungen und die Tastenreihung "147*2580369#" ist auch korrekt.

Die Spannungen bei der 12-er-Tastatur Und so sehen die Spannungen aller Tasten aus. Alles einigermaßen gleich verteilt, und die in der Mitte recht großen Toleranzbereiche liegen auch nirgends übereinander.

Die Spannungen bei der 16-er-Tastatur Und so sehen die Spannungen bei einer 16-er-Tastatur aus, bei der es nötig war, 1%-Widerstände zu verwenden, damit keine Überlappungen auftreten. Hier sind die Toleranzbereiche nur in der Mitte etwas größer, aber auch wesentlich weniger ausgeprägt als mit 5%.

Alle Grafiken hier wurden mit der Version 2.7 des AVR-Simulators
avr_sim angefertigt, der auch einen fortgeschrittenen Widerstandsmatrix-Berechner enthält.

3.3 Spannungswerte und Auswertung

Wie zu erkennen ist, gibt es bei der Verwendung von 5%-Widerständen und der dargestellten Widerstandskombination keine Überlappungen der Spannungsbereiche der einzelnen Tasten.

Wer andere Widerstandskombinationen ausprobieren möchte, kann mit der zugehöigen Tabelle herumspielen (im Open-Office-Format, im Excel-XP-Format). Hier gibt es ein komfortables Kommandozeilen-Programm, das das viel schöner erledigt, und hier gibt es sogar eine grafische Anwendung, die das noch viel schöner erledigt. Beide Programme können auch 4 * 4-Tastenfelder.

3.4 Hinweise zur AD-Wandler-Hardware

ATtiny-Typen bieten meist nur die Möglichkeit, eine intern erzeugte Konstantspannung oder die Betriebsspannung als Referenzspannung des AD-Wandlers zu wählen. Für die Tastaturschaltung kommt nur die Betriebsspannung als Referenzspannung infrage. Diese Option ist beim Initiieren des AD-Wandlers einzustellen.

Bei vielen ATmega-Typen kann auch eine extern erzeugte Referenzspannung verwendet werden, die am Pin AREF zugeführt wird. Verwendet man diese Möglichkeit, wäre auch die Tastaturschaltung aus dieser Referenz zu speisen. Verwendet man keine externe Referenzspannung, dann kommt für den Betrieb der Tastatur nur die Möglichkeit der Verwendung der Betriebsspannung als Referenzspannung infrage. In diesem Fall wird die Betriebsspannung per Software-Option intern an den AREF-Pin geführt, der externe AREF-Pin wird mit einem Folienkondensator von ca.10 nF abgeblockt.

ATmega-Typen bieten zur Erhöhung der Stabilität des AD-Wandlers ferner die Möglichkeit, diesen über den AVCC-Pin separat zu bespeisen. Für die Tastaturschaltung alleine kann dieser Pin direkt an die Betriebsspannung angeschlossen werden. Sollen auch noch andere Messungen veranstaltet werden, bei denen genauer gemessen werden soll, wird der AVCC-Pin über eine Drossel von 22 µH an die Betriebsspannung geführt und mit einem Keramikkondensator von 100 nF gegen Masse abgeblockt.

3.5 Initiieren und Lesen des AD-Wandlers

Zum Auslesen der Tastatur wird ein AD-Wandler-Kanal gebraucht. Der AD-Wandler wird zu Beginn eingestellt. Die beiden Beispiele zeigen den manuellen Einzelstart eines ATmega8 und den interrupt-gesteuerten Dauerstart bei einem ATtiny13.

3.5.1 ATmega8: manuell starten

Als erstes Beispiel ein ATmega8, ohne Interrupts, mit manuellem Start und Stop des AD-Wandlers. Das Tastatursignal liegt am AD-Kanal ADC0.

.DEF rKey = R15 ; Register fuer AD-Wert
.DEF rmp = R16 ; Vielzweck-Register
	; setze MUX auf Kanal 0, Linksjustieren, AREF auf AVCC
	ldi rmp,(1<<REFS0)|(1<<ADLAR) ; ADMUX Kanal 0, AREF auf AVCC
	out ADMUX,rmp
	; AD-Wandler einschalten, Wandlung starten, Teilerrate = 128
	ldi rmp,(1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)
	out ADCSRA,rmp
	; warten bis AD-Wandler fertig mit Wandlung ist
WaitAdc1:
	; ADSC-Bit abfragen, wenn Null ist Wandlung fertig
	sbic ADCSRA,ADSC ; Wandlung beendet?
	rjmp WaitAdc1 ; noch nicht
	; AD-Wandler-Wert MSB lesen
	in rKey,ADCH
	; AD-Wandler wieder abschalten
	ldi rmp,(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) ; ADC aus
	out ADCSRA,rmp
Man beachte, dass diese eine Wandlung 25 * 128 Takte dauert, also bei 1 MHz Prozessortakt 3,2 Millisekunden. Das macht man nur, wenn sonst nichts Wichtiges anderes zu tun ist als im Kreis herum zu laufen.

3.5.2 ATtiny13: Autostart AD-Wandlung, Interrupt-gesteuert

Ja, auch ein ATtiny13 kann unsere Tastaturmatrix einlesen (das wäre mangels Pins bei der Einzelbedrahtung gar nicht möglich).

Eine typische Routine hierfür wäre für den ATtiny13 beispielsweise die folgende Sequenz, bei der ADC3 an Pin 2 des tiny13 im Dauerlauf (der AD-Wandler beginnt nach der Umwandlung von selbst wieder) gestartet wird.

;
; AD-Wandler starten
;
	; PB3=ADC3 wird nur fuer den AD-Wandler verwendet
	ldi rmp,0b00001000 ; PB3 Digitaltreiber ausschalten, spart Strom
	out DIDR0,rmp
	; Referenz = Betriebsspannung, Links-Justieren Ergebnis,
	;   ADMUX auf ADC3 stellen
	ldi rmp,0b00100011 ; Referenzspannung UB, ADC3 waehlen
	out ADMUX,rmp
	; Autostart-Option waehlen
	ldi rmp,0b00000000 ; Freilauf waehlen (startet selbst)
	out ADCSRB,rmp
	; ADC starten, Interrupt ermoeglichen, Teilerrate einstellen
	ldi rmp,0b11101111 ; ADC starten, Autostart,
	out ADCSRA,rmp ;  Int Enable, Teiler auf 128
; fertig initiiert
Der Betrieb per Interrupt setzt voraus, dass der entsprechende Sprungvektor vorhanden ist, also z.B.

;
; Sprungvektoren fuer Reset und Interrupts, ATtiny13
;
.CSEG ; Assembliere in das Code Segment
.ORG $0000 ; an den Anfang des Code Segments
	rjmp main ; Reset vector
	reti ; Int0 interrupt vector
	reti ; PCINT0 vector
	reti ; TC0 overflow vector
	reti ; Eeprom ready vector
	reti ; Analog comparator int vector
	reti ; TC0 CompA vector
	reti ; TC0 CompB vector
	reti ; WDT vector
	rjmp intadc ; ADC conversion complete vector
;
Natürlich muss auch der Stapel initiiert sein und das Interrupt- Statusflag gesetzt sein (SEI).

Die Service-Routine intadc liest den AD-Wandler aus. Da Links-Justieren gesetzt ist, reicht es, das MSB des Ergebnisses zu lesen:

;
; Interrupt Service Routine AD-Wandler
;
.DEF rKey = R15 ; Ergebnisspeicher AD-Wandler-Wert
intadc:
	in rKey,ADCH ; Lese AD-Wandler MSB
	reti ; Rückkehr vom Interrupt
;
Im Register rKey steht jetzt laufend aktuell der Wandlerwert des Keyboards.

3.6 Umwandeln des AD-Wandler-Werts in einen Tastencode

Die Spannung alleine ist noch nicht sehr verwendungsfähig. Da die Spannungen aufgrund der eigenwilligen Gestaltung von Standard-Widerstandswerten (wer hat sich die Reihe 4,7 - 5,6 - 6,8 - 8,2) bloß ausgedacht? Muss entweder ziemlich sturzbetrunken oder ein Mathematiker gewesen sein!) und der arg krummen Formel U = R1 / (R1 + R2) kommt hierfür nur eine Tabelle in Betracht. Die Tabelle kann nicht primitiv sein, da wir ja 256 mögliche ADC-Zustände haben und keine unnötige Platzverschwendung betreiben wollen.

Wir hangeln uns mit dem ADC-Wert in rKey durch folgende Tabelle:

KeyTable:
.DB 7, 255, 18, 1, 28, 2, 42, 3, 64, 4, 91, 5
.DB 121, 6, 156, 7, 185, 8, 207, 9, 225, 10, 237, 0, 255, 11
Das niedrige erste Byte jedes Worts sind jeweils die AD-Werte: von 0 bis <7: keine Taste gedrückt (Tastencode=255), von 7 bis <18: Tastencode 1, etc..

Oder wer lieber gleich ASCII mag:

KeyTable:
.DB 7, 0 , 18, '1', 28, '2', 42, '3', 64, '4', 91, '5'
.DB 121, '6', 156, '7', 185, '8', 207, '9', 225, '*', 237, '0', 255, '#'
Der Code zur Auswertung sieht dann so aus:

;
; Umwandlung des AD-Werts in einen Keycode
;
GetKeyCode:
	; falls der AD-Wert zwischendurch wechselt, vorher kopieren!
	mov R1,rKey ; kopiere AD-Wandler-Wert nach R1
	ldi ZH,HIGH(2*KeyTable) ; Z zeigt auf Tabelle
	ldi ZL,LOW(2*KeyTable)
GetKeyCode1:
	lpm ; Lese Wert aus Tabelle
	cp R1,R0 ; vergleiche AD-Wert mit Tabellenwert
	brcs GetKeyCode2 ; kleiner als Tabellenwert, Taste gefunden
	inc R0 ; teste, ob am Tabellenende
	breq GetKeyCode2 ; Tabellenende erreicht
	adiw ZL,2 ; huepfe ein Wort weiter in der Tabelle
	rjmp GetKeyCode1
GetKeyCode2:
	adiw ZL,1 ; zeige auf MSB = Tastencode
	lpm ; lese Tastencode aus Tabelle in R0
;
Natürlich ist jetzt noch zu prüfen, ob keine Taste gedrückt ist (R0 = 0xFF bzw. bei ASCII: R0 = 0) und es sind Anti-Prell-Aktionen zu basteln (wenn 20 mal hintereinander die gleiche Taste herauskommt, nehme ich sie ernst, etc.).

3.7 Erfahrungen

Die Schaltung und die Software sind sehr stabil. In der ersten Version waren die Widerstände 10 mal so groß. Das hatte höhere Störanfälligkeit zur Folge, z.B. wenn in der Nähe mit einer 2 W-Handfunke gerade gesendet wurde.



An den Seitenanfang

©2006-2017 by http://www.avr-asm-tutorial.net