Forum: Mikrocontroller und Digitale Elektronik Probleme bei T6963C initialisierung (C)


von Marco (Gast)


Lesenswert?

Hallo!
Seit Tagen sitze ich nun an meinem GLCD (240x128, T6963C, 
http://www.lcd-module.de/deu/pdf/grafik/dip240-7.pdf) und versuche ein 
ganz normales Zeichen auszugeben. Ich habe mich hier im Forum und 
diversten Datenblättern zum Thema Initialisierung schlau gemacht, doch 
alles was das Display anzeigt sind "?", undzwar 30x16 Stück, also auf 
dem ganzen Display... Was mache ich falsch? Hat jemand eine Idee? 
Ähnliche Erfahrungen? Danke!

Hier mein Code:
#include <avr/io.h>
#include <util/delay.h>

#define CD PC0
#define WR PC1
#define RD PC2
#define CE PC3
#define RST PC4

#define DATA PORTD
#define CONTROL PORTC



void long_delay(uint16_t ms)
{for(; ms>0; ms--) _delay_ms(1);}

void CLOCK(void) {
  CONTROL &= ~(1<<CE);      //Low-Flanke am CE
  long_delay(10);          //DELAY
  CONTROL |= (1<<CE);        //High-Flanke am CE
  }

void datawrite(int d){

  CONTROL &= ~(1<<CD);      //DATA INPUT
  DATA = d;
  CLOCK();
  }

void cmdwrite(int c){
  CONTROL |= (1<<CD);        //COMMAND INPUT
  DATA = c;
  CLOCK();
  }


int main(void)
{


DDRD = 0xff;          //Datenport als Ausgang
DDRC = 0xff;          //Controlport als Ausgang

CONTROL &= ~(1<<RST);      //RESET 10ms
//long_delay(10);

CONTROL |= (1<<CD) | (1<<RD) | (1<<RST) | (1<<CE);     //Reset aus, 
Lesen aus, Command schreiben ein

CONTROL &= ~(1<<WR);                  //Schreiben ein


cmdwrite(0x80);          // Mode set: use CG ROM, OR text and graphics 
0x80

datawrite(0x00);           //TEXT HOME ADRESS
datawrite(0x00);
cmdwrite(0x40);

datawrite(0x1E);        //TEXT AREA SET number of columns: 30
datawrite(0x00);
cmdwrite(0x41);

datawrite(0x00);        //GRAPHIC HOME ADDRESS
datawrite(0x02);
cmdwrite(0x42);

datawrite(0x1E);        //GRAPHIC AREA
datawrite(0x00);
cmdwrite(0x43);

datawrite(0x00);        //ADDRESS POINTER SET
datawrite(0x00);
cmdwrite(0x24);

datawrite(0x21);        //WRITE "A"
cmdwrite(0xC0);

cmdwrite(0b10010100);      // DISPLAY ON

    while(1)
    {}

    return 0;
}

von marvin m. (Gast)


Lesenswert?

Mach doch mal in der Funktion CLOCK() noch ein weiteres delay ans Ende 
(also nach der High-Flanke). Deine Impulse sind sehr kurz und außerdem 
fragst Du nicht ab, ob das LCD bereits mit der Abarbeitung des 
vorhergehenden Befehls fertig ist.

von Marco (Gast)


Lesenswert?

Danke Marvin!
Ich habe die Statusabfrage noch rausgelassen, da ich zunächst einmal 
Schritt für Schritt vorgehen wollte. Ich habe es in der CLOCK Funktion 
jetzt mit jeweils einem 100ms delay nach der negativen, als auch 
positiven Flanke gemacht, doch das Display zeigt wieder nur quatsch. 
Diesmal keine Fragezeichen, sondern Slashes ("/") - dahinter sieht man 
ganz wenig die Fragezeichen flackern...

von Harry (Gast)


Lesenswert?

Hallo,
nur ne kurze Frage: Wieso benutzt Du nicht die bereits hier vorhandenen 
Librarys für das Display erstmal um zu sehen das es grundsätzlich geht 
und nicht durch vielleicht verkabelungsprobleme oder anderer Dinge murks 
drin ist?

von Harry (Gast)


Lesenswert?

Ich habe eben gesehen das Du PortC für die Control-Signale nutzt. Oft 
wird in den AVRs der PortC für die JTAG's genutzt evtl. Fuses falsch 
gesetzt?
Ich weiß nicht welchen AVR Du nutzt um es genauer zu sagen.

Harry

von Marco (Gast)


Lesenswert?

Hi Harry!
Ich habe einige der hier erhältlichen Libraries probiert, doch die haben 
genausowenig funktionier. Und ich fand es übersichtlicher selber den 
Code zu schreiben, als die großen libraries von anderen durchzuwälzen. 
Ich verwende den Atmega 8 und habe bisher nichts an den Fuses gemacht... 
Ich werde es mal am PortB probieren. Vielen Dank

von Harry (Gast)


Lesenswert?

Hm, hab eben mal nachgesehen... der ATMEga hat kein JTAG (meine ich 
zumindest)
PortD ist der einzige der für Daten geht da er 8 bit breit ist, PortC 
für Control-Port sollte gehen.

Wenn ich mir deinen Code so anschaue, mir fehlt irgendetwas was die 
beiden Pins = RD/WR verwendet. Ich denke zum schreiben braucht es nicht 
nur CE sondern eben auch /WR und zum lesen eben auch /RD.

Ich habe ebenfalls ein 240x128 Display mit T6963C und habe beinahe alle 
hier verfügbarer Standart Routinen getestet und sie laufen nach 
Pin-Anpassung alle.
Vielleicht ist bei deiner Hardware noch ein Fehler?

Also ich würde wirklich erstmal versuchen eine funkt. Library zum laufen 
bekommen. Normalerweise mußt Du nur die Pins,Proz und Takt anpassen dann 
sollte das gehen.
Wichtig ist wahrscheinlich das Du eine kleine Lib. findest da Du "nur" 
den Mega8 verwendest. Die meisten sind für größere Prozessoren 
geschrieben.
Aber wenn Du z.B. nur die reine Init-Routine übernimmst und z.B. 
Pixelsetzen, und/oder Text müßte es gehen.

Gruß und noch nen schönen Sonntag
Harry

von Marco (Gast)


Angehängte Dateien:

Lesenswert?

Ich bin am Ende!
Hardwaretechnisch ist am Display alles korrekt angeschlossen, auch die 
Singale an den Ports sind korrekt. Das Display zeigt nun im "EXOR"-Modus 
das hochgeladene Bild, im "OR"-Modus ist es invertiert(Fragezeichen 
weiß, rest blau) und im "Text Only" Modus zeigt das Display absolut 
nichts an...

WR ist dauerhaft enabled, da ja nur geschrieben wird. Auf die 
Statusabfrage wird verzichtet, da 100ms ja wohl mehr als genug sein 
sollten die Befehle zu verarbeiten.

von Marvin M. (Gast)


Lesenswert?

Hmmm - seltsam. Dass das LCD überhaupt etwas anzeigt, ist schonmal ein 
gutes Zeichen, denn es wird initialisiert.
Was ich gerade in Deinem oben geposteten Code sehe: Wenn Du Daten 
schreiben willst, musst Du den C/D-Pin löschen.

von Ralf (Gast)


Angehängte Dateien:

Lesenswert?

Ich glaube nicht, dass die Signale richtig ankommen, weil ich nicht 
sehe, wo die READ- und WRITE-Signale wieder inaktiv werden. Und der 
T6963C übernimmt Daten erst dann, wenn WR wieder hochgeht bzw. gibt 
Daten solange aus, bis RD wieder hochgeht. Und das sehe ich bei deinen 
DATAWRITE bzw. CMDWRITE Funktionen nicht. Das hatte Harry bereits 
erwähnt, hast du das inzwischen korrigiert?

Guck mal ins angehängte Datenblatt, da siehst du das Timing Diagramm und 
die Befehle sind auch gut erklärt.

Ralf

von Michael U. (amiga)


Lesenswert?

Hallo,

normalerweise sollte das so gehen. Bei solchen Busansteuerungen 
übernehmen eigentlich alle mir bekannten Bausteine bei der L/H-Flanke 
von /CE oder /WE, je nachdem, welche Flanke zuerst kommt.

Da das Display offenbar angesprochen wird, könnten eigentlich nur die 
Parameter falsch sein, also Text-Ram, Grafik-Ram, Display löschen usw.

Irgednwie fehlen mir in seinem ersten Code Init-Teile, außerdem stört 
mich etwas, das er erst ein A schreibt und dann erst das Display 
einschaltet, ist aber eher unbedeutend.

Der Grafikram enthält nach dem Einschalten Zufallswerte, wenn man also 
nur initialisiert und Grafik einschaltet, gibt es normalerweise ein mehr 
oder weniger zufälliges Pixelmuster.

Gruß aus Berlin
Michael

von Marco (Gast)


Angehängte Dateien:

Lesenswert?

Hallo und danke für die Antworten!

Ich habe den Code nun umgeschrieben:
-die C/D, CE, RD/WR Befehle sind nun wie die im Timing Diagramm
-Das Display wird geresettet
-Der Modus wird gewählt: ROM benutzen, OR-Modus
-Text Home Address und Text Area wird gesetzt
-Graphic Home Address und Graphic Area wird gesetzt
-Address Pointer wird auf 0x00 gesetzt
-Zeichen "A" wird geschrieben
-Display wird eingeschaltet: GFX OFF, TXT ON, CURSOR OFF, BLINK OFF



Alles was das Display anzeigt ist auf dem Bild zu sehen... :(



CODE:


#include <avr/io.h>
#include <util/delay.h>

#define CD PC0
#define WR PC1
#define RD PC2
#define CE PC3
#define RST PC4

#define DATA PORTD
#define CONTROL PORTC

void long_delay(uint16_t ms)
{for(; ms>0; ms--) _delay_ms(1);}

void datawrite(int d){

  CONTROL &= ~(1<<CD);      //DATA INPUT

  CONTROL |= (1<<RD);        //Lesen aus
  CONTROL &= ~(1<<WR);      //Schreiben ein

  CONTROL &= ~(1<<CE);      //Low-Flanke am CE
  long_delay(1);          //DELAY

  DATA = d;

  CONTROL |= (1<<WR);        //Schreiben aus

  CONTROL |= (1<<CE);        //High-Flanke am CE
  long_delay(1);          //DELAY

  }


void cmdwrite(int c){

  CONTROL |= (1<<CD);        //COMMAND INPUT

  CONTROL |= (1<<RD);        //Lesen aus
  CONTROL &= ~(1<<WR);      //Schreiben ein

  CONTROL &= ~(1<<CE);      //Low-Flanke am CE
  long_delay(1);          //DELAY

  DATA = c;

  CONTROL |= (1<<WR);        //Schreiben aus

  CONTROL |= (1<<CE);        //High-Flanke am CE
  long_delay(1);          //DELAY

  }

int main(void)
{


DDRD = 0xff;          //Datenport als Ausgang
DDRC = 0xff;          //Controlport als Ausgang

CONTROL |= (1<<CD) | (1<<RD) | (1<<RST) | (1<<CE) | (1<<WR);     //Reset 
aus, Lesen aus, Schreiben aus, Clock auf High, Command INPUT

CONTROL &= ~(1<<RST);      //RESET 100ms
long_delay(100);
CONTROL |= (1<<RST);

cmdwrite(0b10000000);      // Mode set: use CG ROM, OR

datawrite(0x00);           //TEXT HOME ADRESS
datawrite(0x00);
cmdwrite(0x40);

datawrite(0x1E);        //TEXT AREA SET number of columns: 30
datawrite(0x00);
cmdwrite(0x41);

datawrite(0x00);        //GRAPHIC HOME ADDRESS
datawrite(0x02);
cmdwrite(0x42);

datawrite(0x1E);        //GRAPHIC AREA
datawrite(0x00);
cmdwrite(0x43);

datawrite(0x00);        //ADDRESS POINTER SET
datawrite(0x00);
cmdwrite(0x24);

datawrite(0x21);        //WRITE "A"
cmdwrite(0xC0);

cmdwrite(0b10010100);      // DISPLAY ON: GFX OFF, TXT ON, CURSOR OFF, 
BLINK OFF


    return 0;
}

von Sascha F. (sascha_focus) Benutzerseite


Lesenswert?

Hi,

schmeiß doch mal dein delay raus, und frage den Status des Display's ab.
Das hat bei mit bei allen Display's funktioniert.

Gruß Sascha

von Michael U. (amiga)


Lesenswert?

Hallo,

Status würde ich beim T6963C sowieso immer abfragen, das interne Timing 
wird nirgens garantiert.

Zwischen den Flanken von /CE, /WE, /RD usw. bis ca. 10MHz mit SIcherheit 
keinerlei Waits erforderlich, darüber evtl. ein nop, falls die LEitungen 
sehr lang sind (knapp 20cm Flachband sind bei mir noch kein Problem, 
erst bei 16MHz AVR-Takt).

Die längste zeit ist 100ns, also bei 10MHz kann nach C/D-Wechsel im 
nächsten Befehl /CE aktiv werden, ohne die Spezifikation zu verlassen. 
Alle anderen Zeiten sind sowieso kürzer.

Pass bei den Status-Bits auf, eineige Beispielcodes sind da etwas 
fehlerhaft.
Zum normalen Lesen und Schreiben sind nur STA0 und STA1 maßgebend, bei 
den Autobefehlen NUR STA2 oder STA3, je nach Befehl. Einige Sourcen 
testen da alle parallel, das kann schief gehen, STA2 und STA3 sind bei 
den normalen Befehlen undefiniert.

Gruß aus Berlin
Michael

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
Noch kein Account? Hier anmelden.