mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frage zu Display-Code


Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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

Bewertung
0 lesenswert
nicht 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.

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im allgemeinen hat sich der Ansatz "Im Datenblatt nachsehen" bei solchen 
und ähnlichen Problemen ziemlich bewährt ;-)

Da sollte alles notwendige drinnstehen.

Oliver

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe grade die Definition in einem Beispielprogramm gefunden.
Die Koordinaten sind wirklich vertauscht.

Dankeschön nochmal.

hannes

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

Bewertung
0 lesenswert
nicht 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)

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tom M. (tomm) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Woran liegt das wieder?

Am Code?

Oliver

Autor: Hannes (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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

Bewertung
0 lesenswert
nicht 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.

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> hler machst, einen Port
> einzulesen indem du das PORT Register liest

Wie mach ichs denn dann richtig?

hannes

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der Codesammlung gibt es einige gut funktionierende libs für den 
KS0108. z.B. diese hier:
Beitrag "KS0108 GLCD Routinen"

Oliver

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

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

Bewertung
0 lesenswert
nicht 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.

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, danke. Werd ich mich mal dran machen.

hannes

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.