Tastaturboard für Mikrocontrolleranschluss

Tastaturboard mit Tastaturen

Beschreibung
Dieses Testboard bietet eine einfache Möglichkeit des Softwaretestes für ein Projekt mit Tastaturanschluss. Vorgesehen ist das Board für Tastaturen mit einem Matrix Anschluss. Matrix heißt, dass je eine ganze Reihe bzw. eine Spalte der Tastatur jeweils auf einen Anschlusspin gelegt sind. Durch das drücken einer Taste verbindet man nun die jeweilige Reihe mit der dazugehörenden Spalte. Eine eindeutige Zuordnung der Taste wird dadurch möglich. Die Grenze dieses Konzeptes ist dann erreicht, wenn versehentlich oder absichtlich mehrere Tasten gleichzeitig gedrückt wurden. Man kann dies aber mit einer etwas aufwendigeren Software auch abfangen. Die Anzahl der Anschlusspins wird so stark reduziert. Auf diese Art kann eine Tastatur mit 16 Tasten mit 8 Anschlüssen ausgeführt werden. Natürlich kann das dazugehörige Programm auch für andere Tastaturen mit Matrix Anschluss angepasst werden. Auf dem Testboard vorgesehen habe ich zwei Anschlussleisten, da ich zwei unterschiedliche Tastaturen zum testen benutzt habe.

Das Layout des 16 poligen Steckverbinders passt ausserdem auch noch auf das Mikrocontroller Board von Batronix.

Ideal zum Testen des Tastaturboards ist das LCD Testboard

Schaltungsbeschreibung
Die Schaltung selbst ist denkbar einfach auszuführen. Die Reihen und Spalten werden jeweils auf einen Portpin aufgelegt, über eine Jumperbrücke werden alle Pegel auf High gezogen. Die Jumper habe ich vorgesehen, um eine möglichst universelle Verwendung zu ermöglichen. Z.B. ist es bei den Atmel RISC Controller (AT90Sxxxx) möglich, pullup Widerstände innerhalb des Chips ein und auszuschalten (und damit eventuell die Portpins doppelt zu belegen).

Schaltplan
Schaltplan Tastaturboard

Hier sind die beiden bei mir vorhandenen Tastaturen mit der Pinbelegung und Tastenbeschriftungen dargestellt. Die Pinnamen entsprechen der Verwendung im Testprogramm.

Software
Die Ansteuerung des Tastaturboards funktioniert nun so:
Zuerst wird die erste Reihe auf "low" gelegt, danach der Port eingelesen. Ist ausser dem "gesetzten" Pin noch ein Pin auf "low", wurde eine Taste gedrückt. Ist dies nicht der Fall, wird der "Tastenzähler" um die Anzahl Spalten erhöht, und die nächste Reihe wird getestet. Wurde eine gedrückte Taste festgestellt wird der Reihe nach geprüft welcher Pin auf "low" liegt. In der Reihenfolge von einer seite zur anderen wird bei jedem weiteren Pin der "Tastenzähler" um eins erhöht, bis auch bei der Spalte ein "low" festgestellt wird. Der Tastenzähler hat jetzt die laufende Nummer der gedrückten Taste. Mit dieser Zahl wird jetzt der zugeordnete Wert der Taste aus der Tabelle KEYtab geholt, das Carry Flag als Erkennung einer gedrückten Taste gesetzt und der Wert im Akku zurückgegeben. Danach sollte man noch das Programm KEYrelease ausführen, das auf das loslassen der Taste wartet und für eine Entprellung sorgt.
Wie in der Beschreibung angedeutet, ist in diesen Programmen keine Vorsorge gegen das drücken mehrerer Tasten getroffen. Die Taste die zuerst gedrückt wird wird decodiert, weiter geht es erst wenn die letzte Taste losgelassen wird.
Mehr dazu in den Kommentaren zum Sourcecode.

Sourcecode für 8051 und kompatible Mikrocontroller
; Library für Programme rund um die Keypad Ansteuerung
; Folgende Definitionen müssen entweder im Hauptprogramm oder in dieser Library
; gemacht werden. Die Tastatur muss an einen Port angeschlossen sein.
;
;Keypad =P1
;Key_row1 =P1.3         ;Row = Zeile = waagerecht
;Key_row2 =P1.2
;Key_row3 =P1.1
;Key_row4 =P1.0
;Key_col1 =P1.6         ;col. = Spalte = senkrecht
;Key_col2 =P1.5
;Key_col3 =P1.4
;Key_col4 =P1.7  ;Dummyeintrag, damit gleiche Source verwendet werden kann
;Key_nokeyval = 11110000B  ;Setzt alle Reihen auf "L", alle Spalten sind "H"
;Key_numcol =3             ;Anzahl der Spalten

; Zuordnung der Returnwerte (in Hex.), die zurückgegeben werden
;KeyTab db 1,2,3           ;Tabelle je nach Keyboard Tastaturbelegung
;       db 4,5,6
;       db 7,8,9
;       db 0aH,0,0BH       ;den Sonderzeichen * und # sind 0x0a und 0x0b zugeordnet

;KeyASCIItab
;       db "0123456789*#"
;Asciiwert in der Reihenfolge der Hexwert Zuordnung (hat nichts mit der Anordnung der Tasten zu tun!)
;
; In dieser Library habe ich eine Vordefinition für 2 verschiedene Keypads eingebaut, die je nach Bedarf auskommentiert werden können.
; Falls der Compiler "if" Verzweigungen handhaben kann, kann natürlich auch damit umgeschaltet werden.
;
; Die Definition ist so flexibel wie möglich gehalten, ohne das Programm allzu sehr aufzublähen

;Hier starten die Unterprogramme. Folgende Routinen sind enthalten:
;
; KEYread    Bei nicht gedrückter Taste return mit Carry=0
;            Bei gedrückter Taste wird der in KeyTab definierte Wert im Akku
;            zurückgegeben. Carry=1
; KEYascii   Wie KEYread, gibt aber den in KeyASCIItab definierten Character
;            im Akku zurück.
; KEYrelease Wartet so lange bis die Taste losgelassen wird, danach Return.
;            Sorgt ausserdem für ein entprellen der Tasten
;

KEYread
       mov Keypad,#11111111B     ;Alle Bits gesetzt, Start
       mov A,#0                               ;Check Row1, nichts dazuaddieren
       clr Key_row1                         ;Jetzt wird die erste Zeile "L"
       acall KEY_chk_col                 ;Checkt ob Taste gedrückt ist
       setb Key_row1                       ;falls keine Taste der letzten Reihe -> nächste
       mov A,#Key_numcol              ;Anzahl der Stellen pro Reihe dazuzählen
       clr Key_row2                         ;z.B. bei numcol=3
       acall KEY_chk_col
       setb Key_row2
       mov A,#(2*Key_numcol)       ;Anzahl der Stellen pro Reihe dazuzählen
       clr Key_row3
       acall KEY_chk_col
       setb Key_row3
       mov A,#(3*Key_numcol)       ;Anzahl der Stellen pro Reihe dazuzählen
       clr Key_row4
       acall KEY_chk_col
  ; Falls die Tastatur weniger Reihen besitzt, die "überflüssigen" Zeilen auskommentieren

      clr C                                        ;Carry = 0 Keine Taste gedrückt
      ret

KEY_chk_col                                ;bei weniger Reihen entsprechend Zeilen wegnehmen
       jnb Key_col1,KEY_C1
       jnb Key_col2,KEY_C2
       jnb Key_col3,KEY_C3
       jnb Key_col4,KEY_C4
       ret
KEY_C1 add A,#0                       ;1. Taste = Wert + 0
       sjmp KEY_End
KEY_C2 add A,#1                       ;2. Taste = Wert + 1
       sjmp KEY_End
KEY_C3 add A,#2                       ;usw.
       sjmp KEY_End
KEY_C4 add A,#3

KEY_End
       pop DPL                               ;Dummy Register zum
       pop DPH                               ;löschen der alten Rücksprungadresse aus Stack
       mov DPTR,#KeyTab            ;Einstellen der Tabelle
       movc A,@A+DPTR              ;Holen des entsprechenden Wertes
       setb C                                   ;Carry = 1 Taste wurde gedrückt
       ret                                         ;weil die letzte Rücksprungadresse gelöscht wurde
                                                    ;erfolgt Return zum aufrufenden Hauptprogramm !
 
 

KEYascii                                     ;Wandelt den Tastaturcode in ASCII
       lcall KEYread                       ;holt ganz normal den Hexwert der Taste
       jnc KEYascii_End                 ;Carry=0 -> keine Taste gedrückt
       mov DPTR,#KeyASCIItab   ;Tabellenwert setzen
       movc A,@A+DPTR              ;hole passenden Wert aus der Tabelle
       setb C                                   ;Carry=1 -> Taste war gedrückt
KEYascii_End
       ret
 

KEYrelease                                 ;wartet bis Taste losgelassen
       push ACC                            ;Akku sichern
       mov A,#Key_nokeyval
       mov Keypad,A                    ;Alle Zeilen = "L"
KEY_pressed
       mov A,Keypad                    ;Prüft ob Reihe auf "L" geht
       cjne A,#Key_nokeyval,KEY_pressed ;Warte bis Taste losgelassen

  ;Für hartnäckig prellende Tastaturen diese Verzögerungsschleife einbauen
  ;die Werte der Register kann eventuell angepasst werden

       mov A,R1                             ;Sichern der temp. Zählerregister R1 und R2
       push ACC
       mov A,R2
       push ACC
       mov R1,#0                            ;setzen der Werte für die Verzögerungsdauer
Kwait1 mov R2,#0
Kwait2 nop
       nop
       djnz R2,Kwait2                     ;Schleife zum Zeit totschlagen
       djnz R1,Kwait1
       pop ACC                              ;Restore der Register R2 und R1
       mov R2,A
       pop ACC
       mov R1,A
  ;Ende der Verzögerungsschleife
       pop ACC
       ret

;Hier die Tabellenversion für die 16er Tastatur
;KeyTab db 0,1,2,3                    ;Tabelle je nach Keyboard Tastaturbelegung
;       db 4,5,6,7
;       db 8,9,0aH,0bH
;       db 0cH,0dH,0eH,0fH

;KeyASCIItab
       ;Asciiwert in der Reihenfolge der Hexwert Zuordnung (hat nichts mit der Anordnung der Tasten zu tun!)
       db "0123456789ABCDEF"

;Hier die Tabelle für die 12er Tastatur
KeyTab db 1,2,3                        ;Tabelle je nach Keyboard Tastaturbelegung
       db 4,5,6
       db 7,8,9
       db 0aH,0,0BH                    ;den Sonderzeichen * und # sind 0x0a und 0x0b Zugeordnet

KeyASCIItab
       ;Asciiwert in der Reihenfolge der Hexwert Zuordnung (hat nichts mit der Anordnung der Tasten zu tun!)
       db "0123456789*#"
 

Download
Hier die beschriebenen Files zum Download:
 Schaltplan Tastaturboard
 Platinenlayout
 Library Sourcecode keypad.lib
 Testprogramm (Arbeitet zusammen mit dem  LCD Testboard )

Hier die Softwarefiles zusammen als gepackte Datei TastLCD.zip

Kompiliert wurden die Testprogramme mit dem kostenlosen Assembler RAD51 von  Systronix . Dieser Assembler bietet eine Projektverwaltung und arbeitet unter Windows (95+98). Außerdem werden individuelle Registerkonfigurationen und "if else" Verzweigungen unterstützt.
Für den Controllertyp habe ich noch eine "quick+dirty" Definitionsdatei für die Register für RAD51:  MOD51.H
 
 
 
 

Letzter Update: 23.03.2001


Diese Seite ist Teil eines Framesets. Kein Inhalsverzeichnis? Mit Home gelangen Sie zum Index.