Forum: Mikrocontroller und Digitale Elektronik LCD mit ILI9325 funktioniert nicht!


von Honda (Gast)


Angehängte Dateien:

Lesenswert?

Moin,
Ich versuche aktuell ein LCD (http://www.ebay.de/itm/171986693663) zum 
Laufen zu bringen. Ich gehe davon aus, das dieser mit einem ILI9325 
bestückt ist. Mein Code ist angehängt.
Dabei möchte ich das LCD mit einem AtMega1284p mit 16Mhz zum Laufen 
bringen.
Ich habe bereits mehrere Librarys im Internet ausprobiert und kam immer 
zum selben Ergebnis. Das Display zeigt alle Pixel bunt an, kein Muster 
erkennbar, obwohl die Programme das LCD einfarbig bemalen sollen. 
Nachdem die gefundenen Librarys mich nicht weiterbrachten, habe ich mir 
das Datenblatt genauer angeschaut und selber Code geschrieben. Die 
Registerwerte für die Initialisierung habe ich aus einer anderen Library 
kopiert. Dabei habe ich versucht diese nachzuvollziehen und 
gegebenenfalls zu korrigieren. Die Kommentare hinter den 
Register-Schreib-Aufrufen zeigen das Ergebnis. Was mich wundert, ist das 
viele Projekte Register ansprechen, die nicht im Datenblatt 
(https://www.adafruit.com/datasheets/ILI9325.pdf) genannt sind. Ergebnis 
ist schließlich das Selbe wie zuvor, ein buntes Pixelbild. In Foren habe 
ich gelesen, dass dieser Zustand bedeutet, dass das Display erfolgreich 
initialisiert sei (ohne Initialisierung zeigt das Display weiß an), 
daher gehe ich davon aus, dass ich nicht komplett auf dem Holzweg bin :D

Da ich mir nicht sicher bin, ob es sich tatsächlich um ein ili9325 
handelt, wollte ich den Namen aus dem Register 0x00 auslesen. Mit den 
Librarys aus dem Netz bekam ich den Wert 0xC0C0 zurück. Eigentlich 
sollte ich 0x9325 zurück bekommen. Mit meinem eigenen Code bekam ich 
0x00 ausgelesen!
Auf Ebay steht das der Controller ein SPFD5408 sei. Dieser gibt 
ebenfalls über das Register 0x00 seinen Namen raus, d.h. auch dieser 
würde nicht 0xC0C0 ausspucken, sondern 0x5408. Auf der Herstellerseite 
(mcufriend.com/product/html/?66.html) werden als Controller genannt: 
"ili9325  ili9335  ili9341". Wieso dort gleich 3 Chips genannt werden, 
ist mir ein Rätsel :/ Diverse Projekte im Netz gehen von einem ili9325 
aus.

Im Code sind zwei Funktionen zu finden, die ich zum Bemalen des LCD 
geschrieben habe: setPixelXY und Draw_Color. setPixelXY soll ein 100x100 
großes Quadrat ausmalen und setzt dafür den Adress Pointer manuell auf 
jedes einzelne Feld und malt dieses dann aus. Draw_Color nutzt die 
Auto-Increment-Funktion des ili9325, wobei man nur den Befehl zum Malen 
(0x22) geben muss und er anschließend nach jedem geschriebenen Pixel die 
Position um 1 weitersetzt.
Das Ergebnis von beiden Programmen ist ein kurzes Flackern der bunten 
Pixel mit anschließend stehenden bunten Pixeln. Also keine einfarbige 
Fläche. Also genauso, wie mit allen anderen getesteten Programmen.

Theoretisch habe ich im Register 0x03 festgelegt, dass alle Farben 
nacheinander mit jeweils 6 bit geschrieben werden sollen. Dies passiert 
in der Funktion LCD_Write_Pixel.

Jetzt ist die große Frage, was mache ich falsch?
Ist es überhaupt kein ili9325? -> Wie könnte ich herausfinden, was es 
dann ist?
Ist die Initialisierung oder das Setzen der Pixel fehlerhaft? -> Wieso 
klappt es dann bei den anderen mit der gleichen Library?
Ist vielleicht auch etwas Grundlegendes falsch? z.b. Taktfrequenz, 
Steckbrett, AtMega1284p, etc?

Mittlerweile sitze ich bereits eine gute Woche daran und habe das Gefühl 
nicht einen Schritt weiter zu sein! Wäre also klasse, wenn ihr da ne 
gute Idee habt :)

von Michael K. (Gast)


Lesenswert?

20sek lesen der von Dir verlinkten Seite:
> Spfd5408 Chip mit Video-RAM-Puffer

von Honda (Gast)


Lesenswert?

Michael K. schrieb:
> 20sek lesen der von Dir verlinkten Seite:
>> Spfd5408 Chip mit Video-RAM-Puffer

Du scheinst leider meinen Text nicht ganz durchgelesen zu haben:
Honda schrieb:
> [...]
> Auf Ebay steht das der Controller ein SPFD5408 sei. Dieser gibt
> ebenfalls über das Register 0x00 seinen Namen raus, d.h. auch dieser
> würde nicht 0xC0C0 ausspucken, sondern 0x5408. Auf der Herstellerseite
> (mcufriend.com/product/html/?66.html) werden als Controller genannt:
> "ili9325  ili9335  ili9341". Wieso dort gleich 3 Chips genannt werden,
> ist mir ein Rätsel :/ Diverse Projekte im Netz gehen von einem ili9325
> aus.

von Arduinoquäler (Gast)


Lesenswert?

Zeige bitte deine Schaltung. Schaltplan ... nicht Foto.

Ich kenne die Displays dieser Machart. Sie haben eine Pufferschaltung
die es nicht erlaubt auch Daten vom Display zu lesen. Ferner sind die
Touch-Pins "gemultiplext" auf Daten und Steuerpins angeschlossen.
Damit haben sie sich den Touch-Controller gespart und die Ungenauigkeit
der Touch-Leserei vergrössert ....

Wenn du nicht weiterkommst veruche ich deinen Code mal auf meinem
Aufbau laufen zu lassen.

von Honda (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Zeige bitte deine Schaltung. Schaltplan ... nicht Foto.
Die Schaltung ist ziemlich simpel. Im Endeffekt sieht sie so aus:
http://radiomanoff.at.ua/ILI9325/cheme.gif
Selbstverständlich noch ein Pull-Up am Reset, zwei 22pF am Quarz gegen 
GND und einige 100nF in der Versorgung. Der AtMEga läuft mit 3,3V und 
das Display mit 3,3V und 5V.

Wenn du möchtest, kann ich aber auch noch ein anständigen Plan zeichnen.

> Ich kenne die Displays dieser Machart. Sie haben eine Pufferschaltung
> die es nicht erlaubt auch Daten vom Display zu lesen.
Das habe ich auch im Datenblatt gelesen. Leider stand nirgends genau, 
was ich deswegen zu tun habe. Aus diesem Grund habe ich auch einfach mal 
4 Read-Impulse ausgelöst und alle Werte gespeichert. Ergebnis ist die 
Wiederholung des gleichen Wertes. Ich habe da nicht das Gefühl, dass ich 
überhaupt was sinnvolles lese :D

> Ferner sind die Touch-Pins "gemultiplext" auf Daten und Steuerpins
> angeschlossen.

Das klingt jetzt nicht soo cool. In der Tat soll das Display ja Touch 
haben und ich habe mich bereits gefragt, wie ich an diesen rankäme. Muss 
ich dafür evtl. Pins belegen? Ich habe aktuell alle LCD-Pins wie oben 
beschrieben belegt. Und selbstverständlich GND, 3,3V und 5V. Die SD-Pins 
sind offen. Lediglich von dem Pin neben 3,3V weiß ich, dass dieser zum 
Taster auf der Vorderseite gehört...

> Wenn du nicht weiterkommst veruche ich deinen Code mal auf meinem
> Aufbau laufen zu lassen.

Das wäre echt super, damit ließe sich schon mal einiges ausschließen :)

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> Das wäre echt super, damit ließe sich schon mal einiges ausschließen :)

... aber dazu müsstest du wenigsten deinen echten Schaltplan zeigen.
Vollständig! Denn da können Hunde begraben sein.

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> Muss ich dafür evtl. Pins belegen?

Hol dir die Touch-Library auf die Adafruit verweist. Dort kannst du
dir zumindest anschauen wie es geht. Aber die Library baut auf das
Arduino-Gerüst auf und nutzt deren Pinzuweisungen und andere
Grundfunktionen .....

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> Ich habe da nicht das Gefühl, dass ich
> überhaupt was sinnvolles lese :D

Nein, da kommt nur ein floatender Bus daher .....

von Honda (Gast)


Angehängte Dateien:

Lesenswert?

Schaltplan im Anhang.

von Honda (Gast)


Lesenswert?

Zum Schaltplan: Der ATMEGA644-10PU ist in Wirklichkeit ein AtMega1284p, 
wie oben auch beschrieben!


Arduinoquäler schrieb:
> Hol dir die Touch-Library auf die Adafruit verweist. Dort kannst du
> dir zumindest anschauen wie es geht. Aber die Library baut auf das
> Arduino-Gerüst auf und nutzt deren Pinzuweisungen und andere
> Grundfunktionen .....

Mach ich!

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> Schaltplan im Anhang.

Fehler:

Avcc mus mit Vcc verbunden werden (und abgeblockt mit 100nF) sonst
funktioniert Port A nicht!

von Honda (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Avcc mus mit Vcc verbunden werden (und abgeblockt mit 100nF) sonst
> funktioniert Port A nicht!

Gut aufgepasst :) Ist geändert, leider keine Besserung.

von Honda (Gast)


Angehängte Dateien:

Lesenswert?

Also ich mag mich täuschen, aber ich finde in dieser Library:
https://github.com/JoaoLopesF/SPFD5408
Keinen Ansatz, womit zwischen LCD und Touch umgeschaltet wird.
Wenn man sich die SPFD5408_TouchScreen.cpp anschaut, gibt es dort die 
Funktion:
TouchScreen::TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym, 
uint16_t rxplate)

Mit dieser werden wohl die Pins für den Touch übergeben. xp, yp, xm und 
ym werden wohl die Messpunkte sein. Was genau rxplate ist, weiß ich 
nicht. Da mit diesem gerechnet wird, denke ich allerdings nicht, dass 
dies den Multiplexer umschaltet.


Auf der Unterseite der Platine befinden sich zwei 74HC245 (Octal bus 
transceiver; 3-state).
http://www.nxp.com/documents/data_sheet/74HC_HCT245.pdf
Prinzipiell eine wunderbare Möglichkeit zum Umschalten. Allerdings ist 
der für die Komando-Pins Zuständige (U2) fest auf eine Richtung 
eingestellt.
Und beim Zweiten ist DIR nur mit dem Eingang vom U2 verbunden. OE kann 
nur mit VCC verbunden sein, nur dann könnte er nie Signale 
durchlassen...

von Honda (Gast)


Lesenswert?

Okay, wenigstens das Rätsel um U3 ist gelöst. Das Dir signal ist direkt 
mit LCD_RD verbunden, logischerweise :D D.h. die haben vermutlich nix 
mit dem Touch zu tun :/

Ich werde wohl weiter in Bibliotheken schauen.

von Arduinoquäler (Gast)


Angehängte Dateien:

Lesenswert?

..... sooodele .....

ich hab mal um deine Initialisierung etwas herumgebastelt....

Es waren schon ein paar Macken drin die ich jetzt nicht aufzählen
werde.

Eine Minimallösung...
Es sollte sich was an Pixeln bewegen, wenn auch nicht perfekt.
Ich habe auf 16 Bit hingearbeitet, du hattest aber auf 18 Bit
Farben initialisiert, das wirst du schon hinkriegen.
16 Bit wird auf jeden Fall schneller sein.

von Arduinoquäler (Gast)


Angehängte Dateien:

Lesenswert?

Honda schrieb:
> Ich werde wohl weiter in Bibliotheken schauen.

Das ist die Library.

von Honda (Gast)


Lesenswert?

Okay, nun habe ich die Touchschaltung soweit verstanden.
Über die Pins LCD_D6 und LCD_D7 und den Pins LCD_CS und LCD_WR werden 
die "Touch-Widerstände" gemessen (jeweils einer pro Richtung). Die 
Verbindungen dafür liegen vor den 74HC245, d.h. diese beeinflussen den 
Touch nicht. Das LCD überlagert somit lediglich den Touch. Mit ca. 
200Ohm Touch-Widerstand sollte der ili also eigentlich stark genug sein, 
gegen den Touch-Widerstand einen Zustand anzulegen.

Dementsprechend bin ich dem Problem leider noch nicht näher gekommen. 
Ich kann lediglich den Touch als Problemursache erstmal ausschließen.

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> Keinen Ansatz, womit zwischen LCD und Touch umgeschaltet wird.

Umgeschaltet wird am Prozessor. Da die LCD Steuer- und Datenleitungen
immer nur Input sind kann "man" die Touch-Widerstände auf die gleichen
Pins legen und mittels TTL Output am Prozessor und Analog-Spannung
Lesen (an zwei A/D Wandler Pins) die Widerstände auswerten.

von Honda (Gast)


Lesenswert?

Arduinoquäler schrieb:
> ..... sooodele .....
>
> ich hab mal um deine Initialisierung etwas herumgebastelt....
>
> Es waren schon ein paar Macken drin die ich jetzt nicht aufzählen
> werde.

VIELEN DANK! :)

Ich habs mir noch nicht im Detail angeschaut, allerdings sehe ich schon 
mal ein hübsches schwarz-weiß blinkendes Kästchen :)

Nachdem ich den ganzen Tag an diesem Display saß, werde ich mich jetzt 
allerdings erst einmal glücklich Richtung Bett verabschieden.

Nochmals vielen Dank :))

von Honda (Gast)


Lesenswert?

Lies mir keinen Schlaf...

Ich habe mir mal deinen Code angeschaut und frage mich, woher du so 
Sachen wie:
void TFT_Set_XYRange (uint16_t xstart, uint16_t xend,
uint16_t ystart, uint16_t yend)
{
  LCD_WriteCMD (0x2A);    // column addr set

  LCD_Write16 (xstart);
  LCD_Write16 (xend);

  LCD_WriteCMD (0x2B);    // row addr set

  LCD_Write16 (ystart);
  LCD_Write16 (yend);
}

hast? In meinem Datenblatt zum ili steht zu diesen Registern gar nichts 
:/

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> In meinem Datenblatt zum ili steht zu diesen Registern gar nichts

In den meisten ILI**** und anderen Displays sind diese (elementaren)
Befehle implementiert, warum sollte es also bei deinem nicht so sein?
Ich habe es nun mal "aus dem hohlen Bauch heraus" angewendet ohne
es sicher zu wissen dass es bei dir funktioniert.

Im Allgemeinein sind die Befehlssätze der Displays jedoch auch sehr
ähnlich. So muss dein Display nicht wirklich von Ilitek sein.

von Honda (Gast)


Lesenswert?

Arduinoquäler schrieb:
> In den meisten ILI**** und anderen Displays sind diese (elementaren)
> Befehle implementiert, warum sollte es also bei deinem nicht so sein?
> Ich habe es nun mal "aus dem hohlen Bauch heraus" angewendet ohne
> es sicher zu wissen dass es bei dir funktioniert.

Dann finde ich nur, dass man das irgendwo im Datenblatt erwähnen sollte 
:/ Wenn darin nirgends steht, dass es noch weitere gibt, wie soll ich 
dann darauf kommen? Es würde doch eine kleine Referenz ala "Die 
Standardregister sind bei xy zu finden."

Aber gut, dafür kannst du ja auch nix ;)


Aktuell habe ich das ganze auf einem Steckbrett mit nem AtMega1284 
laufen. Ich möchte das Ganze jedoch verbauen und suche nun einen 
passenden SMD-Chip. Auf der Suche nach dem Richtigen, fragte ich mich, 
wie viel Speicher so eine LCD-Ansteuerung in der Regel frisst?

Reichen da locker 32kbit oder sitzt man damit zu schnell auf dem 
Trockenen?
Da ich mich in der Planungsphase befinde, habe ich entsprechend noch 
keine Software, mit der ich den Umfang abschätzen könnte.
Grafisch ist nichts großes geplant, ich denke mal vielleicht 20 Grafiken 
30x30 groß, der Rest wird Schrift sein.
Wären für die Grafiken also 20 Grafiken x 30 Pixel Breite x 30 Pixel 
Höhe x 3 Farben x 6bit/Farbe = 40,5kByte
+ Font für ca. 100 Zeichen 5x7 groß = ~8kByte
Zusammen also ca. 50kByte + Software

Der Chip wird I2C, ein LCD, einige Taster und einige PWMs bearbeiten 
müssen. Rein rechnerisch hätte ich bei nem 64kByte-Chip noch 14kByte für 
die Software über. Halte ich gerade für die Ansteuerung des LCDs 
ziemlich knapp.

Ist das so richtig gerechnet?
Aus dieser groben Rechnung würde ich somit schließen, ich sollte bei den 
128kByter anfangen.

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> Dann finde ich nur, dass man das irgendwo im Datenblatt erwähnen sollte
> :/ Wenn darin nirgends steht, dass es noch weitere gibt, wie soll ich
> dann darauf kommen?

Ja, ich kann auch nix dafür.

Aber wenn die Befehle funktionieren und die in deinem Dateblatt
nicht enthalten sind liegt es doch nahe dass du das falsche
Datenblatt liest, nicht wahr?

Also wird es doch ein ILI**** Display sein (in allen ILIs sind
die Befehle drin), oder zumindest eines das so ziemlich bis voll
kompatibel ist.

Für den Rest deiner Fragen kann ich dir keine Abschätzung geben.

von Thomas F. (igel)


Lesenswert?

Honda schrieb:
> Wären für die Grafiken also 20 Grafiken x 30 Pixel Breite x 30 Pixel
> Höhe x 3 Farben x 6bit/Farbe = 40,5kByte

Die Farben als 3x6Bits zu speichern macht viel umständlichen 
Programmieraufwand. Ich würde entweder gleich 3 Bytes Farbe pro Pixel 
vorsehen oder dann eben 2 Bytes/16-Bit Farbe im 5R6G5B-Format.

> + Font für ca. 100 Zeichen 5x7 groß = ~8kByte

Ein 5x7 Font auf einem 2.4 Zoll Display ist winzig. Aus 1m Entfernung 
kaum zu lesen. Ich würde dir empfehlen einen 12x16 Font vorzuhalten.
Den Font würde ich im Flash des Controllers ablegen sonst muss man bei 
jedem Buchstaben per I2C erst mal die Daten aus dem externen Speicher 
holen.
Weiter bin ich eher für SPI, ist schneller.

von Anon E. (anonelec)


Lesenswert?

Ich habe mich selbst vor ein paar Wochen mit einem solchen Display 
beschäftigt. Wichtig wäre schon die korrekte ID auslesen zu können. So 
lange Du nicht weisst was genau vor Dir liegt wird die Programmierung 
schwierig.

Wenn Du alles richtig machst und Register 0 ausliest und 0x00 kriegst, 
ist es wohl kein ILI9325. Versuch dann mal Register 0xd3 auszulesen. 
Beim ILI9341 liefert das erst ein "dummy byte", dann 0x00 0x93 0x41. Die 
ID ist bei diesem nicht in Register 0.

Beim ILI9341 hatte ich zudem noch das Problem, dass die meisten 
Datenblätter, welche ich auf Google fand, "preliminary" waren und in 
diesen nicht alle Befehle dokumentiert sind. Ich habe nun "specification 
1.11" ohne "preliminary" auf dem Titelblatt, und dort sind alle Befehle 
dokumentiert.

von Anon E. (anonelec)


Lesenswert?

Ich habe mich selbst vor ein paar Wochen mit einem solchen Display 
beschäftigt. Wichtig wäre schon die korrekte ID auslesen zu können. So 
lange Du nicht weisst was genau vor Dir liegt wird die Programmierung 
schwierig.

Wenn Du alles richtig machst und Register 0 ausliest und 0x00 kriegst, 
ist es wohl kein ILI9325. Versuch dann mal Register 0xd3 auszulesen. 
Beim ILI9341 liefert das erst ein "dummy byte", dann 0x00 0x93 0x41. Die 
ID ist bei diesem nicht in Register 0.

Beim ILI9341 hatte ich zudem noch das Problem, dass die meisten 
Datenblätter, welche ich auf Google fand, "preliminary" waren und in 
diesen nicht alle Befehle dokumentiert sind. Ich habe nun "specification 
1.11" ohne "preliminary" auf dem Titelblatt, und dort sind alle Befehle 
dokumentiert.

> + Font für ca. 100 Zeichen 5x7 groß = ~8kByte

Das muss nicht sein. Ich habe für einen 8x12 Font 1.3kB, für einen 16x16 
Font 2.1kb, und für einen 27pixel hohen Proportional-Font (Deja Vu) 
3.2kB. Der Trick dabei ist für die Zeichen ein "run length encoding" zu 
verwenden. Bei mir sieht das so aus dass ich für jedes Zeichen die 
Breite, dann die Anzahl Bytes des Codes, und dann das codierte 
Pixelpattern abspeichere. Das Format ist dabei das folgende: Bits 7..3 
sind die Anzahl "Hintergrundpixel", während Bits 2..0 die Anzahl 
"Vordergrundpixel" sind. Das habe ich so gewählt weil im Mittel mehr 
Hintergrundpixel in Folge kommen als Vordergrundpixel.

Für ein SPACE in 16x16 steht dann z.B.

 db 0x10,0x09,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0x40

0x10 ist die Breite (ist hier da ich auch Proportionalfonts habe), 0x09 
ist die Anzahl der Code-Bytes, und 0xf8 (0b11111000) heisst 31 
Background-Pixel gefolgt von 0 Foreground-Pixeln. Dies 8 Mal wiederholt, 
plus 0x40 am Ende (8 weitere Pixel) gibt 256 "leere" Pixel. So habe ich 
inkl. Breitenangabe 11 Bytes benötigt statt der 32 wenn das Muster 
unkomprimiert abgelegt würde. Bei grösseren Fonts ist der Spareffekt 
noch grösser.

Ausserdem lässt sich die Pixelfolge so schneller "Rausspulen"...

von Arduinoquäler (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Honda schrieb:
>> Ich habe da nicht das Gefühl, dass ich
>> überhaupt was sinnvolles lese :D
>
> Nein, da kommt nur ein floatender Bus daher .....

Ich habe mich getäuscht .....

Der Direction Pin des Buffer 74HC245 ist offensichtlich mit der
Read-Leitung verknüpft sodass der Treiber für's Lesen korrekt
"umgedreht" wird.

Also man kann diese Displays auch lesen .....

Zum Identifizieren gibt es die Befehle

#define RDDID  0x04  // read ID

Das ist die (vermutlich one-time-programmable) ID des
Herstellers (der die Displays auf ein Board packt)

und

#define RDID4  0xD3  // read ID 4

Das ist die TFT ID, also z.B. 0xXX009325 für ILI9325.

Müsste nach meiner (Daumenpeilungs-) Einschätzung für "alle"
ILIxxxx gelten.

von bianchifan (Gast)


Lesenswert?

Honda schrieb:
> Da ich mir nicht sicher bin, ob es sich tatsächlich um ein ili9325
> handelt, wollte ich den Namen aus dem Register 0x00 auslesen. Mit den
> Librarys aus dem Netz bekam ich den Wert 0xC0C0 zurück. Eigentlich
> sollte ich 0x9325 zurück bekommen. Mit meinem eigenen Code bekam ich
> 0x00 ausgelesen!

Kommt mir irgendwie bekannt vor..
Letzte Woche habe ich ein ILI9335 mit touch (ohne Controller) 
(Falschbestellung, sollte ein ILI9341 sein ;)
) ans Laufen gebracht, geholfen hat mir eine Seite unter misc.ws 
irgendwas.
Dort fand ich einen Sketch, der im Gegensatz zu all meinem vorhanden 
KRam (Adafruit + Derivate) das Display korrekt identifizieren und 
anschließend rot einfärben konnte. Alle anderen Programme gaben 
ebenfalls 0xC0C0 zurück.
Die Analyse des Codes zeigte bein Initialisieren im Anschluss an einige 
REgisterWrite Kommandos delays von 20ms.
Ich habe die Initialisierroutinen der getesteten libs dann dahin gehend 
abgeändert, dass ich in die Schleife mit den Registerschreiboperation 
knallhart einen solchen DELAY eingefügt habe.

Später habe ich dann entdeckt, dass auch schon andere auf diese Idee 
gekommen sind.

Ansonsten gibt es noch das ILI9341, das ist SPI und funzt...

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

kommt mir vor wie das "shield" meines Neffen - habe ich mal mit 
rumgespielt (weitgehend copy & paste ...).

Probier mal (da sind die Adafruit Libs  ...9341 ... mit drin - die 
sollten passen).

cu

von Honda (Gast)


Angehängte Dateien:

Lesenswert?

Moin,
Ich hatte gar nicht bemerkt, dass noch so viele Antworten kamen. Ich 
habe mich in der Zwischenzeit um die Ansteuerplatinen gekümmert und die 
Mechanik soweit fertig. Nun wollte ich das LCD wieder in Betrieb nehmen.

Statt des testweise verwendeten AtMega1284p nutze ich nun einen 
AtxMega256A3B mit 32Mhz.

Ich habe die alte Software für den AtxMega umgeschrieben, das Ergebnis 
ist im Anhang.

Wie zu sehen, werden zu erst die Ausgänge initialisiert, dann das LCD, 
dann soll der Name eingelesen und im EEPROM abgespeichert werden und 
dann ein Rechteck gemalt werden.

Die Initialisierung funktioniert (das Bild wird bunt bepixelt).

Das Einlesen des Names führt zu folgenden Ergebnissen:
Adresse-Ergebnis
0x00-0x0000 FFFF FFFF
0x04-0x0404 FFFF FFFF
0xD3-0xD3D3 FFFF FFFF

Für mich ergeben diese Werte keinen Sinn, immerhin sind sie 
reproduzierbar!

Das Rechteck erscheint leider auch nicht. (auch ohne ein Register 
ausgelesen zu haben)

Prinzipiell dachte ich, den funktionierenden Code vom AtMega korrekt 
angepasst zu haben. Tatsächlich scheint dem leider nicht so. Habe ich 
irgendwo einen komplett dämlichen Anfängerfehler drin oder wie kann es 
ansonsten sein, dass der Code ohne Änderung die Initialisierung 
erfolgreich absolviert und dann kein Rechteck anzeigt?

Die Pausenzeiten beim Triggern habe ich testweise auch mal auf 100us 
hochgesetzt, ohne Erfolg. F_CPU ist auf 32Mhz gesetzt, ein 
"Boot-Blinken" erfolgt auch im richtigen Takt, weshalb ich davon 
ausgehe, dass der xMega tatsächlich korrekt auf 32Mhz läuft. Ein Blinken 
testweise implementiertes Blinken nach dem Aufruf der Rechteck-Funktion 
offenbart mir, dass er auch mit allen Aufgaben abschließt, er also 
nirgends im Code festhängt.

von Arduinoquäler (Gast)


Lesenswert?

Warum macht du den Leuten die dir helfen sollen (wollen)
das Leben schwer? Gibst du deinem Compiler auch Sourcen
mit *.txt?

von Honda (Gast)


Lesenswert?

@Thomas Forster
> Die Farben als 3x6Bits zu speichern macht viel umständlichen
> Programmieraufwand. Ich würde entweder gleich 3 Bytes Farbe pro Pixel
> vorsehen oder dann eben 2 Bytes/16-Bit Farbe im 5R6G5B-Format.

Benutze nun 5R6G5B-Format. Ob ich dabei bleibe, muss ich mal schauen. 
Für die Tests hat es sich als ausreichend erwiesen. Ggbf. wird es 
später, wenn ich das richtige Programm schreibe auch auf 3x8bit 
geändert, aber das werde ich dann mal schauen.

> Ein 5x7 Font auf einem 2.4 Zoll Display ist winzig.

Jetzt wo du es sagst, vermutlich richtig. Ähnlich wie oben, wenn es denn 
läuft und ich ans eigentlich Programmieren gehen kann, probiere ich mal 
ein wenig durch, was sich als brauchbar erweist. Eventuell muss ich die 
Fonts auch skalieren können oder zwei Fonts nutzen, sodass für schlechte 
Bedingungen wenig in sehr groß anzeigen kann und durch schnelles 
draufschauen alles relevante erfährt. Und für normale Bedingungen eine 
kleineren Font, damit mehr aufs Display passt.
Vektorgrafiken sind vermutlich recht umständlich zu implementieren, 
oder? Lohnt es sich da, den Font tatsächlich zu skalieren oder sollte 
man lieber mit zwei unterschiedlich großen Fonts arbeiten?

> Den Font würde ich im Flash des Controllers ablegen...

Jup.


> Weiter bin ich eher für SPI, ist schneller.

Zur Ansteuerung des Displays? Da habe ich leider nicht so die Wahl. Der 
Übertragungsmodus ist soweit ich weiß, bereits fest im nicht 
erreichbaren Bereich verdrahtet.


@Anon Elec

> Wenn Du alles richtig machst und Register 0 ausliest und 0x00 kriegst,
> ist es wohl kein ILI9325. Versuch dann mal Register 0xd3 auszulesen.
> Beim ILI9341 liefert das erst ein "dummy byte", dann 0x00 0x93 0x41. Die
> ID ist bei diesem nicht in Register 0.

Ergebnisse, siehe oben. Bin wohl zu blöd zum Auslesen...


> Beim ILI9341 hatte ich zudem noch das Problem, dass die meisten
> Datenblätter, welche ich auf Google fand, "preliminary" waren und in
> diesen nicht alle Befehle dokumentiert sind. Ich habe nun "specification
> 1.11" ohne "preliminary" auf dem Titelblatt, und dort sind alle Befehle
> dokumentiert.

Tatsächlich hat mein Datenblatt kein "preliminary" draufstehen.
Datenblatt: https://cdn-shop.adafruit.com/datasheets/ILI9325.pdf
Auch wenn Version 0.43 nicht gerade für eine fertige Version spricht :D


Zur Font-Kompremierung:
Dazu werde ich mich später nochmal melden, wenn ich mir das in Ruhe 
durchgelesen. Aktuell beschäftigt mich mehr, dass das blöde LCD schon 
wieder nicht will :( Klingt aber auf jeden Fall interessant und spart ja 
gerade bei großen Fonts auch nennenswert Speicher!

@Arduinoquäler:
> Müsste nach meiner (Daumenpeilungs-) Einschätzung für "alle"
> ILIxxxx gelten.

Dann habe ich entweder kein Ili oder ich bin zu blöd zum Auslesen :D


@bianchifan
> misc.ws

Schau ich mir mal an!

> Ich habe die Initialisierroutinen der getesteten libs dann dahin gehend
> abgeändert, dass ich in die Schleife mit den Registerschreiboperation
> knallhart einen solchen DELAY eingefügt habe.

Da aber das Initialisieren gut klappt, wundert mich dann etwas, dass es 
beim Auslesen gar nicht mehr geht. Ich probiere aber mal ne Pause, nach 
dem Setzen der Adresse. Eventuell bin ich da jetzt zu schnell, sodass er 
es nicht schafft, den Namen zu laden.


@Dieter F.
> Probier mal (da sind die Adafruit Libs  ...9341 ... mit drin - die
> sollten passen).

Da ich nicht mit Arduino arbeite, müsste ich die Bibliotheken komplett 
umschreiben, worauf ich eigentlich keine Lust habe, da ich ja einen 
schon mal funktionierenden Code besitze.

von Honda (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Warum macht du den Leuten die dir helfen sollen (wollen)
> das Leben schwer? Gibst du deinem Compiler auch Sourcen
> mit *.txt?

Nein natürlich nicht. Allerdings befinden sich im aktuellen Projekt 
viele viele auskommentierte Bereiche zum Testen diverser Sachen, die ich 
euch ersparen wollte. Daher habe ich den gesamten Code einmal in 
Notepad++ kopiert, ausgemistet und dann abgespeichert.

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> inmal in Notepad++ kopiert, ausgemistet und dann abgespeichert.

.... und Notepad++ kann sicherlich keine C-Datei erzeugen, gell?

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> ein
> "Boot-Blinken" erfolgt auch im richtigen Takt, weshalb ich davon
> ausgehe, dass der xMega tatsächlich korrekt auf 32Mhz läuft.

Das Ausgehen ist nicht richtig.
Der Bootloader weiss ja nichts von deinen Absichten, daher wird
er sich seine eigene Takt-Initialisierung machen (oder keine, dann
läuft der Prozessor auf der Default-Einstellung).

Wenn du sicher gehen willst musst du deine eigene Takt-Initialisierung
schreiben, sonst läuft der Prozessor nur "wie gewachsen".

von Honda (Gast)


Angehängte Dateien:

Lesenswert?

Ich initialisiere den Prozessor mit:
>  /* Enable necessary Clock sources. 32MHz and 32kHz Oscillator */
>  OSC.CTRL = OSC_RC32MEN_bm;
>  /* Wait for Oscillators to become stable */
>  while(!(OSC.STATUS & OSC_RC32MRDY_bm));
>
>  /* Start Calibrating the 32MHz Clock using
>  * the internal calibrated 32kHz Oscillator */
>  OSC.DFLLCTRL = (0 << OSC_RC32MCREF_bp);
>  DFLLRC32M.CTRL = DFLL_ENABLE_bm;
>  /* Set as System Main Clock */
>  CCP = CCP_IOREG_gc;
>  CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
>
>  /* Lock Clock Settings until next Reset */
>  CCP = CCP_IOREG_gc;
>  CLK.LOCK = CLK_LOCK_bm;

Hielt ich für nicht relevant zu posten, da ich mittels Delay und 
LED-Blinken ja bereits sehen konnte, dass er mit der richtigen Frequenz 
arbeitet und das ja so schrieb.

Zur txt: Da das ja problematisch sein scheint, hier der Code nochmal mit 
.c-Endung.

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> Ich initialisiere den Prozessor mit:
>  /* Enable necessary Clock sources. 32MHz and 32kHz Oscillator */
>  OSC.CTRL = OSC_RC32MEN_bm;
> ......

Damit sicher nicht. Immer noch nicht die Regeln zum Posten gelesen?

von Honda (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Honda schrieb:
>> Ich initialisiere den Prozessor mit:
>>  /* Enable necessary Clock sources. 32MHz and 32kHz Oscillator */
>>  OSC.CTRL = OSC_RC32MEN_bm;
>> ......
>
> Damit sicher nicht. Immer noch nicht die Regeln zum Posten gelesen?

Nein. Was meinst du mit "Damit sicher nicht"? Wenn ich entsprechenden 
Code verwende, und ne LED im Takt blinken lasse, erzeugt durch delays, 
die nur mit korrekt abgestimmtem Makro F_CPU auf Taktfrequenz richtig 
funktioniert und die LED dann tatsächlich richtig blinkt, wobei F_CPU 
auf 32Mhz steht, scheine ich ja wohl mit 32Mhz zu arbeiten! Es kann gut 
sein, dass die eine oder andere Zeile beim Initialisieren überflüssig 
ist, das liegt dann daran, dass ich den Code so gefunden habe, er auf 
Anhieb funktionierte und meine Absicht nicht war, den Takt so perfekt 
wie möglich zu konfigurieren, sondern das LCD zum Laufen zu bringen. 
Entsprechend habe ich dann auch nicht weiter dran rumgedocktert...

Und wie gesagt, da die LED korrekt blinkt, sag mir dann doch bitte, was 
das mit dem nicht Funktionieren des LCDs zu tun hat?

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> Ich habe die alte Software für den AtxMega umgeschrieben, das Ergebnis
> ist im Anhang.

Auf welchen LCD Controller hast du dich denn jetzt dabei spekulativ
eingeschossen? Es stand ja dauernd die Frage im Raum welcher
Controller bei dir wirklich eingebaut ist .....

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> Was meinst du mit "Damit sicher nicht"?
1
int main (void)
2
{
3
>  /* Enable necessary Clock sources. 32MHz and 32kHz Oscillator */
4
>  OSC.CTRL = OSC_RC32MEN_bm;
5
>  /* Wait for Oscillators to become stable */
6
>  while(!(OSC.STATUS & OSC_RC32MRDY_bm));
7
>
8
>  /* Start Calibrating the 32MHz Clock using
9
>  * the internal calibrated 32kHz Oscillator */
10
>  OSC.DFLLCTRL = (0 << OSC_RC32MCREF_bp);
11
>  DFLLRC32M.CTRL = DFLL_ENABLE_bm;
12
>  /* Set as System Main Clock */
13
>  CCP = CCP_IOREG_gc;
14
>  CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
15
>
16
>  /* Lock Clock Settings until next Reset */
17
>  CCP = CCP_IOREG_gc;
18
>  CLK.LOCK = CLK_LOCK_bm;
19
}

Build started 21.4.2016 at 16:55:57
avr-gcc  -mmcu=atmega644 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT test.o -MF 
dep/test.o.d  -c  ../test.c
../test.c: In function 'main':
../test.c:3: error: expected expression before '>' token
../test.c:5: error: expected expression before '>' token
../test.c:7: error: expected expression before '>' token
../test.c:11: error: expected expression before '>' token
../test.c:12: error: expected expression before '>' token
../test.c:14: error: expected expression before '>' token
../test.c:15: error: expected expression before '>' token
../test.c:18: error: expected expression before '>' token
make: *** [test.o] Error 1
Build failed with 8 errors and 0 warnings...

von Honda (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Honda schrieb:
>> Ich habe die alte Software für den AtxMega umgeschrieben, das Ergebnis
>> ist im Anhang.
>
> Auf welchen LCD Controller hast du dich denn jetzt dabei spekulativ
> eingeschossen? Es stand ja dauernd die Frage im Raum welcher
> Controller bei dir wirklich eingebaut ist .....

Spekulativ genauso wie vorher. Entsprechend einen ILI****.
Anpassen musste ich ja lediglich den Zugriff auf die Pins. Also sowas 
wir PORTB -> PORTB.OUT usw. Die Initialisierungsroutine als solche ist 
die Gleiche geblieben. Prinzipiell funktionierten die Funktionen mit dem 
AtMega1284p ja auch soweit. (Bis auf das Auslesen, was noch nie mir 
sinvoll vorkommende Werte ausspuckte)

von Arduinoquäler (Gast)


Lesenswert?

Honda schrieb:
> Spekulativ genauso wie vorher. Entsprechend einen ILI****.

Ich empfehle dir eine bestehende Initialsierung zu verwenden
(z.B. aus der UTFT Lib, die ja offensichtlich funktionieren)
die auf den ILI9341 Controller abzielt). Nach dem Überblick
im Angebot scheint genau dieser in den Displays mit 2.2 und 2.4
Inch verwendet zu werden.

Weiterhin kommt mir diese Zeile verdächtig vor
(ob du das wirklich willst?)
1
LCD_WriteReg(0x0003, 0xD030); // 1100 0000 0011 0000 (0x1030);
2
 // 3x6-bit Übertragung, GRAM-Counter beide aufwärts
Dein Code ist auf 16 bit ausgelegt, hier willst du aber 18?

Weiterhin:
1
/*    COLORS        */
2
#define   BLACK 0xFFFF
3
#define   WHITE 0x0000

Schwarz = wenig Licht = wenig Zahl = 0
Weiss   = viel Licht = viel Zahl = 0xFFFF

von Arduinoquäler (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Ich empfehle dir eine bestehende Initialsierung zu verwenden

Hier kannst du dir auch eine Initialsierung rausziehen:

https://github.com/adafruit/Adafruit_ILI9341/blob/master/Adafruit_ILI9341.cpp

von Arduinoquäler (Gast)


Lesenswert?


von Honda (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Ich empfehle dir eine bestehende Initialsierung zu verwenden
> (z.B. aus der UTFT Lib, die ja offensichtlich funktionieren)
> die auf den ILI9341 Controller abzielt). Nach dem Überblick
> im Angebot scheint genau dieser in den Displays mit 2.2 und 2.4
> Inch verwendet zu werden.

Habe die verlinkten Libs ausprobiert. Das Initialisieren funktioniert 
wie üblich, gemalt wird nix...
Was mich wundert, ist, dass die bestehende Routine ja auch schon 
funktioniert hatte, als ich sie auf dem Mega1284p verwendete. Erst als 
ich sie auf den XMega transferierte ging sie nicht mehr!

Ich habe nun mehrfach alle Daten-Pins durchgemessen und für korrekt 
angeschlossen befunden. Eine Testroutine, die nach einander alle Pins 
durchläuft, bestätigte mein Befund.



> Weiterhin kommt mir diese Zeile verdächtig vor
> (ob du das wirklich willst?)
> LCD_WriteReg(0x0003, 0xD030); // 1100 0000 0011 0000 (0x1030);
>  // 3x6-bit Übertragung, GRAM-Counter beide aufwärts
> Dein Code ist auf 16 bit ausgelegt, hier willst du aber 18?

Das stimmt, das ist in der Tat falsch. Dürfte allerdings nicht zu dem 
Fehler führen. Eine Änderung meiner Routine auf 0x5030 hat leider auch 
nicht geholfen.

> Weiterhin:/*    COLORS        */
> #define   BLACK 0xFFFF
> #define   WHITE 0x0000
>
> Schwarz = wenig Licht = wenig Zahl = 0
> Weiss   = viel Licht = viel Zahl = 0xFFFF

Auch da hast du Recht, durch viel Rumprobieren und basteln entstand das 
irgendwann so :D Die Werte wurden beim Beschreiben invertiert, wodurch 
die Farben damals so korrekt waren. Da die Routine auch nicht mehr 
existiert, habe ich die Werte wieder getauscht.


Wie kann es sein, dass die Initialisierung erfolgreich ist, eine 
Beschreibung aber unmöglich, obwohl der benutzte Code bereits 
funktioniert hatte? Gibt es etwas, was beim XMega zu beachten ist, was 
diesen Fehler erzeugen kann?

von Honda (Gast)


Lesenswert?

Ich habe nun einmal sämtliche Pins manipuliert. Also in die Funktion
LCD_WriteCMD entweder
value |= 0b1;
oder
value &= ~0b1;
benutzt, um einen der Pins konstant auf einen Wert zu setzen. Sollte 
sich bei beiden Manipulationen nichts am Erfolg der Initialisierung 
ändern, so könnte dieser Pin defekt sein. Leider brachte auch diese 
Überprüfung keinen Erfolg. Egal welchen Pin ich manipulierte, die 
Initialisierung schlug jedes Mal fehl. Heißt, auf jeden Fall ist jeder 
Pin angeschlossen und da die Initialisierung auch korrekt verläuft, wohl 
richtig.

von Honda (Gast)


Lesenswert?

Ich habe das Display nun wieder am AtMega1284p angeschlossen. 
Tatsächlich zeigt es mir auch dort kein Bild mehr an. Die 
Initialisierung funktioniert, das Bild nicht. Und das mit dem Programm, 
welches bereits lief!

Stellt sich mir nun die Frage, ist das LCD eventuell einfach defekt?

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.