Guten Abend,
als erstes wäre es vielleicht gut, zu erwähnen, dass ich die bekannten
seiten wie majorie und beyondlogic bereits kenne und durchgelesen habe,
und auch mit dem protokoll an sich und der dabei entstehenden software
kein problem habe....
Mein Problem liegt eher bei der Verbindung zwischen Keyboard und
Controller bei den leitungen DATA und CLOCK... undzwar habe ich auf
vielen schaltplänen zusätzlich zwischen dem einfachen kabel zwischen dem
entsprechenden Pin am PS2-port und dem Pin am Controller auch noch eine
Leitung zu VCC mit zwischenwiderstand gesehn.... allerdings nie mit
erklärung... und genau die hätte ich gerne.... undzwar habe ich
vermutet, dass diese leitung dafür da ist, um eben im ruhezustand ein
High-signal zu haben... allerdings ist mir jetzt völlig schleierhaft,
wie sowohl keyboard, als auch Controller die Leitung auf low ziehen
können sollen, bzw. sie so steuern, dass der jeweils andere einen
low-zustand ausliest... Also, mag sein, dass ich etwas völlig Banales
übersehen habe, aber ich kann den Sinn darin nicht erkennen...
Und zusätzlich in verbindung mit obigen wäre noch die Frage, ob ich das
Datenrichtungsbit setzen muss, oder nicht... hatte dazu schon in anderen
posts dieses thema betreffend hier etwas gelesen, jedoch keine antwort
gesehen... und bin mir selber nunmal unschlüssig, da ich ja eigentlich
einen ausgang bräuchte, wenn ich das signal irgentwie steuern will,
jedoch andererseits einen eingang.... also, um ehrlich zu sein bin ich
durch die masse an widersprüchlichen Informationen, die ich dazu finden
konnte etwas erschlagen und wüsste gerne, welchen davon ich vertrauen
kann, und welchen nicht, bzw. wie diese bidirektionale datenleitung denn
letztlich steuerbar ist...
Liebe grüße
Elrohir
> PS2-port und dem Pin am Controller auch noch eine> Leitung zu VCC mit zwischenwiderstand gesehn.
Sowas nennt man Pullup.
Jeder Teilnehmer kann nur die entsprechende Leitung auf GND ziehen oder
hochohmig sein. Damit in der hochohmigen Phase ein definierter Ruhepegel
anliegt, gibt es diese Pullups.
Edit:
Dort findest du eine Skizze zum Thema:
http://www.computer-engineering.org/ps2protocol/
Es reicht aus, wenn du das Satzende mit 1 Punkt markierst ;-)
Oh, und was ich noch hinzufügen wollte:
Aus den mir ergebenden logischen schwierigkeiten bei einer leitung zu
vcc habe ich die verbindung ohne diese hergestellt... jedoch sendet mir
das keyboard keine bestätigung des selbsttestes, sondern liefert einen
dauernden clock-impuls, während die Datenleitung die ganze zeit auf low
liegt.... desweiteren blinken während des selbsttestes (falls er
stattfindet) nicht die LEDs am keyboard, wenn ich den strom einschalte,
was ja beim pc-start direkt zu beginn passiert.... verwirrt ist
An lothar miller:
ahh, danke für die erklärung. In dieser Hinsicht würde es doch
ausreichen, die internen Pull-ups einzuschalten, wenn ich mich nicht
irre.
Den von dir verlinkten Artikel kannte ich zwar bereits, doch habe
zugegebenermaßen erst jetzt durch deinen beitrag verstanden, wie das
gemeint ist. in der hinsicht nochmal danke. Somit müsste ich den Pin als
eingang und mit pullup schalten, und nur, wennn ich die Leitung low
ziehen will als ausgang setzen, richtig?
> In dieser Hinsicht würde es doch ausreichen, die internen Pull-ups> einzuschalten, wenn ich mich nicht irre.
Nein, die sind für "übliche" PS2-Devices zu hochohmig...
10 KOhm sind bei mir im Einsatz. Das ganze funktioniert problemlos.
Wenn er dauernd den Clock sendet heißt dass, dass er ein dauerndes DATA
LOW empfängt (=startbit). Wenn du wieder was zurückkriegen willst musst
du die Leitung wieder auf HIGH hochlassen, d.h. den Pin am µC auf High
Impedanz stellen (DDR 0; PORT 0). Im PIN steht dann der Zustand.
Hm, in der tat...
Jetzt habe ich die Ports als eingänge gelassen, und auch den Pull-up
widerstand ausgelassen..
Code folgendermaßen:
1
voidwaitForClockHigh(void){
2
while(PIN_PS2&(0<<PS2_CLK)){}
3
return;
4
}
5
6
voidwaitForClockLow(void){
7
while(PIN_PS2&(1<<PS2_CLK)){}
8
return;
9
}
10
11
voidreadByte(char*byte){
12
waitForClockLow();
13
if(PIN_PS2&(1<<PS2_DATA))return;else{
14
charpos;
15
*byte=0x00;
16
for(pos=(char)7;pos>=(char)0;pos--){
17
waitForClockHigh();
18
waitForClockLow();
19
if(PIN_PS2&(1<<PS2_DATA))(*byte)|=(1<<pos);
20
}
21
22
waitForClockHigh();
23
waitForClockLow();
24
waitForClockHigh();
25
waitForClockLow();
26
waitForClockHigh();
27
PORTA|=(1<<LED0);
28
return;
29
}
30
}
Allerdings bekomme ich von der Tastatur zuerst Ein Byte was mir...
nunja.. völlig schleierhaft ist, da es weder 0x00, noch 0xAA als
bestätigung für den selbsttest noch 0xFF ist... und danach bleibt die
Data-leitung im High-zustand, die Clockleitung scheint jedoch weiterhin
zu variieren... dies jedoch natürlich nur, wenn ich die prüfung des
startbits weglasse, da dies ebenfalls auf high ist... Nur warum scheint
die Clockleitung dauerhaft noch aktiv zu sein?
Uh, zudem ist mir grad aufgefallen, das ja doch das LSB zuerst gesendet
wird, nicht das MSB... aber selbst, wenn ich das ändere ist das erste
von der tastaturkommende byte nicht 0xAA. und das clocksignal ist
natürlich weiterhin stetig vorhanden. Mir ist zudem aufgefallen, wenn
ich das Data-DDR-bit zu beginn setze, dann leuchten, wie beim start des
PC's kurz alle LEDs beim start auf, jedoch empfange ich dann gar nichts
von der tastatur, was wohl natürlich an dem DDR-bit liegt. Wenn ich das
direkt danach jedoch wieder ausschalte, leuchten je nach Zeitabstand
entweder die LED's nicht, oder ich bekomme nichts von der Tastatur.
hmm, also ich habe jetzt einfach mal alle bytes von der tastatur kommen
lassen, unter der bedingung, dass DDR = 0 und PORT = 0 ist. undzwar so
lange, bis ein byte nichtmehr 0 ist. Aufgehört hat diese Schleife dann,
als ein byte der zahl 0b10000000 ankam. also, das letzte bit (MSB) war
high. Dies wird vermutlich aber eher damit zusammenhängen, dass danach
die Data-leitung dauerhaft auf high steht, während die clock-leitung
fröhlich weiter ihren takt angibt. Nunja, hat jemand vllt. noch einen
Rat, was ich tun kann?
Eine weitere interessante auffälligkeit ist mir bei überprüfung des
CLK-Zustands aufgefallen.
Undzwar hatte ich die waitForClockHigh-methode bisher so aufgeschrieben:
1
voidwaitForClockHigh(void){
2
while(PIN_PS2&(0<<PS2_CLK)){}
3
return;
4
}
Daraus folgte bissher das schon beschriebene Ergebnis. Nun habe ich
diese Methode jedoch wie folgt abgeändert und nun liest er gar kein Byte
mehr aus, da das CLK-Signal kein einziges mal auf High zu gehen scheint.
1
voidwaitForClockHigh(void){
2
while(PIN_PS2&~(1<<PS2_CLK)){}
3
return;
4
}
Was mir nur leider nun gar nicht mehr weiterhilft, da ich ja wie schon
beschrieben DDR und PORT jeweils auf 0 gesetzt habe bei den Pins für CLK
und DATA.