Probleme mit GLCD

Gast #608991
Lesenswert?

Sieht doch ganz gut aus.
Init ist ok. Deine Werte für Text/Grapharea
habe ich auch schon benutzt.

Das könnte man mal probieren:

  _Set(RD); in Checkbusy()
vieleicht doch in die while loop mit rein.

void WR_Cmd(u_char cmd, u_char state){
  Check_Status(state);
  _Data_Port = cmd;
  _Set(CD);
  _Set(RD);
  _Clear(WR);
  _Clear(CE);
wait(1);
  _Set(CE);
  _Set(WR);
}
Gast #609029
Lesenswert?

Dein Busy Check gefällt mir nicht.
Die Abfrage mit dem ? versteh ich nicht :(
Schande über mich. Nie selber benutzt.

So ungefähr sieht ein Busy-Check bei mir auf nem
Atmega aus:

void Check_Status(u_char state){    // Manual mode check
  u_char busy;
  _Set(CD); //einmal reicht
  _Set(WR); //einmal reicht
  do{
    _Clear(CE);
    _Clear(RD);
    wait(1);
    busy = _Data_Port;
               _Set(RD);
    _Set(CE);
  }while((busy & state) == state);
}
Gast #609034
Lesenswert?

Also bei deinem Vorschlag fällt mein buys-flag weg. Da müsstest du in 
der letzten Zeile aber
while((_Data_Port & state) == state); stehen haben.


void Check_Status(u_char state){    // Manual mode check
  bit busy = 1;
  while(busy){
    _Set(CD);
    _Set(WR);
    _Clear(RD);
    _Clear(CE);
    wait(1);
    busy = ((_Data_Port & state) == state)? 0:1;
    _Set(CE);
  }
  _Set(RD);

Mein Busy-Check is eigentlich das selbe.
Ich frage halt das Port ab und vergleiche es mit 0x03(STA0 & 1). Wenn 
Das Ergebnis( mittels dem ?)wahr ist bekomm ich ne 0 zurück und die 
while - Schleife wird beendet. Ansonsten wird ne 1 ins busy geschrieben 
und die while-Schleife läuft so lange bis da ne 0 daher kommt.

müsste doch funzn oder peil ichs grad net?
Gast #609061
Lesenswert?

>Das Ergebnis( mittels dem ?)wahr ist bekomm ich ne 0 zurück und die
>while - Schleife wird beendet.

Ne, deine Schleife ist schon korrekt, meine ist falsch.
Hab das mit dem ? grad mal nachgelesen.

  }while((busy & state) == state);
muss
  }while((busy & state) != state);
lauten. So stehts auch in meinem Quellcode.
Gast #609073
Lesenswert?

Also am Status Check liegt es aller Wahrscheinlichkeit nicht. Gut zu 
wissen aber :)

Nu muss ich mich weiter mühen um den blöden Fehler zu finden. Keine 
Ahnung was da net passt. Muss ich eigentlich noch was anderes 
berücksichtigen (außer set_address) wenn ich irgendeinen Buchstaben 
ausgeben will?

Was ich noch net ganz verstanden habe ist das mit der Text home address 
und der Graph home address (CGRAM & CGROM hab i a net verstanden). Was 
ist eigentlich damit gemeint? Wird in diesem Bereich der grad 
ausgegebene Text(Grafik) zwischengespeichert oder was geschieht hierbei?
Gast #609098
Lesenswert?

>Was ich noch net ganz verstanden habe ist das mit der Text home address
>und der Graph home address (CGRAM & CGROM hab i a net verstanden). Was
>ist eigentlich damit gemeint? Wird in diesem Bereich der grad
>ausgegebene Text(Grafik) zwischengespeichert oder was geschieht hierbei?

Ja, so ist es. Dein Display hat ein SRAM hinten drauf !
Die Texthomeadress gibt an wo dein Textbereich startet.
Die Graphhomeadress gibt an wo dein Grafikbereich startet.
Normalerweise lege ich den Textbereich vor den Grafikbereich.
Da muss man aber je nach Einstellung etwas aufpassen, denn beide
dürfen sich nicht überschneiden.

Die Länge des Textbereiches ist abhängig davon ob du
im 6 Bit oder 8 Bit Textmodus arbeitest. Die Höhe eines
Zeichens ist 8 Pixel. Habe gerade gesehen das du ein 240x128
Display in der Headerdatei hast. Stell die Graphhomeadress
besser mal auf 0x300. Wirst gleich sehen warum.

Nehmen wir mal dein Display mit 240x128.
Jedes Zeichen ist 8 Pixel hoch. Also 16 Textzeilen für dein Display.
Im 8 Bit Modus hast du 30 Zeichen pro Zeile, im 6 Bit Modus
40 Zeichen pro Zeile.

Im 8 Bit Modus brauchst du für 16 x 30 Zeichen Speicher.
Das sind 480 Bytes. 0x200 als Graph home adress ist also ok.

Im 6 Bit Modus brauchst du für 16 x 40 Zeichen Speicher.
Das sind 640 Bytes. 0x200 als Graph home adress ist nicht mehr ok.

Das blöde an der Geschichte:
Der 6 Bit Modus ist für Textdarstellung optimal. Sieht einfach besser
aus und mehr Zeichen pro Zeile darstellbar. Dann läuft
aber auch die Grafik nur mit 6 Bit ! Bei 8 Bit sieht der Text sch..lecht
aus aber mit Grafik ist das arbeiten einfach schneller.

Wenn dein SRAM auf dem Display groß genug ist bekommst du möglicherweise
sogar mehrere Bildschirme in den Speicher !

Aber das ist ne andere Geschichte.
 Holger
Gast #609115
Lesenswert?

tolle Erklärung! Danke.
Wie ist das eigentlich gemeint mit den Bildschirmen? Denk mal so:
Hab da z.B. einen "Willkommens Bildschirm",einen "Menu Bildsch." usw. 
Ist das so richtig oder nicht? Wenn ja...wohin speichere ich diese? In 
den Grafikbereich? Im Textbereich wäre ja net Platz für den Code eines 
ganzen Bildschirmes. Oder sollte man da besser auf einen externen 
Speicher zurück greifen?
Gast #609146
Lesenswert?

Ich glaub das wird ne längere Aktion ;)
Und dein Display läuft noch nicht mal.

Na gut ich versuchs mal:
Beim T6963 gibt es erstmal zwei Sorten Bildschirme.
Den Textbildschirm und den Grafikbildschirm. Beide
werden einfach übereinandergelegt (ODER Verknüpfung).
Könnte sein das das ODER auch per Parameter auf EXOR
geändert werden kann, aber das habe ich noch nicht probiert.

Textbildschirm und Grafikbildschirm sind unabhängig
voneinander. D.h. du kannst den Textbildschirm löschen
ohne den Grafikbildschirm zu löschen. Der bleibt dann
einfach stehen. Umgekehrt gehts genauso. Es sind ja
zwei verschiedene Speicherbereiche.

Du kannst bei genügend Speicher (SRAM auf dem Display !)
mehrere Textbildschirme und Grafikbildschirme benutzen.
Das musst du dem T6963 aber auch mitteilen.
Wenn du z.B. zwei Textbildschirme nutzen möchtest,
verschiebst du einfach die Graph home adress weiter nach oben
(z.B. 0x600) um Platz für zwei Textbildschirme zu machen.

Dann hast du einen sichtbaren Teil des Textbildschirmes
und einen unsichtbaren Teil. Es können ja nur 16 Textzeilen
angezeigt werden. Um in den unsichtbaren Teil des Textbildschirmes
zu kommen programmierst du die Text home adress einfach neu.
Das geht auch Zeile für Zeile (Scrolling).

Beim Grafikschirm kannst du das genauso machen.
Mein Display hat genug Speicher für zwei Grafikschirme.
Die kann ich durch umprogrammieren der Graph home adress
pixelweise rauf und runterscrollen.

War das verständlich ?
 holger
Gast #609241
Lesenswert?

Denk das ne weitere Fehlerquelle vielleicht ne zu lange Datenleitung 
ist. War beim meinem LCD auch mal der Fall. Die Datenleitung war an die 
20cm. Aber trotzdem hab ich am LCD was gesehen nur das anstatt 
Elektronik z.B. Ektink gestanden ist. hmm...kannst da mal mein main 
anschauen? vielleicht liegts eher  in der Software
Gast #609259
Lesenswert?

>In deiner main steht das du 12 Millionen mal pro Sekunde

naja nicht ganz 12 Millionen mal ... aber Pause machen ist sicher 
hilfreich ... und das nicht nur beim display. Hab mal acht Stunden nach 
einem Fehler gesucht und am nächsten Tag fiel mir der Fehler auf Anhieb 
auf.
Gast #609504
Lesenswert?

Guten Morgen.

Hab mich so gefreut als ich das gelesen habe (mit P1). Is ja 
logo...Voller Freude geändert und ... NIX .
Ich packs nich...keine Ahnung was ich noch alles probieren soll

Hier is mal mein aktuelles C-File(net all zu viel geändert)

lg Cri
Angehängte Dateien:
Gast #609512
Lesenswert?

jap,tut er. Hab ich in ner FUnktion (Reset() ) geschrieben.
Dachte zuerst auch das es das sein kann also hab ich dann die Fkt. 
geschrieben . Setze vor der Init einmal Reset...aber was anderes als NIX 
kommt da net :/
Gast #609519
Lesenswert?

Also ich bin einer der dümmsten die ich kenne. Habe die Anschlüsse am 
GLCD genau verkehrt gehabt. Dort wo P1^0 sein sollte war P1^7 usw. ! 
Jetzt seh ich am LCD wenigstens mal einen Haufen Müll! Aber das ist ja 
schon mal was. Ist das normal das man nach der Init einen eher 
undefinierten Screen hat?

das mit dem Warten nach dem Reset werd ich auch gleich ausprobieren.
Gast #609535
Lesenswert?

Ja, der "Müll" ist normal, weil nach dem Einschalten das SRAM auf dem 
Display einen undefinierten Zustand hat, alle Bytes sind mit zufälligen 
Werten gefüllt. Wenn du das Display-ON-Kommando sendest, bevor du das 
RAM löschst, siehst du die zufälligen Werte direkt aufm Display.

Der Display-On Befehl sollte daher einer der letzten Befehle der 
GLCD-Initialisierung sein. Das RAM-Löschen gehört eben zur 
Initialisierung.

Ralf
Gast #609612
Lesenswert?

Hi Holger.

Ich kann nicht einen beliebigen Buchstaben am LCD setzen. Schreib ich 
z.B. set_addr(0x0); und wr_c(); dann fängt er beim 4ten Pixel(in der 
Reihe) mit C an und füllt es mir bis nach unten auf (nur diese eine 
Spalte wo eben das c steht). Aber das macht er nur an der pos 0. sonst 
rührt sich nichts :/

Hast du ne Ahnung was da sein kann?
Gast #609956
Lesenswert?

>Hast du ne Ahnung was da sein kann?

Nein. Da bin ich auch etwas ratlos. set_addr() sieht richtig
aus. Dein wr_a() sieht auch ok aus. Der Opcode
für Write mit increment adress stimmt. Hat die Init nicht
geklappt ? Probier doch mal folgendes:

void init_glcd(void){
  WR_Data((u_char)(_Graph_H_Addr & 0xFF), _STA_01);    // Low byte
  WR_Data((u_char)(_Graph_H_Addr>>8), _STA_01);    // High byte
  WR_Cmd(_Set_Graph_H_Addr, _STA_01);

  WR_Data(_Area, _STA_01);          // Low byte
  WR_Cmd(_Set_Graph_Area, _STA_01);

  WR_Data((u_char)(_Text_H_Addr & 0xFF), _STA_01);    // Low byte
  WR_Data((u_char)(_Text_H_Addr>>8), _STA_01);    // High byte
  WR_Cmd(_Set_Text_H_Addr, _STA_01);

  WR_Data(_Area, _STA_01);          // Low byte
  WR_Cmd(_Set_Text_Area, _STA_01);

  WR_Cmd((_Set_GLCD_Mode | _OR | _CGROM ), _STA_01);
  WR_Cmd((_Set_GLCD_Attributes | _AllOn), _STA_01);
}

/* ---- Set address pointer 
----------------------------------------------*/

void set_addr(unsigned int addr){
  WR_Data( (u_char)(addr & 0xFF) , _STA_01);    // Low byte
  WR_Data( (u_char)(addr>>8) , _STA_01);    // High byte
  WR_Cmd( _Set_Address_pointer , _STA_01);
}
#609990
Lesenswert?

Cri wrote:
> volatile? Wieos?

Es ist die alte Sache und der klassische Fehler; in der Schleife liest 
Du einen Wert ein ("busy"), der aber in der Schleife nicht weiter 
verändert wird (nur halt immer neu eingelesen). Je nach Compiler und 
Optimierungsstufe könnte der Compiler auf die Idee kommen, das "busy" 
schon vor der Schleife einzulesen und innerhalb der Schleife nur den 
eingelesenen und in einem Register gehaltenen Wert zu verwenden, was 
natürlich dazu führt, daß das Busy-Flag des LCD's überhaupt nicht mehr 
beachtet wird. Das kann - muß aber nicht - zu groben Fehlern führen.

Wenn man "busy" mit "volatile" definiert, wird diese Optimierung 
unterlassen und das Busy-Bit wird immer korrekt verarbeitet. Man kann 
aber mit guter Wahrscheinlichkeit Glück haben und der Compiler optimiert 
das nicht - aber der Code ist dann nicht so portabel und im strengen 
Sinne nicht korrekt.

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