Frage zu Display-Code

Gast #1599050
Lesenswert?

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
#1599059
Lesenswert?

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.
Gast #1599068
Lesenswert?

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
#1599083
Lesenswert?

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)
Gast #1599085
Lesenswert?

>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
Persönliche Seite #1599087
Lesenswert?

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.
Gast #1599137
Lesenswert?

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
Gast #1599559
Lesenswert?

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
Angehängte Dateien:
Gast #1599756
Lesenswert?

>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
Gast #1599903
Lesenswert?

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
#1599922
Lesenswert?

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.
#1599979
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren