www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PC-Tastatur mit AVR ersetzen


Autor: Moritz Greif (moritz-)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ich will mit einem ATmega eine PC-Tastatur programmieren, die nur zwei 
Tasten enthält: Pfeil up und Pfeil down

Dafür muss ich mithilfe des Protokolls (im Anhang) vier Bytes 
übertragen:

E0,F0,6B,75 (alle hex)

Hat jemand schon erfahrungen mit Software-Protokollen? Kann das klappen, 
in der Art:

Pin1 on, Pin2 off, warte 1ms, Pin2 off, warte 1,2ms, Pin1 off, warte 0,5 
ms, Pin1 on,.......

Hier jetzt mal nur so als Beispiel. Ich müsste mir dann die Arbeit 
machen für die 4 oben genanten Bytes Unterprogramme zu schreiben, und 
dann

Bei Taste "Pfeil up"
rcall E0uebertragen

bei Taste "Pfeil up"  wieder losgelassen
rcall ...

usw. Das ist die Holzhacker-Methode, aber ich habe noch keine Idee wie 
es eleganter geht...

Ideen?

Grüsse,
Moritz

Autor: Dirk Hofmann (arm-dran)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moritz Greif wrote:
> Hallo!
> Ich will mit einem ATmega eine PC-Tastatur programmieren, die nur zwei
> Tasten enthält: Pfeil up und Pfeil down
>
> Dafür muss ich mithilfe des Protokolls (im Anhang) vier Bytes
> übertragen:
>
> E0,F0,6B,75 (alle hex)
>
> Hat jemand schon erfahrungen mit Software-Protokollen? Kann das klappen,
> in der Art:
>
> Pin1 on, Pin2 off, warte 1ms, Pin2 off, warte 1,2ms, Pin1 off, warte 0,5
> ms, Pin1 on,.......
>
> Hier jetzt mal nur so als Beispiel. Ich müsste mir dann die Arbeit
> machen für die 4 oben genanten Bytes Unterprogramme zu schreiben, und
> dann
>
> Bei Taste "Pfeil up"
> rcall E0uebertragen
>
> bei Taste "Pfeil up"  wieder losgelassen
> rcall ...
>
> usw. Das ist die Holzhacker-Methode, aber ich habe noch keine Idee wie
> es eleganter geht...
>
> Ideen?
>
> Grüsse,
> Moritz

@Moritz

Wenn Du die Tastatur an einen PC anschließen willst, reicht es nicht 
aus,
nur eben die Codes für beide Tasten zu senden.
Der PC kommuniziert mit der Tastatur, macht am Anfang einen Selbsttest.

Wenn Du nicht entsprechend dem PS2 Protokoll reagierst (Standard Set2),
wird der PC die Tastatur als evtl. nicht anwesend erkennen.

Dirk

PS:  Eine Simulation einer PS2 Tastatur mit einem AVR ist grundsätzlich
Problemlos

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es gibt nicht nur einen Code für das Drücken der Taste, sondern auch 
fürs loslassen.
Klar kann man das selbst programmieren, dürfte nicht sonderlich schwer 
sein.
Ich würde eine alte Tastatur auchschlachten und die passenden Anschlüsse 
für die Tasten verwenden. Einfach, billig, betriebssicher, schnell 
gemacht.

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Moritz,

ja - viele Wege führen nach Rom - Du
kannst auch die Daten an eine Routine
übergeben, die den Start ausgibt,
das auszugebende Byte in einer Schleife
schiebt und ausgibt und abschliessend
das Stoppbit sendet.

Gruß Otto

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ok, das mit den Codes für anschlag und loslassen hab ich im Internet 
gefunden. Man muss für die Pfeiltasten doooferweise zwei Byte senden für 
gedrückt, und drei Byte für wieder losgelassen.

Das Mit dem Selbsttest am Anfang ist ja eglich. Danke für den Hinweis!
Ich werde mich darüber mal erkundigen.

Aber ihr denkt, dass einfaches, manuelles, an & aus machen von zwei Pins 
ausreicht. Na das probier ich auch dann mal aus.

Eine Frage noch: ist der Takt des Clock Impulses genormt? Kann er 
beliebig lang sein? Und wichtiger: muss er immer gleich getaktet sein, 
oder kann man z.b. bei Bit 5 den Clock takt verlängern (sozusagen die 
Übertragung verzögern/stoppen) oder so? theoretisch handelt es sich doch 
um ein asynchrones Protokoll-Signal!!! (reagiert ja eigentlich auf die 
flanken)

Grüsse
Moritz

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Moritz,

die Tastatur macht einen Selbsttest.

Für den PC ist die Welt in Ordnung,
wenn die Leitungen High-Pegel haben.

"an und aus machen" geht, wird aber
sicher ein wenig lang....

Gruss Otto

Autor: Dirk Hofmann (arm-dran)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Moritz

Und hier der altbekannte Link:

http://www.marjorie.de/ps2/start.htm

So einfach funktioniert das nicht.

1.) Die Tastatur ist immer der Taktmaster
Ein Impuls dauert zwischen 20 und 40 µS (schwankt deswegen, weil die 
Tastaturen meistens keinen Quarz sondern nur ein RC Glied, Resonator 
haben)

2) Der PC richtet sich nach diesem Takt, kann jedoch durch 
"herunterziehen" der Signale von CLK und oder DAT die Tastatur zu 
versch. Aktionen veranlassen.
Du musst dann beide Ports nach dem schreiben zurücklesen und prüfen, ob 
der
PC eine Aktion starten möchte.

Dirk

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo, also ich lass die beide pins an, bis der PC den Clock-Pin nicht mehr 
auf null gezogen hat, dann kann ich die übertragung starten.
Als Takt sind 20 bis 40 µs  ja mit nem 8Mhz Quarz am Atmega8 kein 
Problem.
Ich werde dann die sende Pins mit zwei andern pins verbinden, die als 
Eingang konfiguriert sind, dann kann ich zwischendurch immer mal prüfen, 
ob der PC aufmuckt.

Muss ich die manchmal erwähnten "Echo"-Bytes und so auch senden? Ich 
blick da nicht durch in den Codetabellen. Wenn der PC zum Beispiel LED1 
an sendet, kann ich das doch einfach  ignorieren, oder?

moritZ


--> nur mal so nebenbei: Die beiden Pfeiltasten werden mit schönen 
vandalismussicheren Tastern neben den neuen digitalen Vertretungsplan in 
unserer Schule angebracht, sodass die Schüler auf den Monitoren scrollen 
können. Ist ein Projektsche was unsere hilflose Schule armen 
Oberstufenschülern aufhalst :-)... Moritz könnten Sie vielleicht mal ...

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Moritz,

>Wenn der PC zum Beispiel LED1
>an sendet, kann ich das doch einfach  ignorieren, oder?

ja

Otto

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So hier nochmal das Timing zusammengefasst:

"The time from the rising edge of a clock pulse to a Data transition 
must be at least 5 microseconds. The time from a data transition to the 
falling edge of a clock pulse must be at least 5 microseconds and no 
greater than 25 microseconds"
"The clock frequency must be in the range 10 - 16.7 kHz. This means 
clock must be high for 30 - 50 microseconds and low for 30 - 50 
microseconds"

mal auf Deutsch:
----------------------------------------------------------------------
Clock pulse an, mindestens 5 µs warten, dann erst 
Datenleitungs-Pegelwechsel, dann wieder mindestens 5µs (und nicht länger 
als 25µs) und Clocksignal wieder low.
So. Jetzt erstmal warten (der Datenpin behält seinen Bit-Wert. der Clock 
Pin ist low.) und zwar ,sagen wir, 40 µs.

Jetzt wieder Clock an, mind. 5µs warten dann erst 
Datenleitungs-Pegelwechsel, dann wieder mindestens 5µs (und nicht länger 
als 25µs) und Clocksignal wieder low.
usw...
-----------------------------------------------------------------------



Ich mach das dann mal so (Bsp. 122:     0b01111010)

CLK        DATA          Dauer   Beschreibung
------------------------------------------------------------
1          1                     start und init des pc's
----------------------------------------------------------
1          0             20µs
0          0             40µs    Startbit
1          0             20
1          0             20      data transition (erstes bit 0)
0          0             40
1          0             20
1          1             20      data transition
0          1             40
1          1             20
1          1             20      data transition
0          1             40

usw.

Dann ist das Clock signal wie oben aufgeführt 40µs high und 40µs low, 
entspricht einer frequenz von 12,5kHz. Im grünen Bereich.

So, jetzt gehts an die Programmierung!!!

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erklärs mir bitte noch mal: du willst ein paar Stunden programmieren 
(solange wirds dauern), ein Platine frickeln, Fehler suchen, 
Programmiereung ändern und und und. Mit Informationssuche und Fragen 
hast du jetzt schon ein paar Stunden vertan. Warum bitte schlachtest du 
nicht eine Tastatur? Nur um sagen zu können: ich habs selbst gemacht??
Eine gute Lösung ist immer auch eine effektive Lösung. Es gibt 
sinnvollere Projekte, wenn es dir ums Basteln geht.
kopfschüttelnd...

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moritz schrieb:

> Ist ein Projektsche was unsere hilflose Schule armen
> Oberstufenschülern aufhalst :-)... Moritz könnten Sie vielleicht mal ...

Otto

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja und?
Ich fänds cooler, wenn der gute Moritz am nächsten Morgenmit einer 
Blackbox auftaucht, 4 Drähte anknippert und die Sache läuft.
Es gibt keinen sinnvollen Grund, das selbst zu machen. Alte Tastaturen 
liegen eigentlich immer rum, und eine könnte sogar noch mal einer 
sinnvollen Verwendung zugeführt werden. Aber ne, nur nichts einfach 
machen.

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na wenn ich den Code erstmal habe, kann ich ja nach belieben Tastaturen 
bauen, mit nur den Tasten, die ich möchte.
Ich habe parallel eine Anfrage bekommen, ein keypad mit einigen Tasten 
zu bauen, um eine CNC-Fräse zu bedienen. Die Mechaniker wollen in der 
Werkstatt nämlich keine ganze Tastatur- und jedesmal eine schlachten ist 
doch Quatsch

ausserdem glaube ich fest daran, dass man auch noch ganz elegant mit 
bits schieben oder so, beliebige bytes senden kann...

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für eine Abkürzung ist mir kein Umweg zu weit.

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Für eine Abkürzung ist mir kein Umweg zu weit.

und: der Weg ist das Ziel...

Otto

Autor: Dirk Hofmann (arm-dran)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moritz Greif wrote:
> Für eine Abkürzung ist mir kein Umweg zu weit.

Jetzt bruhigt Euch mal wieder.

@Crazy horse

Lass Moritz doch das machen. Auf jeden Fall sammelt er dabei 
Erfahrungen.
Wo ich Dir rechtgebe ist, wenn es schnell gehen soll. Da ist ne 
modifizierte
alte Tastatur mit Sicherheit die bessere Wahl.

@Moritz
Also wenn es schnell gehen soll, ne alte. Stell es Dir aber nicht ganz 
so einfach vor. Mit weglassen oder nicht reagieren auf Befehle vom PC, 
wirst
Du keinen Erfolg haben. Bereite Dich darauf vor, einen 2 Kanal Oszi auf
beide Leitungen zu hängen um mitzulauschen.

Und ganz wichtig, beide PortTreiber dürfen nur source current sein.
Mir highside Treiber zerstörst Du evtl. das Ganze.

Viel Erfolg

Dirk

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Natürlich kann man das selbst programmieren, gar keine Frage. Noch dazu, 
da es völlig dokumentiuert ist und keinerlei echte Schnüffelarbeit zu 
leisten ist.
Egal, welche Spezialtastatur du brauchst-der Tastaturcontroller kann das 
alles. Es sei denn, du willst ganz eigene Tastaturcodes senden. Damit 
kann dann allerdings keine Software was anfangen, bleibt 
höchstwahrscheinlich schon im Betriebssystem stecken und würde nicht mal 
in einer eigenen Anwendungssoftware ankommen.
Und wenn du je auf einem Wertstoffhof o.ä. warst - dort lagern hunderte, 
die auf den Schredder warten. Fast jeder Computerladen, fast jede Firma, 
die mehr als 3 Computer hat, hat die Dinger rumliegen, garantiert auch 
in deiner Schule (dank Geldknappheit leben die meisten Computerräume von 
Schulen von Spendencomputern, dementsprechend kommt da auch reichlich 
Müll rein. Selbst neu kaufen kannst du die für 3€ (die Tasten selbst 
sind dann natürlich eher unbrauchbar). Und nun rechne mal deinen MC, 
Kabel mit PS2-Stecker, Platine.
Leg dich ins Bett und denke morgen noch mal vorurteilsfrei drüber nach.

Autor: Bernd T. (bastelmensch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich gebe da Crazy Horse recht.

Nimm so eine billig-Tastatur und dann bau das was Dich interessiert in 
ein kleines Gehäuse rein.

Damit hast Du bewiesen das Du Kostenbewußt arbeitest. (allerdings nicht 
sehr umweltfreundlich in diesem Fall)

Autor: Christian U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habs gestern gemacht da ichs für n Prüfgerät brauchte. War 20 min 
Arbeit danach liefs. Musste 2x mitm Oszi vergleichen. Wo bitte soll das 
Problem sein  einfach den io port schalten und _delay_us is auch 
erfunden. In der Wiki steht der aufbau schön erklärt. Da muss man nicht 
nen 80 Beitrags Thread draus machen.

Autor: Ulf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Christian U.

Kannst Du den Code posten ?
Würde mich mal interessieren.

Autor: Christian U. (z0m3ie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab den code mal auf standart C umgebastelt im Prüfgerät nutz ich 
spezielle IO routinen. so sollt es gehn.
void PS2_init(void)
{
  PS2_DDR  |= ((1<<PS2_CLOCK)|(1<<PS2_DATA));
  PS2_PORT |= ((1 << PS2_CLOCK)|(1 << PS2_DATA));
}

void PS2_clock(void)
{
  _delay_us(15);
  PS2_PORT &= ~(1 << PS2_CLOCK)
  IO_set(PS2_CLOCK,1);
  PS2_PORT |= (1 << PS2_CLOCK)
  IO_set(PS2_CLOCK,0);
}

void PS2_send(uint8_t data)
{
  uint8_t tmp = data;
  uint8_t i;
  
  //Startbit
  PS2_PORT &= ~(1 << PS2_DATA)
  PS2_clock();
  //Daten
  for (i=0;i<8;i++)
    {
      if (tmp & 1)
        PS2_PORT &= ~(1 << PS2_DATA);
      else
        PS2_PORT |= (1 << PS2_DATA);
      tmp >>= 1; 
      PS2_clock();
    }
  //Parität
  if (tmp & 1)
    PS2_PORT &= ~(1 << PS2_DATA);
  else
    PS2_PORT |= (1 << PS2_DATA);
  PS2_clock();
  //Stopbit
  PS2_PORT |= (1 << PS2_DATA)
  PS2_clock();
  _delay_ms(1);
}

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sowas in assembler wär cool.

Wie kann man einzelne Bits eines Registers rausbekommen, um die einzeln 
in einem Protokoll zu senden?
Hat da jemand einen Ansatz?

Meine Idee wäre, das Register erst mit 0b1000000 zu subtrahieren und 
gucken ob ein Überlauf entsteht, dann mit 0b01000000 , dann mit 
0b00100000, usw.
Doch ist das sehr umständlich und müsste wahrscheinlich ein 
timing-Problem mit dem Host geben.

Was ich im Prinzip möchte, ist ein Register, das man mit einem bel. Wert 
belädt, und dann eine Funktion "rcall send_register" , die dann die 8 
Datenbits mit Stopp,Parity, usw., an den PC sendet.

Bis jezt hab ich nur jedes Byte einzeln programmiert, was extrem nervig 
ist und nur für wenige machbar.

Gruss,
Moritz

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moritz Greif wrote:
> sowas in assembler wär cool.
>
> Wie kann man einzelne Bits eines Registers rausbekommen, um die einzeln
> in einem Protokoll zu senden?
> Hat da jemand einen Ansatz?

Du kannst zb. die rotier oder schiebebefehle benutzen um
ein Register um 1 Bit nach Links zu rotieren (schieben).
Das Bit das links rausfällt landet im Carry Flag.
Und dann gibt es da noch Sprungbefehle, die abhängig davon
ob das Carry gesetzt ist einen Sprung durchführen oder nicht.

Studiere doch das mal, da wird das genau so benutzt:
http://www.mikrocontroller.net/articles/AVR-Tutori...


Autor: Dirk Hofmann (arm-dran)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Christian U.

Und dieser Code soll funktionieren ?

Ahja...

Dann bitte mal das komplette Programm mit den beiden Tasten (2 Portpins 
zur Simulation dafür) und dem Protokoll-Handling, lauffähig mit jedem 
PC-PS2 Tastaturanschluß.

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl Heinz: Das war genau das, was ich gebraucht habe! Danke!°°°

Autor: Christian U. (z0m3ie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Dirk Hofmann

hakts ?
Bin ich verpflichtet euch Code zur Verfügung zu stellen ?
Zur Information:

Ich benutze das um ein Embedded Device zu Testen keinen PC.
An dieses Device werden normalerweise PS/2 Tastaturen angeschlossen.
Deshalb brauch ich nur eine routine die mit PS/2 Protokolle sendet. Und 
das ist diese die ich gepostet hab.

>Und dieser Code soll funktionieren ?

Und ja sie hält sich exakt an die Spezifikation und funktioniert.
Ein PC sendet auch Daten an die Tastatur. Was mit diesen routinen 
natürlich nicht gegeben ist. Aber nachzuschauen ob der DATA port für > 
100us auf low ist und dann meine Clockroutine 11x aufzurufen und dabei 
nach jedem Aufruf den status von DATA in eien Variable zu schieben 
sollte kein Problem darstellen damit könnte man auch empfangen.

Ich hab mir die Mühe gemacht extra die Routinen umzubasteln da ich 
spezialisierte IO RRoutinen im PG habe. Und dann kommt wieder jemand wie 
herr Hofmann daher... Was bitte sollte daran denn nicht funktionieren ? 
Hast dus probiert ?

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, hier mal meine vorläufige assembler-version
.include "m8def.inc"    ; alle Signale müssen noch invertiert werden!!!!

ldi r16, 0b00000110
out DDRB, r16

ldi r16, LOW(RAMEND)             ; LOW-Byte der obersten RAM-Adresse
out SPL, r16
ldi r16, HIGH(RAMEND)            ; HIGH-Byte der obersten RAM-Adresse
out SPH, r16

.def temp1=r20
.def temp2=r21
.def parity=r22

ldi parity, 1                    ; 0 ist ja gerade, gerade bedeutet parity = 1

protokoll:
sbi Portb, 1
sbi Portb, 2

init:
sbic pinb, 4
rjmp init
;---------------
;>>>>> temp1 ist zu übertragenes Byte
;>>>>> rcall Schiebe überträgt das Byte
;>>>>> danach sind DATA und CLOCK 1

loop:
;...hier kommen die Tastaturbefehle
rjmp loop

Schiebe:
rcall Startbit

    push  temp2
    ldi   temp2, 8             ; 8 Bits müssen ausgegeben werden
 
Schiebe_1:
     ;
     ; jeweils das höchstwetrige Bit aus temp1 ins Carry Flag schieben
     ; Je nach Zustand des Carry Flags wird die Datenleitung entsprechend
     ; gesetzt oder gelöscht
     ;
    rol  temp1                 ; HSB -> Carry
    brcs Schiebe_One           ; Carry gesetzt? -> weiter bei Schiebe_One
;------------------------; Eine 0 ausgeben-------------------------------------
sbi portb, 1
rcall warte
cbi Portb, 2
rcall warte
cbi portb, 1
rcall warte
rcall warte  

rjmp bitweiter
;-------------------------------------

Schiebe_One:
             ; Eine 1 ausgeben
sbi portb, 1
rcall warte
sbi Portb, 2
rcall warte
cbi portb, 1
rcall warte
rcall warte
;-------------parity aktualisieren
cpi parity, 0
brne wechsel
rjmp sonst
wechsel:
ldi parity, 0
rjmp ende
sonst:
ldi parity, 1
ende:
;---------------------------------

bitweiter: 
dec   temp2                ; Anzahl der ausgegebenen Bits runterzählen
brne  Schiebe_1            ; Wenn noch keine 8 Bits ausgegeben -> Schleife bilden
 
pop   temp2

parity_bit:
;----------------------
cpi parity, 0
breq null
rcall send_eins
rjmp ende_
null:
rcall send_null
ende_:
;----------------------

rcall stoppbit

ret

;---------------------------
Startbit:
;------------------
sbi Portb, 2
sbi portb, 1
rcall warte
cbi Portb, 2
rcall warte
cbi portb, 1
rcall warte
rcall warte
;------------------
ret

send_Null:
;------------------
sbi portb, 1
rcall warte
cbi Portb, 2
rcall warte
cbi portb, 1
rcall warte
rcall warte
;------------------
ret
Send_eins:
;------------------
sbi portb, 1
rcall warte
sbi Portb, 2
rcall warte
cbi portb, 1
rcall warte
rcall warte
;------------------
ret
Stoppbit:
;------------------
sbi portb, 1
rcall warte
sbi Portb, 2
rcall warte
cbi portb, 1
rcall warte
rcall warte
sbi Portb, 1
;------------------
ret

;Parity Bit:
; Gerade Anzahl von 1en => Parity ist 1
; ungerade Anzahl von 1en => Parity ist null



warte:  ;15µs
; ============================= 
;   Warteschleifen-Generator 
;     120 Zyklen:
; ----------------------------- 
; warte 120 Zyklen:
          ldi  R17, $28
WGLOOP0:  dec  R17
          brne WGLOOP0
; ============================= 
ret

Autor: Roger Steiner (edge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian Ulrich wrote:

> Was bitte sollte daran denn nicht funktionieren ?

entweder fasst dein uint8_t mehr als 8 bit oder dann wird die parity 
wohl kaum nach Spezifikation sein.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
;-------------parity aktualisieren
    cpi parity, 0
    brne wechsel
    rjmp sonst
wechsel:
    ldi parity, 0
    rjmp ende
sonst:
    ldi parity, 1

das ist aber mächtig kompliziert für
    eor parity, 0b00000001


logische Operation       Verwendung für
---------------------------------------
   ODER                  Bit setzen
   UND                   Bit löschen; Bit zum Abfragen ausmaskieren
   XOR                   Bit toggeln (aus 0 mach 1 und umgekehrt)

Autor: Christian U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>entweder fasst dein uint8_t mehr als 8 bit oder dann wird die parity
>wohl kaum nach Spezifikation sein.

ups...
copy&paste lässt grüssen beim umbau hab ich das aus der schleife kopiert 
und vergessen aus tmp data zu machen :p
muss natürlich so aussehen:
void PS2_init(void)
{
  PS2_DDR  |= ((1<<PS2_CLOCK)|(1<<PS2_DATA));
  PS2_PORT |= ((1 << PS2_CLOCK)|(1 << PS2_DATA));
}

void PS2_clock(void)
{
  _delay_us(15);
  PS2_PORT &= ~(1 << PS2_CLOCK)
  IO_set(PS2_CLOCK,1);
  PS2_PORT |= (1 << PS2_CLOCK)
  IO_set(PS2_CLOCK,0);
}

void PS2_send(uint8_t data)
{
  uint8_t tmp = data;
  uint8_t i;
  
  //Startbit
  PS2_PORT &= ~(1 << PS2_DATA)
  PS2_clock();
  //Daten
  for (i=0;i<8;i++)
    {
      if (tmp & 1)
        PS2_PORT &= ~(1 << PS2_DATA);
      else
        PS2_PORT |= (1 << PS2_DATA);
      tmp >>= 1; 
      PS2_clock();
    }
  //Parität
  if (data & 1)
    PS2_PORT &= ~(1 << PS2_DATA);
  else
    PS2_PORT |= (1 << PS2_DATA);
  PS2_clock();
  //Stopbit
  PS2_PORT |= (1 << PS2_DATA)
  PS2_clock();
  _delay_ms(1);
}

Autor: Roger Steiner (edge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian U. wrote:
> muss natürlich so aussehen:
> [snip]

Nicht wirklich. Das hat nichts mit parity zu tun. Du sendest lediglich 
das LSB nochmals.

Der assembler source von Moritz koennte diesbezueglich wohl eher korrekt 
sein. Aber wer will sich schon durch einen Meter bit-banging in asm 
hangeln.

Autor: Christian U. (z0m3ie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hast recht.
hat wohl eher durch zufall bei den 2 werten für die ich die routine 
geschrieben habe funktioniert.
  //Parität
  uint8_t parity = 0;
  tmp = data;
  for (i=0;i<8;i++)
    {
      parity += tmp&1;
      tmp<<=1;
    }
  if (parity & 1)
    PS2_PORT &= ~(1 << PS2_DATA);
  else
    PS2_PORT |= (1 << PS2_DATA);
  PS2_clock();
  //Stopbit

Autor: Roger Steiner (edge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian Ulrich

vom prinzip her kommts langsam, bloss wird tmp noch in die falsche 
richtung geshiftet und somit falsch berechnet. Ausserdem wird mit der 
addition die gerade paritaet gebildet. PS2 ist aber odd parity.

Zudem komm ich mit deinem Port handling nicht ganz klar, leben deine 
Daten in einer bit invertierten Welt?

Autor: Dirk Hofmann (arm-dran)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Christian Ulrich

nochmal ahjaaaa....

zufällig hab ich die PS2-PC Seite als TaktSlave emuliert und ist in 
vielen
Geräten 100% aktiv.
Ich weiß also wovon ich rede.

Schau Dir lieber nochmal Deinen Code an, bevor Du ihn 10mal korrigierst.

Dirk

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl Heinz: das mit dem eor werd ich sofort übernehmen, Danke!!!

Morgen werd ich den Code testen und verschönern, soweits geht.
Wenn alles klappt, dann kommt auch ne Empfangsfunktion rein, um ne 
exacte kommunikation mit dem PC zu erreichen. Empfangen ist ja 
eigentlich bloss umgekehrt Bits schieben. Wie Christian Ulrich schrieb:

> Aber nachzuschauen ob der DATA port für >
> 100us auf low ist und dann meine Clockroutine 11x aufzurufen und dabei
> nach jedem Aufruf den status von DATA in eien Variable zu schieben
> sollte kein Problem darstellen damit könnte man auch empfangen.

Gruss, Moritz

...doof kann man sein, man muss sich nur zu helfen wissen :-)

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HEy ich habe nochmal ne Frage, weil mei mir das nicht einwandfrei 
funktioniert mit der Tastatur.

Wenn ich den PC mit dem µC am PS2 boote, reicht es da, wenn ich CLOCK 
und DATA auf High lege, (der PC zieht sie ja dann auf Low, wenn er 
beschäftigt ist), ich müsste dann nur überprüfen, ob die Leitungen 
(wieder) high sind, und dann kann ich ihm Daten senden, richtig?

Also ignoriere ich quasi alle seine Anfragen zu ID, Einstellungen, usw.

Otto (Gast) schrieb:
> Für den PC ist die Welt in Ordnung,
> wenn die Leitungen High-Pegel haben.

Oder liege ich da falsch??? Funktionierts hats bis jetzt noch nicht, 
eventuell liegt aber noch ein Code- oder anderes Problem vor.

Gruss,
Moritz

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Moritz,

bei mir war es so - wenn eine Leitung auf "Low"
ist, meckert er beim "booten" über "keyboard error"
oder so.

Es was bei mir auch nicht so einfach, bis es
funktionierte - wenn ich mir recht erinnere,
wurde jede Taste sofort 1x erkannt, dann aber
erst wieder, wenn "ihr" "Release-Code" erkannt
wurde.

Gruß Otto

Autor: Dirk Hofmann (arm-dran)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Moritz

Es gibt zwei Optionen um die Leitungen wahlweise auf 0 zu ziehen.
1.) Um zu verhindern, daß die Tastatur Daten sendet (interner Puffer)

2.) Um der Tastatur mittzuteilen, daß der Master Daten an die Tastatur 
senden
möchte.

Der PC kommuniziert mit der Tastatur. Seine Anfragen zu ignorieren wird
keine korrekte Funktion zur Folge haben.

Dirk

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auf http://www.marjorie.de/ps2/ps2_keyboard.htm findet man einen 
möglichen Ablauf beim booten:

Tastatur: AA  Selbsttest bestanden         ;Keyboard controller init
Host:     ED  Setzen der Status-LEDs
Tastatur: FA  Acknowledge
Host:     00  Alle LEDs aus
Tastatur: FA  Acknowledge
Host:     F2  Lese ID
Tastatur: FA  Acknowledge
Tastatur: AB  Erstes Byte der ID
Host:     ED  Setzen der Status-LEDs       ;BIOS init
Tastatur: FA  Acknowledge
Host:     02  Num Lock LED an
Tastatur: FA  Acknowledge
Host:     F3  Wiederholrate einstellen     ;Windows init
Tastatur: FA  Acknowledge
Host:     20  500 ms / 30.0 Zeichen/sec
Tastatur: FA  Acknowledge
Host:     F4  Enable
Tastatur: FA  Acknowledge
Host:     F3  Wiederholrate einstellen
Tastatur: FA  Acknowledge
Host:     00  250 ms / 30.0 Zeichen/sec
Tastatur: FA  Acknowledge


Meint ihr, dass ich dieses komplizierte Startverfahren durchlaufen 
lassen muss, beim booten, nur dass ich dann am Ende "Pfeil Up" und 
"Pfeil down" senden kann?...
krass

Autor: Dirk Hofmann (arm-dran)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, so sieht es wohl aus.

Aber was soll daran kompliziert sein?

Wie gesagt, daß wichtige ist, mit ACK (FA) zu antworten, damit der PC
weiß, daß die Tastatur angeschloßen ist.
Wenn Du zum Beispiel Daten zum setzen der LEDs empfängst, dann 
bestätigst
Du das, musst ja aber deswegen keine einschalten.

Es ist eben wichtig, eine PS2 Tastatur zu emulieren.

Es ist nicht schwer aber man muß es tun. Sonst geht nix.

Dirk

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Moritz,

wie bereits beschrieben, reichte (bei mir):

- beide Leitungen high-Pegel beim "booten"
- anfänglich das "Totstellen" auf die Anfragen des Hosts und
- das Senden der Daten.

Sobald der Host Reaktionen zeigt, habe ich anfangs die
Übertragung abgebrochen.

Später habe ich es dann erweitert.

Gehe mal davon aus, wenn Dein Timing stimmt, das Startbit
und 8 Bit und das Stopbit gesendet werden, kommt auch
etwas bei "Deinem" PC an.

Otto

Autor: Moritz Greif (moritz-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ich probiers jetzt erstmal auf die Otto-Version aus, wenns nicht 
klappt, gibts die Dirk-Version. Bei der Dirk Version muss ich mich dann 
nochmal um das Empfangen kümmern, ist ja nochmal ein bissl Arbeit.
Danke,
Moritz

Autor: MisterMime (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus,

wie ich sehe arbeitet ihr gerade mit dem Tastaturprotokoll.

Ich wollte/will noch immer ein Gerät bauen, dass auf einen Tastendruck 
reagiert; Es soll nur "lauschen", mehr nicht. Es funktioniert aber immer 
noch nicht ;).

Könnetet ihr euch mal diesen Thread anschaun? :
Beitrag "AT-Tastatur - PC - µC "einschleifen" -> RS232"

Vielleicht hilft er auch ein bisschen.

Ich bin mir sicher, dass irgendwo ein einziger "wait"-Befehl fehlt, aber 
wo nur :).


Mfg

MisterMime

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo MisterMime,

das wird dem Moritz sicher weiterhelfen - nur Dir nicht.

Als ich damit gekämpft habe, habe ich zu "debug-Zwecken"
abwechselnd sowohl das Empfangene als auch das Gesendete
auf einem LCD ausgegeben - so habe ich dann so manche
Fehler erkennen können - speziell die Timing Probleme
könntest Du so überprüfen.

Gruß Otto


Autor: Marc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe vorhin diesen Beitrag eröffnet: 
Beitrag "PS/2 Protokoll auf AVR - Tastatur (Maus) emulieren, Fragen zur Schaltung und Programm"

und bin, nachdem ich etliche Male die Suche bemüht habe auf diesen 
interessanten Thread gestoßen.
Vielleicht kann mir ja hier jemand mit meinen grundsätzlichen Fragen 
helfen:

Wie sieht die physikalische Verbindung nun genau aus, wenn ich nur den 
uC an den PS/2 des PCs anschliessen möchte (keine Tastatur oder so 
dran)?

Wie löst man denn am besten die Initialisierung, so dass der PC 
überhaupt bereit ist Daten entgegen zu nehmen? (Ich habe auch gelesen 
was hier steht, nur dummerweise ist der Thread ohne eine endgültige 
Klärung abgerissen)

Um die Leitungen LOW oder HIGH zu setzen, reicht es doch eine 0 oder 
eine 1 an dem I/O auszugeben oder muss ich noch etwas beachten?

Wie bestimme ich das Timing um im richtigen Augenblick die Leitungen LOW 
oder HIGH zu setzen, brauche ich dazu den Timer0 (hat irgendwo mal 
jemand geschrieben) oder lässt sich das anders lösen?

Mit welcher Taktfrequenz sollte der atmega8 dann am besten laufen, 
reichen 4 oder 8 MHz oder sollten es schon 16 MHz sein?

Ein Beispiel Assembler Code, der z.B. einfach ein Zeichen in einer 
Schleife wiederholt an den PC sendet wäre und zum allgemeinen 
Verständnis bestimmt hilfreich.

Es wäre nett, wenn mir das vielleicht jemand erklären könnte oder mir 
vielleicht entsprechende Links zukommen lassen kann, ich bin noch neu 
was diese ganzen Mikrocontroller Geschichten angeht aber lernwillig...

Gruß,
Marc

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.