Hey Bin gerade beim Ansteuern eines Graphikdisplays 128x64 und habe ein fertiges glcd.c als Vorlage für genau den gleichen Controller. Versuche nun einen Punkt auf das LCD zu schreiben, was auch zwar nicht 100%ig funktioniert (Pixel hüpft hin und her), aber da bin ich dran. Im Originalcode gibt es da eine Codepassage, die ich nicht ganz verstehe. Festgelegt wird die Stelle des Punktes am Display: LcdInstructionWrite (X_ADRESS + (Yaxis / 8)); LcdInstructionWrite (Y_ADRESS + (Xaxis); LcdDataWrite (DataRead | (1 << (Yaxis % 8))); Warum nehme ich bei der X-Adresse den Wert der Y-Koordinate und umgekehrt? hannes
Hannes schrieb: > Festgelegt wird die Stelle des Punktes am Display: > > LcdInstructionWrite (X_ADRESS + (Yaxis / 8)); > LcdInstructionWrite (Y_ADRESS + (Xaxis); > LcdDataWrite (DataRead | (1 << (Yaxis % 8))); > > Warum nehme ich bei der X-Adresse den Wert der Y-Koordinate und > umgekehrt? Sieht so aus, als ob da eine logische 90° Drehung des Displays mit eingebaut wurde. Vielleicht ist es auch im Datenblatt des Displays so bezeichnet, dass X und Y vertauscht sind. Vielleicht hatte deine Vorlage auch einen Fehler in der Achsbezeichnung, der zwar behoben aber nicht konsequent durchgezogen behoben wurde.
Danke erstmal. Beim Controller handelt es sich um den KS108, wobei ich im Datenblatt keinen Hinweis auf die 90°-Drehung gefunden habe. Außerdem stimmt die Anzeige am Display, denn wenn ich die Koordinaten vertausche, dann ist der Punkt komplett woanders. Und warum nehme ich beim lcdDataWrite dann wieder nur die Y-Achse und nicht auch die X-Achse? hannes
Im allgemeinen hat sich der Ansatz "Im Datenblatt nachsehen" bei solchen und ähnlichen Problemen ziemlich bewährt ;-) Da sollte alles notwendige drinnstehen. Oliver
Habe grade die Definition in einem Beispielprogramm gefunden. Die Koordinaten sind wirklich vertauscht. Dankeschön nochmal. hannes
Hannes schrieb: > Danke erstmal. > Beim Controller handelt es sich um den KS108, wobei ich im Datenblatt > keinen Hinweis auf die 90°-Drehung gefunden habe. Nein. Das hast du misverstanden. Viellicht hat sich derjenige, von dem du den Code geklaut hast, eine 90° Drehung eingebaut (was weiß ich, weil ihm zb die Anschlüsse beim Einbau in ein Gehäuse im Weg waren, oder so was ähnliches)
>Beim Controller handelt es sich um den KS108
Die Info kam etwas zu spät.
Der KS108 addressiert den 64x64-Bildschirm über acht 8-Bit hohe Zeilen
(X=0..7) á 64 Bit (Y=0..63). Damit sind in dessen Konvention X und Y
gegenüber der üblichen Anordnung vertauscht. Dein Code berücksichtigt
das.
Das steht aber wirklich alles im Datenblatt ;-)
Oliver
Hannes schrieb: > Beim Controller handelt es sich um den KS108, wobei ich im Datenblatt > keinen Hinweis auf die 90°-Drehung gefunden habe. Außerdem stimmt die > Anzeige am Display, denn wenn ich die Koordinaten vertausche, dann ist > der Punkt komplett woanders. Da ist auch nix mit Drehung... Die Horizontale wird tatsächlich als "Y" bezeichnet, siehe "Instuctions". > Und warum nehme ich beim lcdDataWrite dann wieder nur die Y-Achse und > nicht auch die X-Achse? Nicht verwirren lassen... Was für dich X ist lt. Datenblatt Y.
Was jetzt aber immer noch nicht passt, ist, dass wenn ich die Startzeile (Z-Addresse) auf 0 setzten will, also an den Anfang des Displays, der Punkt flackert. Es leuchtet nicht nur ein Pixel sondern in kurzen abwechselnden Abständen beide. Woran liegt das wieder? hannes
So, der Code jetzt hinzugefügt. Fast alle Probleme sind beseitigt, bis auf eines: In der Funktion lcdSetDot() ist vor dem dataRead() ein lcdInstructionWrite(Y). Dieses setzt mir den Datenport PORTD des Displays auf 0x40. Eben um auf die erste Spalte zuzugreifen. Wenn ich jetzt dataRead() aufrufe, gibt mir das natürlich 0x40 zurück, was aber nicht sein soll. Denn beim ersten Durchlauf steht am Display ja noch nichts. Wenn ich den Port jetzt vorher auf 0x00 setze, bekomme ich keine vertikale Linie zusammen, sondern immer nur einen Punkt pro Spalte. In meiner Vorlage ist es genauso programmiert, deswegen bin ich jetzt ein wenig ratlos. Kann da wer weiterhelfen? hannes
>Wenn ich jetzt dataRead() aufrufe, gibt >mir das natürlich 0x40 zurück, ... Datenblatt lesen. Code lesen. POPRTC und PORTD mit #defines lesbare Namen geben. Der Display-Befehl "Read display data" liest das Display an der aktuellen Leseadresse aus. Wenn das Display leer ist, sollte da immer 0x00 gelesen werden. Was die aktuelle Leseadresse ist, und warum man da zweimal lesen muß, steht auch im Datenblatt. Oliver
Das mit dem Dummy-Read und der Leseaddresse habe ich schon gefunden im Datenblatt. Das macht mir auch keine Sorgen mehr. Aber nur rein von der Logik her, wenn ich eine Instruction auf den PORTD ausgebe, und im nächsten Schritt diesen wieder einlese, ohne den Port zu löschen, dann ist doch das jeweilige Bit noch gesetzt. Ich habe es jetzt so gelöst, das ich auf dataRead() verzichte und stattdessen meinen Befehl direkt nach dem lcdDataWrite() noch auf eine Variable schreibe. Diese simuliert mir also den dataRead. Trotzdem möchte ich wissen, wie ich das Problem umgehen kann. hannes
Hannes schrieb:
> Trotzdem möchte ich wissen, wie ich das Problem umgehen kann.
Da liegt anscheinend einiges im argen.
Ich habe jetzt nicht grossartig analysiert, aber zb das hier
void lcdWaitBusy()
{
PORTD = 0xff;
unsigned char read;
read = PORTD;
PORTC = 0b00000000;
triggerH;
lcdDelay(1);
triggerL;
while(read & 0x7f == 0x80);
}
Das ist doch Müll
* Von einem Pin wird eingelesen, indem man das PIN Register ausliest?
* Wie soll sich in der while Schleife ganz unten, die Variable read
jemals verändern?
Aber da du an dieser Stelle schon DEN Fehler machst, einen Port
einzulesen indem du das PORT Register liest, denke ich, dass du den
Fehler auch an anderen Stellen gemacht hast.
Karl heinz Buchegger schrieb: > hler machst, einen Port > einzulesen indem du das PORT Register liest Wie mach ichs denn dann richtig? hannes
In der Codesammlung gibt es einige gut funktionierende libs für den KS0108. z.B. diese hier: Beitrag "KS0108 GLCD Routinen" Oliver
Theoretisch würds ja so funktionieren: DDRD = 0x00; //setzt mir PORTD als Eingang. read = PORTD; oder eben gleich PIND einlesen read = PIND; So entnehme ich das dem Datenblatt des ATMega8. hannes
Hannes schrieb: > Theoretisch würds ja so funktionieren: > > DDRD = 0x00; //setzt mir PORTD als Eingang. > read = PORTD; > > oder eben gleich PIND einlesen > > read = PIND; > > So entnehme ich das dem Datenblatt des ATMega8. Dann liest du falsch. Arbeite bitte die ersten Kapitel im Tutorial durch. Zwischen den beiden gibt es einen grundlegenden Unterschied. Vor allen Dingen, weil das Auslesen von PORT etwas völlig anderes macht als du vermutest (du liest damit den Einschaltzustand der Pullup-Widerstände aus). Den Zustand der physikalischen Pins erhält man, indem man das PIN Register ausliest. Punkt.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.