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
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.
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.