Forum: Projekte & Code PS2-Tastatur / PS2-Maus an Attiny2313 in C


von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

Anstatt mir Tastaturen aus einzelnen Tasten zusammen zu löten und 
qualvoll (Stichwort: bulletproof) zu entprellen, versuche ich im Moment, 
ausrangierte Tastaturen zu recyclen.
Selbst neu gekauft sind Tastaturen preiswerter etwa als die 
Folientastaturen vom C.
Und bieten dabei zusätzliche Optionen, wie etwa
- die drei LEDs, die man nach herzenslust schalten kann,
- die Auswertung mehrerer gleichzeitig gedrückter Tasten (wie etwa 
CTRL-ALT-DEL),
- und in ein fertiges Gehäuse sind sie auch bereits eingebaut.

Da das Protokoll der PS2-Tastatur und der PS2-Maus gleich ist, kann man 
mit den Routinen auch eine Maus als Eingabegerät betreiben.
Die Standardmaus bietet immerhin drei Tasten – und die Mausbewegungen 
kann man ebenfalls auswerten. Die Intellimouse hat sogar 5 Tasten plus 
Scrollrad (liefert Werte von 0 .. 7).
Damit läßt sich schon allerhand anfangen.

Die erforderliche Hardware ist anspruchslos.
 Ein ATtiny mit 2k Flash und 128Byte SRAM reicht aus. (benutzt habe ich 
eine ATtiny2313 mit XTAL 7.3xx.xxx MHz).
Auf dem mc werden der INT0 und Timer0 belegt.
Die Tastatur oder Maus wird mittels DIN/bzw. PS2-Buchse an INT0 (clock) 
und PD4 (data) angedockt.
Mit entsprechenden Änderungen im Programmcode lassen sich auch andere 
Lösungen finden.
Ich habe jeweils noch 100k als Pullups an die Clock-/Data-Pins geklemmt.
Soll die Ausgabe der Daten über die serielle Schnittstelle erfolgen, 
dann ist noch ein Quarz mit 2 Kondensatoren erforderlich. Das wars aber 
auch schon.

Anregung für die Routinen ist die AVR313 von Atmel sowie die 
Informationen auf der Seite www.marjorie.de. Hier gibt eine sehr gute 
Dokumentation des Tastaturprotokolls (als ausdruckbare PDF) . Und einen 
Link zur Seite www.computer-engineering.org, auf der die Funktion der 
PS2-Maus ausführlich beschrieben ist.
Nachdem es dann dank dieser Angaben gelungen war, nicht nur die Codes 
von der Tastatur zu empfangen, sondern auch Befehle an die Tastatur zu 
senden (wie z.B. die LEDs zu schalten, RESET ausführen), war es ein 
kleiner Schritt, anstelle der Tastatur eine Maus zu konfigurieren und 
die von ihr gelieferten Daten auszuwerten.

Die Empfangsroutine (INT0_ISR) arbeitet interruptgesteuert im 
Hintergrund.
Die Routine prüft das Start-, Paritäts- und Stopbit sowie die Dauer der 
Übertragung.
Im Fehlerfall wird ein Fehlercode gesetzt und die Fehlermeldung kann 
angezeigt werden.
Die Interruptroutine legt die eingegangen Daten in einem Ringbuffer ab.

Das Hauptprogramm muss prüfen, ob Daten im Puffer sind – und sie dann 
abholen und auswerten.
Bis hier hin arbeiten Maus- und Tastaturprogramm gleich. Die 
Unterschiede liegen in der Auswertung der empfangenen Daten.

Das Procedere im Detail:

Interrupts freischalten, initialisieren mit
- PS2_init()
Beim Empfang muss main() lediglich mit
- PS2_is_byte_in_buffer() geprüft werden, ob (mindestens) 1 Byte 
ansteht, dann wird es mit
- PS2_get_byte_from_buffer() abgeholt und ist anschließend zu 
verarbeiten.

Das Senden an ein PS-Gerät übernimmt PS2_cmd(CMD).
Mit jedem Aufruf wird genau 1 Byte abgeschickt und auf die 
Bestätigung/Antwort gewartet.
Die Bestätigung des Gerätes (0xFA) landet im Buffer und kann abgefragt 
werden.

Weitere Bytes als Parameter werden ebenfalls mit PS2_cmd(Parameter) 
verschickt.
Sollen die bei der Transaktion zurückgebenen Werte nicht geprüft werden, 
so kann man den Buffer mit PS2_init() einfach löschen.

Die Auswertung

Die Auswertung der Mausaktivität ist relativ einfach:
Die Daten kommen immer im 3er Gruppen (aber bei Intellimouse in 4er 
Gruppen):
- Byte 1 enthält Statusinformationen
- Byte 2 und 3 die Y- / X- Koordinatenveränderung seit der letzten 
Sendung.

Bei der Tastatur kann es aufwändiger werden.
Abhängig davon, wie komplex die Auswertung der TastaturCodes werden 
soll, sind hier zahlreiche  Fallunterscheidungen erforderlich:
- die Tastatur senden SCAN- und BREAK-Codes,
- manche Tasten sollen ggf. direkt ein Unterprogramm aufrufen (z.B. F1 
.. F12),
- manche Tasten schalten nur ein Statusbit um (SHIFT, CTRL, ALT),
- die Bedeutung vieler Tasten ist abhängig davon, ob SHIFT gedrückt ist 
oder nicht.
Der Zusammenhang zwischen eine Tastaturcode und dem dadurch zu 
generierenden ASCII-Zeichen kann nicht berechnet werden, hierfür muss in 
einer Tabelle nachgeschlagen werden.

Hier muss jeder für sich und seine Anwendung entscheiden, wie die 
Schnittstelle Programm -  Bediener aussehen soll.

Es sind zwei Programm-Beispiele beigefügt:
Für die PS2-Tastatur:
Liefert die ASCII-Zeichen der betätigten Taste auf der seriellen 
Schnittstelle zurück,
der Status von CTRL, SHIFT, ALT wird registriert und kann ausgewertet 
werden.
Als Demo fest 'verdrahtet' sind:
Ein CTRL-ALT-DEL setzt die Tastatur zurück (die LEDs blinken kurz auf),
bei jedem RETURN werden die LEDs getoggled, F1 drückt "F1" aus!

Für die PS2-Maus:
Sendet ein RESET an die Maus und gibt die Antwort auf der seriellen 
Schnittstelle aus.
Fragt dann noch einmal die Maus_ID ab (in der Regel 0, Intellimouse 3).
Anschließend wird die Wiederholung auf maximal 10 Sendungen je Sekunde 
eingestellt, die Auflösung auf 1 Einheit je mm und anschließend die 
Ausgabe aktiviert.
Die Antworten der Maus auf die Befehle werden über die serielle 
Schnittstelle protokolliert.
Danach werden die Mausbewegungen in X/Y-Koordinaten ausgegeben und 
gedrückte Tasten angezeigt.

Die Auswertung einer Intellimouse konnte ich mangels Hardware nicht 
implementiert.

Beide Programme sollen als Grundgerüst für individuelle Anpassungen 
dienen.

Viel Spaß beim Anpassen.

Michael S.

von PicPic (Gast)


Lesenswert?

Das suche ich (Tastatur)für den (z.B.) P16F627/28 in ASM.

von Michael S (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

die Auswertung des "Maustreibers" habe ich noch einmal umgestellt.
Anstelle von Koordinaten wird nun nach jeder Mausaktivität ein Byte 
ausgegeben, das den Status von 7 Tasten übermittelt:

CURROR_LEFT  (Bit.7)
CURSOR_RIGHT  (Bit.6)
CURSOR_DOWN  (Bit.5)
CURSOR_UP  (Bit.4)
frei    (Bit.3)
Maus_M    (Bit.2)
Maus_R    (Bit.1)
Maus_L    (Bit.0)

Die Mausbewegung wird in virtuelle Tastendrücke umgewandelt und 
simuliert nun die Cursortasten.
Die Bits stehen in der Variablen key_status und werden im beigefügten 
Beispiel über die serielle Schnittstelle mit 38400 Baud ausgegeben.

Als Interpretationshilfe:

0x81 bedeutet dann: Mausbewegung nach links,  linke Maustaste gedrückt
0x42                Mausbewegung nach rechts, rechte Maustaste gedrückt
0x10                Mausbewegung nach oben,   keine Maustaste gedrückt
0x50                Mausbewegung nach oben und rechts, keine Maustaste 
gedrückt


Ausserdem wird nach jeder registrierten Mausaktivität wird ein "beep" 
auf einem Summer als akustische Rückmeldung ausgeben (angeschlossen ist 
der Summer an OC1A = PB3, verbunden mit Masse oder VCC).

In einer praktischen Anwendung würde ich das Byte per SPI an einen 
Master
versenden.
Solange der keine Eingaben benötigt, holt er sich das SPDR einfach nicht
ab.
Wenn dann ein Dialog mit dem Anwender gefragt ist, wird der 
SPI-Interrupt
aktiviert - und alle Mausaktivitäten können durch Auswertung der 7 Bits 
in
entsprechende Aktionen umgesetzt werden.

Somit kann eine einfache Feld-Wald-und-Wiesen-Maus sieben 
unterschiedliche Tasten zur
Verfügung stellen.
Mir haben bislang meist 4 Tasten gereicht, 2 zum Navigieren im Menü,
1x ESC zum Beenden und 1x RETURN zum Bestätigen.

viel Spaß

Michael S.

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

hier eine Ergänzung für die Intellimouse:
In einer Programmvariante werden 5 Tasten, das Scrollrad und natürlich 
die Mausbewegungen unterstützt.
Das Programm sendet nunmehr 2 Byte mit Cursorstatus und Bewegung des 
Scrollrades.
Das erste Byte ist identisch mit der Ausgabe der  PS2-Maus.
Im zweiten Byte ist der Status der Maustasten 4 und 5 sowie das 
z-movement (Scrollraddrehung) abgelegt.
Zusätzlich eingebaut ist die Ausgabe über ein Software- 
SPI-Schnittstelle.

Ein Timing Problem beim Senden an die Maus ist behoben: wenn Befehle zu 
schnell nacheinander an die Maus gesendet werden, dann macht sie dicht 
und antwortet nur noch mit 0xFE.
Dies Problem taucht nur auf, wenn die Debuggingausgabe der Daten über 
die serielle Schnittstelle abgeschaltet war (die Ausgabe selbst diente 
als "Verzögerung").
Eine Warteschleife in PS2_cmd hat das Problem behoben.

Diese Änderung (auch sie Ausgabe über SPI) ist auch in den Code für die 
PS2_Maus eingepflegt.

Michael S.

von Sven W (Gast)


Lesenswert?

Hallo und vielen Dank für dieses Projekt, das ist genau das was ich 
gesucht habe!
Allerdings habe ich zwei kleine Fragen bezüglich des Tastatur Programms.
1. Ich benutze einen Quarzoszillator mit 18,4320 MHz. Muss ich (ausser 
F_CPU im Makefile) irgendwelche änderungen vornehmen? z.B. Prescale??
2. In der rs232.h heist es: #define TEILER ((F_CPU /(BAUD * 16l)) -1). 
Sollte es nicht 16 statt 161 heißen?
Ich bekomme mit beiden einstellungen nur kryptische Zeichen ausgegeben. 
Ein kleiner Tip was helfen könnte?
MfG

Sven W

von Adam P (Gast)


Lesenswert?

hallo sven,

das heißt nicht 161, sondern 16 (kleines L).
eine andere schreibsweise wäre 16UL.

mfg adam p.

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.