Forum: Mikrocontroller und Digitale Elektronik Ansteuerung LCD-Display mit t6369c-Chip und 16Mhz Taktfrequenz


von Chesterfield93 (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

um den Thread hier mal wieder ins Leben zu rufen:

ich programmiere gerade an einem Display mit T6963C-Chip und habe das 
ganze an einem AT90CAN128 hängen..
Daten-Port: C; Control-Port: A; JTAG disabled, und die hier angebotene 
Library in Benutzung. Das ganze funktionierte einwandfrei mit der 
internen Taktfrequenz des AT90 (8MHz), aber als ich den Chip jetzt auf 
einen externen 16MHz Quarz umgestellt habe, hat das Display angefangen 
nur noch Mist anzuzeigen... Fuses zurück auf internen Takt und es 
funktioniert wieder alles. Ich habe inzwischen gefühlt jedes 
Elektronikforum 2-mal durchsucht, aber überall wo jemand mal das Problem 
mit der Taktfrequenz beschreibt, kommt kein befriedigendes Ergebnis 
heraus.

Die Display-Library die ich benutze ist die von einem "Radoslaw 
Kwiecien", ist sehr übersichtlich und nachvollziehbar programmiert und 
hat eine "delay"-Funktion, die eine Verzögerung abhängig der 
Taktfrequenz verursacht. Habe die Dateien und auch meine Projektdateien 
hier mal in den Anhang gehängt und ein paar Fotos von dem beschriebenen 
Problem gemacht.

Ich hoffe sehr dass mir hier jemand weiterhelfen kann. Sitze inzwischen 
seit mehreren Wochen nur andem Problem und so langsam hört es auf spaß 
zu machen...

Danke im Voraus!

: Verschoben durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Chesterfield93 schrieb:
> und hat eine "delay"-Funktion, die eine Verzögerung abhängig der
> Taktfrequenz verursacht.

Die wird wohl das Problem sein.
1
void delay(void)
2
{
3
  volatile unsigned char i;
4
  for(i = 0; i < (F_CPU/1000000); i++)
5
  {
6
    asm("nop");
7
  }
8
}

Ändere die probeweise, indem Du sie langsamer machst. Also entweder den 
Teiler (1000000) verkleinern oder ein zweites nop in die Schleife 
einfügen.

von Thomas F. (igel)


Lesenswert?

void GLCD_WriteData(unsigned char data)
{
  while(!(GLCD_ChceckStatus()&0x03));
  GLCD_DATA_PORT = data;
  GLCD_CTRL_PORT &= ~((1 << GLCD_WR) | (1 << GLCD_CE) | (1 << GLCD_CD));
  delay();
  GLCD_CTRL_PORT |= ((1 << GLCD_WR) | (1 << GLCD_CD)); // | (1 << 
GLCD_CE));
}

Du kannst auch mal probieren nach der letzten Zeile auch noch ein 
delay() einzufügen.

von Chris K. (christopher_k25)


Lesenswert?

Hallo,

Danke für die schnellen Antworten!

Ich habe alles schon versucht.
Ich hab' die Delay-Funktion in der Schleife auch schon bis zu 
verschiedenen festen Wert zählen lassen, anstatt einen Teiler für F_CPU 
zu nehmen, habe den Teiler zwischen 10.000 und 32.000.000 variiert - 
also echt so ziemlich jede denkbar mögliche Zeit abgedeckt - hat alles 
nichts gebracht.
Seltsamerweise funktioniert das ganze mit interner Taktfrequenz tadellos 
- dann bauen sich zwar die Grafiken einfach leeehr langsam auf oder es 
haut bei dem 32.000er Teiler (das ist immerhin der 32-fache Wert des 
originalen) ein paar Pixelfehler rein, aber wirklich kaum...

Auch die Idee mit der delay()-Funktion an anderen Stellen hatte ich 
schon. Leider ebenfalls kein Ergebnis, egal wo ich sie mit ran hänge

: Bearbeitet durch User
von Georg G. (df2au)


Lesenswert?

Bist du sicher, dass der Compiler dein delay() nicht weg optimiert? 
Verwende doch probehalber mal das gcc _delay_us().

von holger (Gast)


Lesenswert?

Wie lang ist das Kabel zum Display?

von spess53 (Gast)


Lesenswert?

Hi

>Seltsamerweise funktioniert das ganze mit interner Taktfrequenz tadellos
>- dann bauen sich zwar die Grafiken einfach leeehr langsam auf

Dann passt was nicht. So ein Display hatte ich schon mit 4MHz betrieben. 
Da baut sich ein kompletter Screen ohne merkliche Verzögerung auf. 
Allerdings in Assembler. Bei 11,... MHZ sind an ein paar Stelle ein paar 
zusätzliche NOPs drin.

MfG Spess

von Georg G. (df2au)


Lesenswert?

Alte Soft durchwühlt und fündig geworden. Bei mir lief ein solches 
Display mit 16MHz und (fast) der gleichen Lib. Einziger Unterschied, den 
ich auf die schnelle sehe:

void delay(void) {
    uint8_t i;
    for(i = 0; i < (F_CPU/1000000L); i++) {
        asm volatile ("nop\n\t"::);
        }
    }


Kabellänge übrigens etwa 15cm, normales Flachkabel.

von spess53 (Gast)


Lesenswert?

Hi

Ups, gerade gesehen:

>void GLCD_DrawMap(unsigned char map[32][4], unsigned char px, unsigned char >py) 
{ // Draw Logos
>  unsigned char l, c, b;
>  for (l=0;l<32;l++) {
>    for (c=0;c<4;c++) {
>      for (b=0;b<8;b++) {
>        GLCD_SetPixel(c*8+b+px, l+py, map[l][c] & (1<<7-b));
>      }
>    }
>  }
>}

das ist natürlich tödlich langsam. Grafiken gebe ich Byteweise aus. 
Deine Routine dürfte um ein zigfaches langsamer sein.

MfG Spess

von Chris K. (christopher_k25)


Lesenswert?

Habe es gerade ausprobiert und bekomme keine Änderung.
Unter 8MHz immernoch alles tip top, unter 16MHz nur Müll.

Es gab ja auch unter 8 MHz mit der originalen Funktion keine Probleme 
mit der Funktion, und durch Veränderung des Teilers in der Schleife 
wurde der Aufbau des Bildes auch schneller oder langsamer. Ich zweifle 
inzwischen daran dass es an der delay()-Funktion liegt.

Es scheint so als ob der Controller das Bild im Fehlerfall mehrfach 
versucht aufzubauen und immer wieder abstürzt und von vorne anfängt - 
manchmal braucht er weit mehr als 10 Anläufe bis sich der "Home-Screen" 
aufbaut, und dann auch nur mit dem Fehler den ihr ja oben im Bild schon 
seht.

von Patrick (Gast)


Lesenswert?

Chris K. schrieb:
> braucht er weit mehr als 10 Anläufe
Watchdog aktiv?

von Chris K. (christopher_k25)


Lesenswert?

Kabellänge: ca. 40cm, Flachband.

@spess: Danke, habe es mir mal notiert, das wäre natürlich noch ne 
Möglichkeit der Optimierung. Allerdings muss ich das Display ja erstmal 
überhaupt zum laufen bringen...

Einen Watchdog habe ich nicht am laufen. Soweit ich das verstanden habe 
ist das ein Auto-Reset, den ich regelmässig nullen muss, der den Zweck 
hat ungewollte endlosschleifen zu verhindern?

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>while(!(GLCD_ChceckStatus()&0x03));

Ist eine zusätzliche Bremse. Leg das While in GLCD_ChceckStatus.

MfG Spess

von Quentin (Gast)


Lesenswert?

Auf den ersten Blick fällt mir auch nur das delay auf.
Bei mir lief das Display mit 40 MHz. Folgenden Kommentar habe ich im 
Code gefunden:
1
// wait function for 80 ns (see data sheet)
2
// F_CPU  1MHz 1 NOP = 1000 ns
3
// F_CPU 10MHz 1 NOP =  100 ns
4
// F_CPU 30MHz 1 NOP = 33.3 ns
5
// F_CPU 40MHz 1 NOP =   25 ns
Offenbar müssen da irgendow 80 ns eingehalten werden. Bei 16 MHz sollten 
zwei NOP reichen.

Achso. Außerdem werden in meinem Code die Leitungen einzeln 
angesprochen. Erst CE, dann RD usw.
Ich habe jetzt nicht ins Datenblatt geschaut, aber vielleicht spielt das 
auch noch eine Rolle...

von Georg G. (df2au)


Lesenswert?

Quentin schrieb:
> Offenbar müssen da irgendow 80 ns eingehalten werden. Bei 16 MHz sollten
> zwei NOP reichen.

Die NOP-Schleife wird pro 10MHz CPU-Frequenz einmal durchlaufen. Dazu 
kommt die Zeit für Call-Return. Und da es bei mir mit 16MHz gepasst hat, 
muss der Fehler bei dir an anderer Stelle liegen. Nimm doch einfach mal 
ein Scope und sieh dir die Signale an. Messen heißt Wissen.

von Chris K. (christopher_k25)


Lesenswert?

Hallo,

vielen Dank für die vielen Ideen und Ratschläge,

Im Endeffekt hat es schinbar an einem der Daten-Pins des 
Microcontrollers gelegen.. ich habe auf Verdacht nochmal alle nach 
gelötet und jetzt passt es. Das Beinchen hatte wohl einfach einen 
minimalen Wackelkontakt.

Zur Info: mit 'nem Teiler von 2.000.000 in der delay-Funktion passt die 
Ansteuerung, wenn ich sie noch schneller mache fängt er an hier und da 
ein paar Pixel zu verhauen.

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.