Forum: Mikrocontroller und Digitale Elektronik ILI9486 8-Bit Parallel Bus deutlich langsamer als SPI


von Felix N. (felix_n888)


Lesenswert?

Guten Abend,

Ich habe mal eine Frage. Ich bin zurzeit an einem kleinen Projekt am 
basteln für welches ich ein TFT Display gebrauche. Bis jetzt habe ich 
immer Displays mit dem ILI9341 Controller genommen meistens in der Größe 
von 2,2 oder 2,8 Zoll. Die Display sind mit einem SPI Interface 
ausgestattet.

Nun möchte ich gerne ein 4 Zoll Display mit dem ILI9486 Controller 
verwenden, aufgrund der besseren Lesbarkeit auf Entfernung wegen der 
Größe. Dieser verwendet ein 8-Bit Parallel Datenbus plus ein paar 
Steuerleitungen. Da die Controller nahe zu identisch sind war es so gut 
wie kein Problem diesen ans laufen zu bekommen. Nur die Geschwindigkeit 
ist im Verhältnis zum ILI9341 sehr langsam.

Gut der ILI9486(480x320) hat jetzt doppelt so viele Pixel wie der 
9341(320x240). Mit meiner halbwegs "optimierten" ILI9341-SPI Library 
schaffe ich bei einem STM32F103C8T6 auf dem SPI2 Bus mit 18MHz SCK Takt 
eine vollständige Bildschirmlöschung in 150ms. Was mir schon völlig 
ausreicht. Wenn ich den noch schnelleren SPI1 Bus(AHB läuft auf 72MHz) 
dann geht das sogar noch schneller bin mir nicht mehr sicher aber das 
müsste etwas um die 20-40ms gewesen für eine komplette Löschung. Da kann 
man schon fast die einzeln Farben nicht mehr richtig erkennen so schnell 
wechselt das ganze.

Beim 4 Zoll Display mit ILI9486 brauche ich für eine komplette Löschung 
jedoch 777ms. Selbst wenn ich die Pixelanzahl in der Software begrenze 
auf 320x240 so das Links und Unten vom Display nur weiß ist brauche ich 
immer noch gut 400ms. Erst bei einer Auflösung von 150x150 komme ich auf 
die gleichen 140ms.

Die CPU selbst läuft auf 72 MHz. Der Code für das ganze 
Grafik/Ansteuerung Zeugs ist absolut identisch mit dem 9341. Nur der I/O 
Kram ist anderes, und da glaube ich ist auch das Problem. Ich verwende 
folgenden Code um die Daten ans Display zu senden:
1
//Aus der Header datei
2
#define DX_HIGH(port, pin) port->BSRR |= (1<<pin)
3
#define DX_LOW(port, pin)  port->BSRR |= (1<<(pin + 16))
4
5
  if(data & (1<<0)) DX_HIGH(GPIOA, ILI_D0); else DX_LOW(GPIOA, ILI_D0); //LCD_D0 PB15
6
  if(data & (1<<1)) DX_HIGH(GPIOA, ILI_D1); else DX_LOW(GPIOA, ILI_D1); //LCD_D1 PB13
7
  if(data & (1<<2)) DX_HIGH(GPIOA, ILI_D2); else DX_LOW(GPIOA, ILI_D2); //LCD_D2 PB12
8
  if(data & (1<<3)) DX_HIGH(GPIOB, ILI_D3); else DX_LOW(GPIOB, ILI_D3); //LCD_D3 PA15
9
  if(data & (1<<4)) DX_HIGH(GPIOB, ILI_D4); else DX_LOW(GPIOB, ILI_D4); //LCD_D4 PA12
10
  if(data & (1<<5)) DX_HIGH(GPIOB, ILI_D5); else DX_LOW(GPIOB, ILI_D5); //LCD_D5 PB4
11
  if(data & (1<<6)) DX_HIGH(GPIOB, ILI_D6); else DX_LOW(GPIOB, ILI_D6); //LCD_D6 PB3
12
  if(data & (1<<7)) DX_HIGH(GPIOB, ILI_D7); else DX_LOW(GPIOB, ILI_D7); //LCD_D7 PB5
13
14
  WR_ACTIVE;
15
  WR_IDLE;

Wüsste jetzt aber nicht wie man das noch groß optimieren kann. Außer das 
alle Datenleitungen an einem Port hintereinander zulegen so das LCD_D0 = 
PA0 ... LCD_D7 = PA7 wäre. Dann könnte ich das ganze direkt mit 
GPIOX->BSRR = xxx machen ohne das ganze if else aber ich weiß nicht ob 
das so viel Unterschied machen würde.

Hat da noch jemand ne Idee was man machen könnte um die Übertragung 
schneller zu machen? Bzw. warum ist das Display im Parallel Bus so viel 
langsamer als das andere im SPI Modus, auch wenn die Pixelanzahl gleich 
ist bei beiden.

Die entsprechenden GPIO Pins sind alle als Output Push-Pull mit einer 
maximalen Geschwindigkeit von 50MHz konfiguriert.

Mfg

von Frank K. (fchk)


Lesenswert?

Benutze den FMC. Dann wird alles von der Hardware erledigt, und nur so 
erreichst Du die maximale Geschwindigkeit. Für den FMC ist das Display 
ein einfaches SRAM.

fchk

von Harry L. (mysth)


Lesenswert?

Felix N. schrieb:
> Dann könnte ich das ganze direkt mit
> GPIOX->BSRR = xxx machen ohne das ganze if else aber ich weiß nicht ob
> das so viel Unterschied machen würde.

Natürlich macht das einen Unterschied.
Einen Gewaltigen sogar.

Wie oben bereits gesagt: nutze eine MCU mit FMC.

Der F103 hat eh zu wenig RAM für solche Spielereien.

von Felix N. (felix_n888)


Lesenswert?

Frank K. schrieb:
> Benutze den FMC. Dann wird alles von der Hardware erledigt, und nur so
> erreichst Du die maximale Geschwindigkeit. Für den FMC ist das Display
> ein einfaches SRAM.

Hallo Frank,

Also ist das FMC so etwas ähnliches wie das XMEM Interface bei den AVRs? 
Nur der STM32F103C8T6 hat dieses Interface leider nicht.

Harry L. schrieb:
> Natürlich macht das einen Unterschied.
> Einen Gewaltigen sogar.

Ok dann habe ich nix gesagt. Wie macht man denn sowas bei den STM32 am 
besten? Das BSRR Register hat ja 16-Bit für das setzten eines Bit und 16 
Bit für das löschen eines Bits. Kann man dann das Output Data 
Register(ODR) nutzen und dann einfach GPIOX->ODR |= data & 0xFF; machen? 
Bei dem BSRR Register müsste ich doch wieder abfragen ob es eine 0 oder 
1 ist um dann entsprechend das normal Bit zu setzten oder das Bit + 16 
zu löschen.

Harry L. schrieb:
> nutze eine MCU mit FMC.

Grundsätzlich kein Problem, nur leider sind die tollen MCUs fast einfach 
nicht zu bekommen. Ich habe vor einem Monat mit einem Nucleo-64 Board 
mit einem STM32F446RE angefangen der hat meinig auch das FMC Interface 
andere haben glaubig sogar direkt ein 8080 Parallel Interface. Und die 
Blue Pill Board kriegt man ganz gut noch ist zwar meistens ein CKS statt 
ein STM drauf, aber für meine letzten 2 Projekte war der völlig 
ausreichend.

Harry L. schrieb:
> Der F103 hat eh zu wenig RAM für solche Spielereien.

Naa, ich habe das ganze Projekt schonmal auf ein ATMega328P mit 16 MHz 
aufgebaut das ging noch nur hat mich die geringe Refresh Rate gestört 
und das mir der FLASH ausgegangen ist.

Mfg

von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> Außer das
> alle Datenleitungen an einem Port hintereinander zulegen so das LCD_D0 =
> PA0 ... LCD_D7 = PA7 wäre. Dann könnte ich das ganze direkt mit
> GPIOX->BSRR = xxx machen ohne das ganze if else

Genau so macht man das!

Felix N. schrieb:
> aber ich weiß nicht ob das so viel Unterschied machen würde.

Dann lass dir von mir sagen dass das den ganz grossen
Unterschied macht.

Siehe auch:  Beitrag "LCD 480x320 mit wenig Aufwand zum Anbinden"

von Felix N. (felix_n888)


Angehängte Dateien:

Lesenswert?

Mal so ganz blöd gefragt, mir kam da gerade so eine Idee:

Ich habe noch welche von den 74HC595 8-Bit Schieberegistern. Die haben 
ja logischerweise 8 Ausgänge(LCD_D0 bis LCD_D7) und entsprechend ein 
Shift, Store und Datenpin.

Wenn ich jetzt das SPI Interface nehme MOSI auf den Datenpin des 595 
lege. CS auf den Storepin und das SCK Taktsignal auf den Shiftpin dann 
dann habe ich doch, in meinen Kopf zu mindestens gerade, ein SPI auf 
Parallel Bus Wandler gebaut bzw. das Datenblatt sagt in den 
"Applications" sogar auch "Serial to Parallel Data Conversion".

Laut Datenblatt liegt fMax bei 4,5V bei 91 MHz und bei 2V bei 30MHz also 
bei 3,3V irgendwo bei ~50MHz oder so. Sollte für 18MHz SPI oder evtl. 
auch 36MHz SPI noch locker reichen.

CS, D/C und WR bediene ich dann noch ganz normal über die GPIOs. Müsste 
man damit dann nicht auch höhere Geschwindigkeiten erreichen lassen?

Ein versuch wäre es morgen alle mal für mich Wert. Vielleicht gab es 
sowas ja auch schon mal? Oder wurde gemacht? Hab mal ein Schaltbild 
angehängt wie ich mir das ganze vorstelle.

//EDIT:



Mfg

Arduinoquäler schrieb:
> Genau so macht man das!

Ok werde ich als erstes testen bevor ich mein oben Beschriebenes 
vorhaben versuche.

Arduinoquäler schrieb:
> Dann lass dir von mir sagen dass das den ganz grossen
> Unterschied macht.

Ja dann.

Arduinoquäler schrieb:
> Siehe auch:  Beitrag "LCD 480x320 mit wenig Aufwand zum Anbinden"

Danke

: Bearbeitet durch User
von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> Danke

Als Nachtrag:

Arduinoquäler schrieb:
> Ich komme damit für den Vorgang des Display Löschens auf nur 90ms Dauer
> (480x320 Pixel a 16 Bit).

Auf einem ATMega644 mit 20MHz.

von Felix N. (felix_n888)


Lesenswert?

Arduinoquäler schrieb:
> Auf einem ATMega644 mit 20MHz.

Ja habe mir den Beitrag gerade auch durchgelesen.

Und das alles nur durch das setzten der Daten auf den Port direkt sprich 
GPIO->ODR = data & 0xFF; oder steckt da noch mehr dahinter. Ich meine 
der STM läuft ja auf einer ganz anderen Geschwindigkeit.

Hab mir wohl den Code von Arduino Librarys angeschaut wie MCUFriend 
allerdings steig ich da nicht hinter da wird das ganze mit Makros 
gemacht.

Mfg

von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> Müsste
> man damit dann nicht auch höhere Geschwindigkeiten erreichen lassen?

Klar geht das auch, denn immerhin kannst du auf dem F103 SPI1
mit 36 MHz laufen lassen (SPI2 nur 18MHz). Da gilt es nur
aufzupassen dass die SPI-Anbindung schon etwas anspruchsvoll
wird (Clock-Flanken, Masse-Bezug etc).

Etwas Overhead gibt es da man bei jedem Byte die SPI-Maschine
des F103 abwarten muss bis sie fertig ist. Das dauert etwas
länger. Beim Parallel-I/O ist man nach dem Write-Low/Write-High
Zyklus und CS-Off schon fertig.

von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> Und das alles nur durch das setzten der Daten auf den Port direkt

Ja.

Felix N. schrieb:
> oder steckt da noch mehr dahinter

Nein .... Nur CS und Write-Cycle

Felix N. schrieb:
> Ich meine
> der STM läuft ja auf einer ganz anderen Geschwindigkeit.

Wenn du den F103 meinst, der braucht natürlich auch ein paar
Zyklen, aber das geht trotzdem flott.

von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> Hab mir wohl den Code von Arduino Librarys angeschaut wie MCUFriend
> allerdings steig ich da nicht hinter da wird das ganze mit Makros
> gemacht.

Ich meine: "Arduino Library" sagt alles. Die müssen ja immer
über die Port-Definitionen und Digital Write gehen, das nagt
sehr an der Performance. Seit vielen Jahren für mich als
Geschwindigkeits-Optimierer ein rotes Tuch.

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Felix N. schrieb:
> isplay mit dem ILI9486 Controller
> verwenden, aufgrund der besseren Lesbarkeit auf Entfernung wegen der
> Größe. Dieser verwendet ein 8-Bit Parallel Datenbus plus ein paar
> Steuerleitungen.

Wie kommst du darauf? Laut Datenbalat Kap. 7.1.3 hat er sowas durchaus.
- 
https://www.displayfuture.com/Display/datasheet/controller/ILI9486L.pdf

Dem kompletten Bildschirm löschen (auf einem Controller der weder einen 
Doppelten Framebuffer hat noch Blockbefehle) ist meist eh keine allzu 
gute Idee. Eher immer nur eine Zeile oder sogar nur einen Bereich 
aktualisieren wo sich auch wirklich was geändert hat. Ggf. einfach 
nochmal den vorherigen Text mit derselben Farbe wie den Hintergrund 
ausgeben und danach den neuen Text in "sichtbarer" Farbe ausgeben. Die 
vertikal scroll Funktion ist da manchmal auch recht hilfreich. Eine 
Text-Zeile nach unten scrollen und ober dann die neue hinschreiben. 
Einfach mal nicht den eingeschlagenen Lösungsweg gedanklich 
Festzementieren sondern kreativ werden was noch so alles möglich ist. 
Dann kann man selbst mit solch eher einfach gestrickten Controllern ein 
ansprechende Anzeige ohne großes Flackern, langsame 
Aktualisierungszeiten usw. realisieren.

von Philipp K. (philipp_k59)


Lesenswert?

Vielleicht ein Blackpill(stm32f4) mit externem Flash, da kann man sogar 
Zeichensätze als Bilder zum Display schieben. Da Lob ich mir das Arduino 
Framework, das gleiche Projekt in einer Stunde auf esp32,atmega oder 
Stm32 umbauen und dabei noch Recht leserlicher Code. (Die 
Schreibeoutinen für das LCD musste ich bisher immer direkt ohne Arduino 
schreiben)

Habe auch schon einen Blackpill liegen um zu testen ob der die 
Transparenz beim Schreiben hinbekommt.

von olaf (Gast)


Lesenswert?

> Ich meine der STM läuft ja auf einer ganz anderen Geschwindigkeit.

Irrelevant. Ihr solltest nicht vergessen das bei den modernen MCUs der 
Core einen anderen Takt hat als die Peripherie. Da muss runtergetaktet 
und einsycronisiert werden.

Ansonsten kann manchmal nicht schaden wenn man in seinem Debugger auf 
Assemblerdarstellung umstellt und sich mal den erzeugten Code anschaut. 
Sowas bildet ungemein. .-)
Und natuerlich die Finger weg von dem Arduinoscheiss. Wenn da jedesmal 
beim rumwedeln mit einem Port noch eine Funktion hinterhaengt dann ist 
das toedlch, erst recht bei den lahmen Arms die ihre Register auf dem 
Stack sichern muessen und keine Banks umschalten koennen.

Die hier angefuehrte Idee ein Register an SPI zu haengen geht 
natuerlich. Das hat man schon vor 30Jahren so gemacht. Ob es 
geschwindigkeitsmaessig was bringt muss man sehen oder besser genau 
ausrechnen. Ich vermute mal das haengt davon ab ob man das 
uebernahme-flag von Hand setzen muss oder ob es von SPI mitgehaendelt 
werden kann und man alles vom DMA machen lassen kann.

Olaf

von Walter T. (nicolas)


Lesenswert?

Alle Bits an einen Port macht es schneller. Es bleibt aber immer noch 
langsamer als SPI (Wartezeiten TDST und TWC im Datenblatt).

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Felix N. schrieb:
> Außer das
> alle Datenleitungen an einem Port hintereinander zulegen so das LCD_D0 =
> PA0 ... LCD_D7 = PA7 wäre. Dann könnte ich das ganze direkt mit
> GPIOX->BSRR = xxx machen ohne das ganze if else aber ich weiß nicht ob
> das so viel Unterschied machen würde.

Zumindest 8 aufeinanderfolgende Portbits, dann kann man das Byte 
hinschieben. Daß diese 8-fache if/else Orgie nicht performant ist, 
sollte klar sein.

Ich hatte früher auch oft aufs Layout optimiert. Heutzutage sind aber >2 
Lagen und Vias kein Kostenfaktor mehr.

von Johannes S. (Gast)


Lesenswert?

Felix N. schrieb:
> Grundsätzlich kein Problem, nur leider sind die tollen MCUs fast einfach
> nicht zu bekommen.

Da gibt es ein China Board mit dem F407, kostete mal 10€, müsste jetzt 
immer noch zu bekommen sein. Das Board das auch in dem STECCY Projekt 
hier verwendet wurde. Das hat extra einen Header auf dem 16 Bit für das 
FSMC liegen, es gibt auch 320x240 9341 Displays zum aufstecken.

Bei 320x480 hast du den Faktor 153.600, eine Differenz von 1 μs pro 
Pixel macht also gleich 153 ms in der Laufzeit. Da lohnt es sich an 
dieser Stelle zu optimieren.

von Bernd N. (_bn_)


Lesenswert?

https://www.stupid-projects.com/driving-an-ili9341-lcd-with-an-overclocked-stm32f103/

Also mit einem STM32F103 kommt man völlig aus. Ansteuerung per SPI DMA. 
Das sollte dann schnell genug sein.

von Walter T. (nicolas)


Lesenswert?

Sollte die Lösung übrigens letztendlich in einem preiswerten 
SPI-tauglichen TFT-Modul mit 800 x 600 Pixeln liegen, wäre ich sehr 
daran interessiert.

Ich finde bei der Auflösung nur die langsamen, Arduino-kompatiblen 
8-Bit-Module.

: Bearbeitet durch User
von Arduinoquäler (Gast)


Lesenswert?

Walter T. schrieb:
> Ich finde bei der Auflösung nur die langsamen, Arduino-kompatiblen
> 8-Bit-Module.

Dann zeig doch mal dein "TFT-Modul mit 800 x 600 Pixeln" mit 8-Bit
Ansteuerung.

von Johannes S. (Gast)


Lesenswert?

Wenn es um das schnelle Löschen bzw. Füllen eines Bereiches mit einer 
Farbe geht, dann kann man das optimieren indem man erst das Window 
setzt, dann die Farbe, dann nur noch x*y Schreibtakte. Das aufwändige 
zusammenfrickeln des Colorbytes ist da nur einmal nötig.
Libraries wie die AdafruitGFX machen das aber auch so.
Beim übertragen eines Framebuffers hilft das natürlich nicht.

von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> //Aus der Header datei
> #define DX_HIGH(port, pin) port->BSRR |= (1<<pin)
> #define DX_LOW(port, pin)  port->BSRR |= (1<<(pin + 16))

(Nebenbemerkung: bisschen schneller geht das auch)
Ein Ver-odern der Bits mit den Registern ist übrigens nicht
erforderlich. Das kann man erkennen wenn man die Funtionen
der SPL (z.B.) anschaut. Es gibt auch ein explizites Reset-
Register für die Port Bits .... spart alles ein paar Zyklen.

Leicht gekürzte Version:
1
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
2
{
3
  if (BitVal != Bit_RESET)
4
  {
5
    GPIOx->BSRR = GPIO_Pin;
6
  }
7
  else
8
  {
9
    GPIOx->BRR = GPIO_Pin;
10
  }
11
}

von Johannes S. (Gast)


Lesenswert?

Per lookup tables geht es auch einen Tick schneller, aber sinnvoller ist 
wirklich ein uC mit mehr IO und FMC.

von Arduinoquäler (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Leicht gekürzte Version:
> void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
... war leider zuviel gekürzt.
Der Vollständigkeit halber hier die richtige Definition:
1
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)

von Purzel H. (hacky)


Lesenswert?

Der Bus wird bitweise angesteuert anstelle von Byteweise.

Weshalb koennen die Bits nicht nebeneinander liegen ? PA0-PA7 ? Weshalb 
PB15, PB13, PB12, PA15, PA12, PB4, PB3, PB5 ?

Ich denk das bringt einen Faktor 20. Alle Compares fallen weg und alle 
Einzelzugriffe.

Alternativ, die Compares weg mit

PB15 = Data[0]      // LSB
data = data shr 1;  // shift right 1
PB13 = Data[0]
data = data shr 1;  // shift right 1
PB12 = Data[0]
data = data shr 1;  // shift right 1
PA15 = Data[0]
data = data shr 1;  // shift right 1
PA12 = Data[0]
data = data shr 1;  // shift right 1
PB4 = Data[0]
data = data shr 1;  // shift right 1
PB3 = Data[0]
data = data shr 1;  // shift right 1
PB5 = Data[0]

Vielleicht gibt es auch bitzugriffe...

PB15 = Data[0]      // LSB
PB13 = Data[1]
PB12 = Data[2]
PA15 = Data[3]
PA12 = Data[4]
PB4 = Data[5]
PB3 = Data[6]
PB5 = Data[7]    // MSB

von Arduinoquäler (Gast)


Lesenswert?

Purzel H. schrieb:
> Weshalb koennen die Bits nicht nebeneinander liegen ?

RTFT (read the fucking thread)

Wenn du nicht blind auf diesen Thread geantwortet sondern
aufmerksam alles durchgelesen hättest würdest du feststellen
dass der TO dies alles schon weiss.

von m.n. (Gast)


Lesenswert?

Johannes S. schrieb:
> aber sinnvoller ist
> wirklich ein uC mit mehr IO und FMC.

Und auch, wenn einzelne Controller nicht verfügbar sind, wäre ein 
Nucleo/Discovery-Board eine günstige Lösung, an einen geeigneten µC zu 
kommen. Beispiel: 
https://www.mouser.de/ProductDetail/STMicroelectronics/STM32F411E-DISCO?qs=ClYTdQWm4hA7%252B0FuWfpEHA%3D%3D

Selber hätte ich noch ein Nucleo-F746ZG, was ich wohl nicht mehr 
brauchen werde. Andere Leute hier haben sicherlich auch noch Boards, die 
nicht mehr gebraucht werden.
Noch eine Alternative: 
Beitrag "4,3" TFT-Controller STM32F730" einen STM32F730 
hätte ich auch noch.

von Felix N. (felix_n888)


Lesenswert?

Arduinoquäler schrieb:
> Klar geht das auch, denn immerhin kannst du auf dem F103 SPI1
> mit 36 MHz laufen lassen (SPI2 nur 18MHz). Da gilt es nur
> aufzupassen dass die SPI-Anbindung schon etwas anspruchsvoll
> wird (Clock-Flanken, Masse-Bezug etc).

Moin,

Ah ok, ja ich habe es heute versuch ans laufen zu bekommen mit dem 595. 
Irgendwie klappt das aber auch noch nicht. Ist aber auch egal ich 
bekomme damit scheinbar eh nicht mehr als 222ms hin.

Arduinoquäler schrieb:
> Dann lass dir von mir sagen dass das den ganz grossen
> Unterschied macht.

Ja und da hattest du recht. Ich habe nun die Pins PA0 bis PA7 für den 
Datenbus vorgesehen und konnte die Funktionen auf:
1
GPIOA->ODR = data & 0xFF;
2
WR_ACTIVE;
3
WR_IDLE;

kürzen.

Für eine Vollständige Löschung brauche ich jetzt nur noch 128ms anstatt 
700ms. Das ist schon nicht schlecht.

Irgend W. schrieb:
> Wie kommst du darauf?

Was meintest du genau?

Irgend W. schrieb:
> Eher immer nur eine Zeile oder sogar nur einen Bereich
> aktualisieren wo sich auch wirklich was geändert hat.

Das mache ich im normalen Betrieb auch. Nur den Bildschirm komplett zu 
löschen ist das zeitintensivste. Wenn das relativ niedrig ist, sind die 
Unterfunktionen wie drawRect, fillRect nochmal deutlich schneller. Also 
diente die Bildschirmlöschung nur als "Benchmark".

Ich hatte das ganze Projekt wie bereits oben mal erwähnt auf einem 
ATMega328P mit 16 MHz aufgebaut. Display war da ein 2,8 Zoll Display mit 
dem ILI9341 via SPI angesteuert. Das ganze ist eine Art 
"Überwachungsmonitor" für den PC. Die Hardware mit Display und so ist 
nur der eine Teil der andere Teil ist meine Java Software welche PC 
Daten wie GPU-Auslastung/Temperatur/Takt etc... von GPU-Z einließt und 
ans Display sendet und das Display stellt das ganze dann mit Analogen 
"Tachoanzeigen" da. Und noch ein bisschen RGB LED Kram.

Das ganze ist also quasi ein "Rework/Überarbeitung ..." oder wie man das 
auch immer nennt. Da aber das 2,8 Zoll Display aufgrund der Entfernung 
von wo man draufschaut relativ klein ist insbesondere weil ich kleine 
Schriftgrößen verwenden musste das ganze jetzt auf einem 4 Zoll Display.

olaf schrieb:
> Ansonsten kann manchmal nicht schaden wenn man in seinem Debugger auf
> Assemblerdarstellung

Kann ich nicht. Auf dem Blue-Pill Board ist ein CKS32F103C8T6 verbaut 
der lässt sich mit dem ST-Link nicht debuggen.

olaf schrieb:
> Die hier angefuehrte Idee ein Register an SPI zu haengen geht
> natuerlich. Das hat man schon vor 30Jahren so gemacht. Ob es
> geschwindigkeitsmaessig was bringt muss man sehen oder besser genau
> ausrechnen.

Habe ich noch nicht getestet bzw indirekt. Wenn ich den Code ohne 
Display laufen lasse mit den acht Datenleitungen nebeneinander braucht 
ein Löschzyklus 128ms(Lass ich mir via USART ausgeben und 1ms Timer), 
wenn ich die Lib auf SPI umstellte(SPI1, 36MHz) dann komme ich maximal 
auf 222ms Löschzeit für ein Zyklus. Von daher gehe ich mal davon aus das 
es langsamer ist als dass 8080 Interface.

Johannes S. schrieb:
> Da gibt es ein China Board mit dem F407, kostete mal 10€, müsste jetzt
> immer noch zu bekommen sein. Das Board das auch in dem STECCY Projekt
> hier verwendet wurde.

Ah danke, schaue ich mir mal an.

Johannes S. schrieb:
> Füllen eines Bereiches mit einer
> Farbe geht, dann kann man das optimieren indem man erst das Window
> setzt, dann die Farbe, dann nur noch x*y Schreibtakte. Das aufwändige
> zusammenfrickeln des Colorbytes ist da nur einmal nötig.

Die ili9341_clear Funktion die den ganzen Bildschirm löscht ist 
eigentlich eine fillRect Funktionen mit startX und startY = 0 sowie endX 
und endY die maximale Pixelanzahl.

Und die fillRect Funktion sieht wie folgt aus:
1
void ili9341_fillrect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) {
2
  if((x >=LCD_WIDTH) || (y >=LCD_HEIGHT)) return;
3
  if((x+w-1)>=LCD_WIDTH)
4
  w=LCD_WIDTH-x;
5
  if((y+h-1)>=LCD_HEIGHT)
6
  h=LCD_HEIGHT-y;
7
8
  ili9341_setAddress(x, y, x+w-1, y+h-1);
9
10
  for(y = h; y > 0; y--) {
11
    for(x = w; x > 0; x--) {
12
      ili9341_pushColor(color);
13
    }
14
  }
15
16
  CS_IDLE;
17
}

pushColor sendet einfach 2x ein 8Bit Wert: color >> 8 und color & 0xFF

Purzel H. schrieb:
> Weshalb koennen die Bits nicht nebeneinander liegen ? PA0-PA7 ?

Weil das zu dem Zeitpunkt wo ich das Display mit angeschlossen habe die 
einzigen freien Pins noch waren da andere Funktionen wie SPI2, I2C1 und 
2x USART2 bereits im Betrieb waren.

m.n. schrieb:
> Und auch, wenn einzelne Controller nicht verfügbar sind, wäre ein
> Nucleo/Discovery-Board eine günstige Lösung, an einen geeigneten µC zu
> kommen

Hmm, weiß nicht 20 Euro für ein Nucleo-64 F446RE blechen um an einen 
STM32F446RE und an den STM32F103C8T6(Der auf der ST-Link Platine oben 
sitzt) Controller zu kommen. Ist glaubig nicht die beste Idee. Zu 
mindestens Geldtechnisch gesehen und der Rest der Nucleo Platine ist 
dann auch unbrauchbar. Aber als Notlösung denke ich wäre es ok für 1-2 
male.

Mfg

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Felix N. schrieb:
> Irgend W. schrieb:
>> Wie kommst du darauf?
>
> Was meintest du genau?

Warum die nicht auch weiterhin einfach das SPI interface nutzt sondern 
meinst jetzt auf einmal als uralte 8080-Interfache nutzen zu müssen?

von Walter T. (nicolas)


Lesenswert?

Felix N. schrieb:
> Hmm, weiß nicht 20 Euro für ein Nucleo-64 F446RE blechen um an einen
> STM32F446RE und an den STM32F103C8T6(Der auf der ST-Link Platine oben
> sitzt) Controller zu kommen. Ist glaubig nicht die beste Idee.

Beim STM32F446RE wird es kaum schneller. Da muss man die Bus-Wartezeiten 
TDST und TWC dann tatsächlich implementieren. Für Sie getestet.

Wenn man das Timing zu dicht auf Kante näht, gibt es übrigens leichte 
Farbverfälschungen. Irgendwie scheinen die LSB langsamer als der Rest 
eingelesen zu werden oder eine höhere Kapazität zu haben, was zu Fehlern 
im grünen Bereich führt.

Irgend W. schrieb:
> Warum die nicht auch weiterhin einfach das SPI interface nutzt

Die billigen arduinoförmigen Displaymodule sind halt so. SPI wäre glaube 
ich jedem lieber. Aber die Module lassen sich nicht ohne weiteres 
ändern, da geklebt.

Felix N. schrieb:
> und der Rest der Nucleo Platine ist
> dann auch unbrauchbar.

Eigentlich kann man von den Nucleos fast nicht zuviele haben. Ich finde 
die klasse für jede Art von Testaufbau.

: Bearbeitet durch User
von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> Ja und da hattest du recht. Ich habe nun die Pins PA0 bis PA7 für den
> Datenbus vorgesehen und konnte die Funktionen auf:
> GPIOA->ODR = data & 0xFF;
> WR_ACTIVE;
> WR_IDLE;
>
> kürzen.
>
> Für eine Vollständige Löschung brauche ich jetzt nur noch 128ms anstatt
> 700ms. Das ist schon nicht schlecht.

Danke für die Rückmeldung. Meinen Äusserungen entsprechend hättest
du (und ich) ein noch besseres Ergebnis erwartet, aber das kann
man sich nachträglich schon erklären:

- du brauchst ein Read-Modify-Write um den 8-Bit Datenport
zu schreiben. Das braucht mehr Operationen als ein einfaches
direktes Write.
- der F103 hat natürlich eine I/O-Schicht die nicht direkt am
Core hängt was immer zu Synchronisations- bzw. Wartezyklen
führt. Insofern ist ein 8-Bit ATMega von Vorteil bei schnellen
Port Writes.

Will man den ersteren Aspekt vermeiden könnte man versuchen ob
man das ODR auch allein 8-bittig schreiben kann, bin aber
momentan nicht sicher ob das zulässig ist.

Felix N. schrieb:
> ili9341_pushColor(color);

Bisschen was kann man noch an Speed gewinnen indem man diese
Funktion nicht aufruft sondern deren Code direkt in die
Schleife legt.

WR_ACTIVE und WR_IDLE hast du nach meinem Hinweis optimiert?

von Bernd N. (_bn_)


Lesenswert?

Felix N. schrieb:
> wenn ich die Lib auf SPI umstellte(SPI1, 36MHz) dann komme ich maximal
> auf 222ms Löschzeit für ein Zyklus.

Ich hatte dir ja weiter oben einen Link gesetzt. Extrem Beispiel mit 
overclocking. Ich verwende die gleiche Program Logik aber ohne 
overclocking, ist zwar mal eine nette Spielerei aber für einen 
vernünftigen Betrieb eh nicht brauchbar. Wie dem auch sei, verwendet man 
die SPI mit DMA und baut das Program vernünftig auf dann dauert ein 
clear display max 40 mSec. Mit anderen Worten, dein Program gehört mal 
aufgeräumt und optimiert.

von Johannes S. (Gast)


Lesenswert?

Felix N. schrieb:
> for(y = h; y > 0; y--) {
> 11    for(x = w; x > 0; x--) {
> 12      ili9341_pushColor(color);
> 13    }
> 14  }

Da wird unnötig Zeit verbraten. Einmal den Datenport setzen, dann h*w 
Pulse mit WR_ACTIVE; WR_IDLE; generieren.

von Arduinoquäler (Gast)


Lesenswert?

Bernd N. schrieb:
> Wie dem auch sei, verwendet man
> die SPI mit DMA und baut das Program vernünftig auf dann dauert ein
> clear display max 40 mSec.

Das mag für das Setzen von Massen von Bits zutreffen. Es hilft
leider überhaupt nichts für die kleinen Operationen, da wo man
kleine Rechtecke füllen muss. Typisches Beispiel sind Fonts.
Dort müsste man für jeden Teilbereich eines Characters (Quatrate,
Rechtecke oder einzelne Pixel) jeweils einen neuen DMA aufsetzen
was extrem mit Overhead behaftet ist. Nein, man kann nicht
einfach die komplette Bitstruktur eines einzelnen Characters
einfach komplett mit DMA ins Display RAM flashen.

Daher ist DMA in unserem Zusammenhang immer nur die halbe Miete.

von Arduinoquäler (Gast)


Lesenswert?

Johannes S. schrieb:
> Da wird unnötig Zeit verbraten. Einmal den Datenport setzen, dann h*w
> Pulse mit WR_ACTIVE; WR_IDLE; generieren.

Ja klar, ganz richtig. Hätte nur auch mal in meinem Code
nachschauen brauchen ....

von Johannes S. (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Daher ist DMA in unserem Zusammenhang immer nur die halbe Miete.

Ist bei diesen Displays sinnvoll wenn man erst in einen Buffer zeichnet 
und den dann überträgt. Gerade bei Zeichen mit ungleichen Größen kann 
man damit flackern vermeiden. Altes Zeichen löschen und neues 
drübermalen flackert, auch wenn nur wenige ms dazwischen liegen.

von Bernd N. (_bn_)


Lesenswert?

Arduinoquäler schrieb:
> Daher ist DMA in unserem Zusammenhang immer nur die halbe Miete.

Nein, das ist ein Baustein von vielen. Ich mache z.B. keine 
Grenzwertabfragen in jeder Funktion sondern exakt nur eine an einer 
einzigen Stelle.

Das hier ist kraut und Rüben...
1
void ili9341_fillrect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) {
2
  if((x >=LCD_WIDTH) || (y >=LCD_HEIGHT)) return;
3
  if((x+w-1)>=LCD_WIDTH)
4
  w=LCD_WIDTH-x;
5
  if((y+h-1)>=LCD_HEIGHT)
6
  h=LCD_HEIGHT-y;
7
  ili9341_setAddress(x, y, x+w-1, y+h-1);
8
9
  for(y = h; y > 0; y--) {
10
    for(x = w; x > 0; x--) {
11
      ili9341_pushColor(color);
12
    }
13
  }
14
  CS_IDLE;
15
}

von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Bildschirm löschen ist eine oft vorkommende Aktion, die eine 
extra-Implementierung rechtfertigt, um eine große einfarbige Fläche 
möglichst schnell zu senden.

Aber der Teil mit den Fonts stimmt natürlich. Hier ist das saubere 
Bus-Timing extrem wichtig. Ich habe mal ein Bild angehängt. Ist ein 
ILI9341 auf einem STM32F446RE, weil ich das gerade auf dem Schreibtisch 
habe, aber beim 9488 sieht es gleich aus. Wegen der Demo habe ich das 
Warten ein wenig knapper gemacht.

Der einfarbige dunkle Hintergrund (nicht schwarz) wird mit der immer 
gleichen Wiederholung der gleichen zwei Bytes in einer extra dafür 
implementierten Funktion möglichst schnell geschrieben und ist 
fehlerfrei.

Die Fonts kommen später und werden als Rechtecke geschrieben. Man sieht, 
dass einzelne Grünwerte nicht stimmen, obwohl die Einzelpixel sogar 
etwas langsamer geschrieben werden. Wenn ganze Spalten gleichfarbig 
sind, tritt es nicht oder seltener auf. Der Effekt ist nur bei gekipptem 
Display zu sehen.

Bei SPI-Display gibt es diesen Effekt nicht und bei großzügigerem Timing 
verschwindet er glücklicherweise. Deswegen reichen einzelne NOPs nicht 
mehr auf dem STM32F446 - er kann bei den 8-Bit-Displays nur mit höherer 
Taktfrequenz warten.

: Bearbeitet durch User
von Arduinoquäler (Gast)


Lesenswert?

Johannes S. schrieb:
> Ist bei diesen Displays sinnvoll wenn man erst in einen Buffer zeichnet
> und den dann überträgt.

Ja gut .... 480x320 Pixel á 16 Bit ergibt gut 300kByte. Um diesen
Buffer bereitzustellen braucht es schon ein etwas grösseres STM32
Kaliber. Nicht aber einen F103.

Mit Framebuffer arbeiten ist daher schon eine andere Liga,
erfordert auch in der gesamten Programmierung ein etwas
anderes Konzept.

von Arduinoquäler (Gast)


Lesenswert?

Bernd N. schrieb:
> Das hier ist kraut und Rüben...

Begründe das bitte ausführlich.

Ich sehe nur ein CS_IDLE welches dort nicht ganz passt.

Und ein ili9341_pushColor(color) welches nur einmal gebraucht
wird (und eben nicht in der Schleife), wie Johannes schon
richtig bemerkte.

von Arduinoquäler (Gast)


Lesenswert?

Walter T. schrieb:
> Die billigen arduinoförmigen Displaymodule sind halt so. SPI wäre glaube
> ich jedem lieber. Aber die Module lassen sich nicht ohne weiteres
> ändern, da geklebt.

Um deinen Horizont etwas zu erweitern:

Es gibt schon seit vielen Jahren das Display 480x320 mit ILI9488
für den RaspBerry. Das wissen scheinbar nur wenige, oder haben
es nicht kapiert dass es mit SPI geliefert wird, und dass man es
mit wenig Aufwand an jedes STM-Eval-Board oder an einen Arduino
anschliessen kann. Beim Arduino fällt dann noch die Pegel-
Anpassung an 3.3V an.

Siehe z.B. eBay-Artikelnummer 265211449760.

Mittlerweile gibt es auch (von Waveshare) dieses Display mit
SPI und direkt aufsteckbar auf die Arduino-Konnektoren.

Siehe z.B. eBay-Artikelnummer 283705700293.

Wenn sich jemand an ILI9488 vs. ILI9486 aufhängen sollte: die
sind annähernd identisch bzw. gleich zu behandeln.

von Arduinoquäler (Gast)


Lesenswert?

Arduinoquäler schrieb:
> Es gibt schon seit vielen Jahren das Display 480x320 mit ILI9488
> für den RaspBerry.

Hier

Beitrag "Re: STM32 F746zg nucleo und ILI9488 TFT per SPI langsam ?"

hatte ich schon mal mit einem Discovery F407 Board geübt.

Ist gut vier Jahre her. Auf dem zweiten Bild sieht man einen
Connector (blau) für die Displays mit 16-Bit Interface
(Ansteuerung über FSMC) und einen weiteren (weiss) für das
"RaspBerry-Display" (Ansteuerung über SPI).

von Walter T. (nicolas)


Lesenswert?

Arduinoquäler schrieb:
> Um deinen Horizont etwas zu erweitern:

Es erweitert nicht meinen Horizont, aber es ist gut zu wissen, dass es 
diese Module endlich auch in preisgünstig gibt.

von Arduinoquäler (Gast)


Lesenswert?

Walter T. schrieb:
> Es erweitert nicht meinen Horizont

Vielleicht kannst du meinen Horizont erweitern (der ja bereits
sehr gross zu sein scheint) indem du meine offene Frage zu deiner
haltlosen unbegründeten Behauptung beantwortest.

Walter T. schrieb:
> mit 800 x 600 Pixeln liegen, wäre ich sehr daran interessiert.
>
> Ich finde bei der Auflösung nur die langsamen, Arduino-kompatiblen
> 8-Bit-Module.

Meine Frage dazu lautete:

Arduinoquäler schrieb:
> Dann zeig doch mal dein "TFT-Modul mit 800 x 600 Pixeln" mit 8-Bit
> Ansteuerung.

von Arduinoquäler (Gast)


Lesenswert?

Arduinoquäler schrieb:
> (der ja bereits sehr gross zu sein scheint)

bezog sich natürlich auf:

Walter T. schrieb:
> Es erweitert nicht meinen Horizont

von Philipp K. (philipp_k59)


Lesenswert?

Wenn man schon Zeichnet kann man das Display im 8bit Modus fahren und 
kleinere Sachen vom RAM direkt per DMA schreiben.. das müsste definitiv 
schneller werden und die kleinen Grafiken kann man sauber anpassen.

Was sagt denn die Berechnung anstatt testen? zum Beispiel 8bit Modus 
könnten bis zu 68ms fürs löschen bringen.. mit den 122ms 16bit ist man 
da ja sogar unter dem Optimum.

von Walter T. (nicolas)


Lesenswert?

Arduinoquäler schrieb:
> Walter T. schrieb:
>> mit 800 x 600 Pixeln liegen, wäre ich sehr daran interessiert.
>>
>> Ich finde bei der Auflösung nur die langsamen, Arduino-kompatiblen
>> 8-Bit-Module.

Das war wohl ein freudscher Vertipper.

von Peter D. (peda)


Lesenswert?

Walter T. schrieb:
> Bildschirm löschen ist eine oft vorkommende Aktion

Ich habe das noch nie gebraucht. Ich überschreibe immer mit dem neuen 
Bildinhalt.
Zwischendurch löschen sieht unprofessionell aus, da es flackert, bis man 
das neue Bild schreibt. Z.B. bei der Heizungssteuerung fällt das sehr 
auf.
Auch bei nem Text-LCD sieht man das schön, wenn Anfänger löschen, bis 
der Arzt kommt.

von Felix N. (felix_n888)


Angehängte Dateien:

Lesenswert?

Arduinoquäler schrieb:
> Will man den ersteren Aspekt vermeiden könnte man versuchen ob
> man das ODR auch allein 8-bittig schreiben kann, bin aber
> momentan nicht sicher ob das zulässig ist.

Hallo,

Das Datenblatt vom F103C8T6 sagt beim GPIOX->ODR Register das es nur im 
Word Mode adressiert werden darf.

"These bits can be read and written by software and can be accessed in 
Word mode only."

Arduinoquäler schrieb:
> WR_ACTIVE und WR_IDLE hast du nach meinem Hinweis optimiert?

Ähmm ich habe nochmal geschaut in diesem Beitrag konnte aber nix finden? 
Sonst nein da habe ich im Moment noch nix gemacht. Was genau meinst du 
mit "optimiert"? Könntest du mir den entsprechend Beitrag nochmal 
nennen?

Bernd N. schrieb:
> Mit anderen Worten, dein Program gehört mal
> aufgeräumt und optimiert.

Ich weiß nicht mehr woher ich genau diese Lib habe. Ursprünglich war sie 
für den ILI9341 vorgesehen. Inzwischen habe ich sie für den ILI9341 ein 
bisschen optimiert bzw. das habe ich vor 1-2 Jahren gemacht. Ich habe 
die Dateien mal angehängt. Nicht wundern warum alles dort mit ili9341 
heißt wie gesagt ursprünglich für ili9341 vorgesehen nun auf 8080 
Parallel umgeschrieben für ILI9486.

Walter T. schrieb:
> Bildschirm löschen ist eine oft vorkommende Aktion, die eine
> extra-Implementierung rechtfertigt, um eine große einfarbige Fläche
> möglichst schnell zu senden.

Eigentlich mache ich das nur nach dem Init des Displaytreiber und falls 
neuzeichen einfach zu aufwendig wäre.

Arduinoquäler schrieb:
> Ich sehe nur ein CS_IDLE welches dort nicht ganz passt.

Das passt. Alle Funktionen rufen die ili9341_setAddress Function auf wo 
die X und Y Koordinaten gesetzt werden wodrin jetzt gearbeitet wird auf 
dem Display und dort mache ich dann das CS_ACTIVE entsprechend mit dem 
ganzen DC_COMMAND, DC_DATA etc... und danach kommen ja nur noch Daten 
also kommt dann zB. pushColor und danach ist die ganze Kommunikation mit 
dem Display abgeschlossen deswegen CS_IDLE. Spart ein paar Takte als 
immer wieder CS_ACTIVE; Daten schreiben WR_ACTIVE; WR_IDLE; CS_IDLE.

Arduinoquäler schrieb:
> Und ein ili9341_pushColor(color) welches nur einmal gebraucht
> wird (und eben nicht in der Schleife)

Das verstehe ich jetzt nicht ganz also die for schleife geht ja die 
ganzen Pixel durch die ich füllen will und pushColor sagt welche Farbe 
wenn ich die Farbe vorher fest lege was muss ich denn dann in der for 
Schleife machen?

Arduinoquäler schrieb:
> vielen Jahren das Display 480x320 mit ILI9488
> für den RaspBerry. Das wissen scheinbar nur wenige, oder haben
> es nicht kapiert dass es mit SPI geliefert wird

Ohh, das hört sich interessant an. SPI ist immer gut, meistens. Und 
danke für die Display Links.

Philipp K. schrieb:
> RAM direkt per DMA schreiben

Ich muss sagen ich arbeite noch nicht lange mit den STM32 Controllern. 
Etwa vor 1,5 Monaten habe ich mit einem Nucleo-64 STM32F446RE 
angefangen. Daher kenne ich mich mit den ganzen Bereichen die der 
Mikrocontroller bietet noch nicht so gut aus wie zB. bei den AVRs.

Die DMAs machen doch Memory to Memory oder Peripheral to Memory bzw. 
umgekehrt. Kann man damit auch die GPIO steuern? Oder bezog sich der DMA 
Content auf die Ansteuerung des Displays via SPI?

Philipp K. schrieb:
> Was sagt denn die Berechnung anstatt testen?

Muss gestehen das ich keine Ahnung habe was ich da berechnen soll 
geschweige denn wie.

Peter D. schrieb:
> Ich überschreibe immer mit dem neuen
> Bildinhalt.

Wenn das möglich ist mache ich das in der Regel auch. Zum Beispiel habe 
ich ein ILI9341 2,8 Zoll Display bei meinem Aquarium Steuergerät verbaut 
welches über Menüs verfügt um Werte abzulesen oder einzugeben. Da lösche 
ich den Bildschirm komplett einmal wenn das Menü gewechselt wird weil 
zum Teil komplette Bereich wie Bearbeitungsknöpfe, Neustart etc.. auf 
komplett anderen X,Y Koordinaten gesetzt werden müssen. Änderung im Menü 
selbst wie zB. die IP-Adresse des ENC28J60 wird direkt einfach durch ein 
neunen String ersetzt da er gleich lang ist überschreibt er einfach den 
alten Wert, da flackert dann gar nichts. Sonst wenn die länge nicht mehr 
stimmt fülle ich vorher mit einem schwarzen fillRect auf und schreibe 
dann neu.

Walter T. schrieb:
> Beim STM32F446RE wird es kaum schneller. Da muss man die Bus-Wartezeiten
> TDST und TWC dann tatsächlich implementieren. Für Sie getestet.

Ah ok. Auf die TXE Flag zu warten hat funktioniert konnte es aber mit 
__NOP() optimieren, anstatt auf das Flag zu warten. Falls sich das "Sie" 
auf mich bezogen hat "Du" ist auch okay :)

Walter T. schrieb:
> Eigentlich kann man von den Nucleos fast nicht zuviele haben. Ich finde
> die klasse für jede Art von Testaufbau.

War heute den ganzen Tag in Essen, zufällig ein Conrad Laden gefunden 
hatten aber keine Nucleo Boards mehr sonst hätte ich noch eins von da 
mit genommen. Sonst muss ich mal schauen ob ich mir davon noch welche 
besorge.

Walter T. schrieb:
> Wenn man das Timing zu dicht auf Kante näht, gibt es übrigens leichte
> Farbverfälschungen. Irgendwie scheinen die LSB langsamer als der Rest
> eingelesen zu werden oder eine höhere Kapazität zu haben, was zu Fehlern
> im grünen Bereich führt.

Ja das habe ich beim STM32F103C8T6 mit dem SPI2 Bus der auf 18 MHz SCK 
Takt lief auch beobachten können, das es teilweise Probleme gab wenn ich 
die Daten ins Datenregister(SPI2->DR) geschoben habe und dann nur 3 NOPs 
abgewartet habe. Bei 4 NOPs gehts zur Sicherheit habe ich 5 genommen.

Walter T. schrieb:
> Aber die Module lassen sich nicht ohne weiteres
> ändern, da geklebt.

Muss man dafür nicht ein paar bestimmte Pins des ILI Controllers auf 
Masse bzw. Vcc legen um das Interface festzulegen? Also praktisch fast 
unmöglich?

Mfg

von Philipp K. (philipp_k59)


Lesenswert?

Felix N. schrieb:
> Die DMAs machen doch Memory to Memory oder Peripheral to Memory bzw.
> umgekehrt.

Ja, aber das wichtige ist ja das es ohne rechenticks passiert.. also 
quasi ein separater Datenschaufler. Das geht auch zwischen SPI1 und 
SPI2.. zum Beispiel schiebe ich die kompletten Bilddaten via dma bei 
18Mhz vom Flash ins Display.

Mit Berechnung meinte ich zum Beispiel 1/(18000000/(480*320*8)) für 8 
Bit. Wobei ich mich noch Frage ob der stm32 überhaupt 8 Bit kann.

Ich benutze übrigens auch nur den 9488. Kein Plan wieso.

von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> Ähmm ich habe nochmal geschaut in diesem Beitrag konnte aber nix finden?
> Sonst nein da habe ich im Moment noch nix gemacht. Was genau meinst du
> mit "optimiert"?

Arduinoquäler schrieb:
> Ein Ver-odern der Bits mit den Registern ist übrigens nicht
> erforderlich. Das kann man erkennen wenn man die Funtionen
> der SPL (z.B.) anschaut. Es gibt auch ein explizites Reset-
> Register für die Port Bits .... spart alles ein paar Zyklen.

von Arduinoquäler (Gast)


Lesenswert?

Johannes S. schrieb:
> Wenn es um das schnelle Löschen bzw. Füllen eines Bereiches mit einer
> Farbe geht, dann kann man das optimieren indem man erst das Window
> setzt, dann die Farbe, dann nur noch x*y Schreibtakte. Das aufwändige
> zusammenfrickeln des Colorbytes ist da nur einmal nötig.

Felix N. schrieb:
> Das verstehe ich jetzt nicht ganz also die for schleife geht ja die
> ganzen Pixel durch die ich füllen will und pushColor sagt welche Farbe
> wenn ich die Farbe vorher fest lege was muss ich denn dann in der for
> Schleife machen?

Gemeint ist dass man den Datenport nur einmal mit der Farbe
beschreibt und dann nur noch Write-low-Write-high Zyklen aus-
führt, so viele wie Pixel geschrieben werden sollen. Das spart
die weiteren Schreibvorgänge auf den Datenport für die immer
gleich bleibende Farbe. Das funktioniert aber nur für 16-Bit-
Datenports, oder Pixel mit 8-Bit Farbauflösung am 8-Bit-Daten-
port, oder mit Nur-Weiss (0xFFFF) oder Nur-Schwarz (0x0000)
oder mit jeder 16-Bit Farbe bei der unteres und oberes Byte
gleich sind.

Alle Klarheiten beseitigt?

von Walter T. (nicolas)


Lesenswert?

Peter D. schrieb:
> Ich habe das noch nie gebraucht. Ich überschreibe immer mit dem neuen
> Bildinhalt.

Das mache ich innerhalb eines ... nennen wir es "Screens" auch. Aber 
beim Screen-Wechsel wird einmal mit der neuen Hintergrundfarbe 
überschrieben. Die Kacheln wirklich lückenlos zu bekommen ist mir zu 
mühsam.

Felix N. schrieb:
> Muss man dafür nicht ein paar bestimmte Pins des ILI Controllers auf
> Masse bzw. Vcc legen um das Interface festzulegen? Also praktisch fast
> unmöglich?

Genau. Und das auf Flex-Leiter. Ich habe es für mich als "unpraktikabel" 
abgestempelt.

von olaf (Gast)


Lesenswert?

> Genau. Und das auf Flex-Leiter. Ich habe es für mich als "unpraktikabel"
> abgestempelt.

Das geht schon. Ich hab das vor >15Jahren mal mit einem Display von 
Pollin
gemacht weil der Controller auch nur Parallel rausgefuehrt hatte:

http://www.criseis.ruhr.de/bilder/wenn_ihr_euch_dann_besser_fuehlt.jpg

Ich hab das damals sogar ohne Mikroskop gemacht. Der Trick besteht
darin vor den Löten an den duennen Leiterbahnen links und recht einen
Aufkleber drauf zu kleben. Man schafft sich so eine passende
Loetstopmaske .-)
Der rote Faedeldraht ist das uebliche Zeug mit 0.2mm. Das goldene Zeug
ist duenner. Ich glaub das hatte ich irgendwo von einem Trafo 
abgewickelt.
Die Loetstellen an dem IC selber sind leider etwas schlecht zu sehen
weil ich das 2k-Kleber draufgemacht habe.

Olaf

von m.n. (Gast)


Lesenswert?

Peter D. schrieb:
>> Bildschirm löschen ist eine oft vorkommende Aktion
>
> Ich habe das noch nie gebraucht. Ich überschreibe immer mit dem neuen
> Bildinhalt.

Das ist doch praxisfremd. Nach Rückkehr aus einem Untermenü ist der 
Bildschirminhalt unbekannt, und es muß zwangsläufig alles gelöscht und 
neu geschrieben werden.

> Zwischendurch löschen sieht unprofessionell aus, da es flackert, bis man
> das neue Bild schreibt. Z.B. bei der Heizungssteuerung fällt das sehr
> auf.

Mit der richtigen Soft-/Hardware flackert da nichts. Aber bei den 
"hiesigen" Anwendungen handelt es sich auch wohl mehr um Zeichnen, wo 
man dann zusehen kann, wie sich das Bild aufbaut.
Heizungssteuerung? Ist das ein Ersatz fürs Fernsehkucken?
Die kann im Keller doch flackern wie wild.

> Auch bei nem Text-LCD sieht man das schön, wenn Anfänger löschen, bis
> der Arzt kommt.

Was soll das denn? Schön, daß man nicht so doof ist wie die Anderen?

Diese ILI-Controller mit ihrer lockeren Anbindung an den µC sind ganz 
praktisch, für wenig Geld eine TFT-Anzeige inkl. lokalem Bildspeicher zu 
bekommen. Wenn man Geschwindigkeit braucht muß der µC direkten Zugriff 
auf den Bildspeicher haben.

von m.n. (Gast)


Lesenswert?

Felix N. schrieb:
> Hmm, weiß nicht 20 Euro für ein Nucleo-64 F446RE blechen um an einen
> STM32F446RE und an den STM32F103C8T6(Der auf der ST-Link Platine oben
> sitzt) Controller zu kommen. Ist glaubig nicht die beste Idee. Zu
> mindestens Geldtechnisch gesehen und der Rest der Nucleo Platine ist
> dann auch unbrauchbar. Aber als Notlösung denke ich wäre es ok für 1-2
> male.

Entweder man braucht den µC, dann ist derzeit die Verfügbarkeit das 
wichtigste Kriterium, oder man braucht ihn nicht. Bei einem Einzelstück 
ist der Preis nicht so entscheidend.
Aktuell werden F303 in angeknabberter Verpackung angeboten: 
https://www.mikrocontroller.net/topic/523341#6789705
Leider aber auch ohne FSMC.

von Walter T. (nicolas)


Lesenswert?

olaf schrieb:
> Das geht schon. Ich hab das vor >15Jahren mal mit einem Display von
> Pollin
> gemacht weil der Controller auch nur Parallel rausgefuehrt hatte:
>
> http://www.criseis.ruhr.de/bilder/wenn_ihr_euch_dann_besser_fuehlt.jpg

Schick! Wild!

m.n. schrieb:
> Was soll das denn? Schön, daß man nicht so doof ist wie die Anderen?

Das lese ich nicht daraus. Ich lese daraus lediglich, dass die 
Interpretation des vagen Begriffs "häufig" eine andere ist als die, ich 
ich in meinem Ursprungs-Post meinte. Ich glaube, den Anfänger-Versuch, 
bei jedem Bild-Update bei einem Display ohne Framebuffer erst einmal den 
Hintergrund zu löschen, haben wir alle einmal gemacht. Wäre das Ergebnis 
gut geworden, wären wir dabei geblieben. Nachdem sich herausgestellt 
hat, dass es keine gute Idee ist, machen wir es jetzt anders.

Also meine Aussage von oben etwas defensiver formuliert: Ich halte die 
Möglichkeit, den Hintergrund schnell einfarbig zu füllen für wichtig 
genug, eine eigene Schreib-Funktion zu rechtfertigen, denn sie 
beeinflusst massgeblich die gefühlte Interaktionsgeschwindigkeit 
("Schwuppdizität") der grafischen Benutzerschnittstelle (GraBSch) beim 
Erstaufbau. Für GraBSchen, bei denen hauptsächlich die gleichen Daten 
mit unterschiedlichen Werten dargestellt werden, ist das natürlich 
weniger relevant.

: Bearbeitet durch User
von m.n. (Gast)


Lesenswert?

Walter T. schrieb:
> Ich glaube, den Anfänger-Versuch,
> bei jedem Bild-Update bei einem Display ohne Framebuffer erst einmal den
> Hintergrund zu löschen, haben wir alle einmal gemacht. Hätte es
> geklappt, wären wir dabei geblieben. Nachdem sich herausgestellt hat,
> dass es keine gute Idee ist, machen wir es jetzt anders.

Und damit gibt es keinen Grund, einem Anfänger dieses Vorgehen mit "bis 
der Arzt kommt" ungefragt vorzuwerfen.

von Philipp K. (philipp_k59)


Lesenswert?

Man muss halt alles selbst machen wenn man viele Wechselnde Bildbereiche 
hat. Die Performance benötigt man eigentlich nur für einen Bilderrahmen 
oder Seitenwechsel.. da kann man aber Effekte generieren das es wie 
gewollt aussieht, zum Beispiel immer im Kreis flitzen und dann in der 
Mitte enden, oder umgekehrt.

Bei 18Mhz fängt es ab einer bestimmten Größe an aufzufallen, ich glaube 
das war irgendwo bei 100*100Pixel solange man vorher nicht noch 
rumrechnen muss.

Welche Library wird denn benutzt?

Ich habe das mal mit dem ili9486 gemacht, das schnellstmögliche mit 
Flash sieht man auf dem Video, also das Updates kaum auffallen. Ab 
stm32F4 hat man vielleicht noch Platz um sogar ein Hintergrundbild und 
Transparenz mit einzubringen, das muss ich aber noch selbst testen, auf 
einem esp32 flitzt das richtig Sorglos.

Beispiel mit Flash-Spi..
https://youtu.be/KhNEtgMYAAE

Habe da Mal ein Brekaout gebastelt, das klappt super ohne Transparenz, 
dafür ist der F103 einfach zu klein. 
https://hackaday.io/project/103344/gallery#cd19b5bfd34ca9a689c9e8de927bc093

von Bernd (Gast)


Lesenswert?

Philipp K. schrieb:
> Beispiel mit Flash-Spi..
> https://youtu.be/KhNEtgMYAAE
Netzfrequenzmessung. Nett.
Wie genau wird der Nulldurchgang ermittelt? Mit Trafo + Komparator oder 
Trickschaltung zur Strombegrenzung + Optokoppler?

Jetzt würde mich noch der grafischem Verlauf über die letzten xxx 
Minuten interessieren.
Hier gibt es dafür ein nettes Codeschnipsel:
https://www.youtube.com/watch?v=YejRbIKe6e0

von Philipp K. (philipp_k59)


Lesenswert?

Bernd schrieb:
> letzten xxx
> Minuten interessieren.

Gehört ja eigentlich nicht hierhin.. Ist mit Trafo direkt.. der versorgt 
nebenbei noch die Platine selber. und die Anzeige selbst ist schon 
mehrfach abgeglichener Live Mittelwert bis es schön Smooth aussah.

Quasi ist das nur TFT Initialisieren, das "Fenster" über die Arduino Lib 
setzen und dann mit DMA den Speicherbereich aus dem Flash Hand gecodet 
hinschaufeln (Das sind ja nur nen paar Zeilen wenn das init des STM32 
stimmt). So direkt mit den Libs hat es nicht geklappt.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

m.n. schrieb:
> Das ist doch praxisfremd. Nach Rückkehr aus einem Untermenü ist der
> Bildschirminhalt unbekannt, und es muß zwangsläufig alles gelöscht und
> neu geschrieben werden.

Neu Schreiben reicht völlig und dann bis zum Fensterende mit Leerzeichen 
auffüllen. Die Länge des neuen Strings läßt sich ja einfach ermitteln.

m.n. schrieb:
> Heizungssteuerung? Ist das ein Ersatz fürs Fernsehkucken?

Das ist das Teil auf dem Heizofen im Keller. Bei jedem Tastendruck 
flackert das ganze Display. Aber wenigstens nicht, wenn sich Zahlen 
ändern. Hersteller weiß ich nicht.

Bei einem 32Bit-Boliden lege ich einen Bildspeicher im RAM an und 
schreibe alle Änderungen dort hinein. Und dann wird der geänderte 
Fensterbereich ins Display kopiert.

von Walter T. (nicolas)


Lesenswert?

Peter D. schrieb:
> Neu Schreiben reicht völlig und dann bis zum Fensterende mit Leerzeichen
> auffüllen. Die Länge des neuen Strings läßt sich ja einfach ermitteln.

Nanu? Warum sollte man ein Grafik-Display ausschließlich wie eine 
Text-Konsole nutzen? Oder ist "Fenster" bei Dir eine Kachel 
(Fenster/Zelle/wie auch immer ein Rechteck jetzt heißt)?

: Bearbeitet durch User
von Felix N. (felix_n888)


Angehängte Dateien:

Lesenswert?

Philipp K. schrieb:
> Ja, aber das wichtige ist ja das es ohne rechenticks passiert.. also
> quasi ein separater Datenschaufler.

Hallo, hatte diesen Beitrag im Forum irgendwie ganz vergessen upps ...

Ja ich weiß bzgl. des DMAs hätte ich auch nochmal eine Frage bin mir 
nicht sicher ob das so funktioniert wie ich mir das Vorstelle. Da die 
STM32 ja deutlich mehr RAM haben als die AVRs zB. F103C8T6 20kB und beim 
F446RE schon 128kBytes möchte ich gerne so Art "Grafiken" im RAM 
hinterlegen um die dann auf den Display wiederzugeben, zB 
Temperaturfühlerzeichen. Bei den AVRs ist das immer am SRAM gescheitert 
einmal hatte ich am ATMega2506 ein 56kBytes externes SRAM drangeschraubt 
damit ging das ganze dann gut mal abgesehen von der Geschwindigkeit. 
Aber egal zur Frage: Ich kann den DMA ja so konfigurieren das die 
Quelladresse(Source) auf ein Datenarray zeigt mit den Grafikinhalt und 
die Zieladresse(Destination) auf das GPIOA->ODR Register zeigt. Dann 
8-Bit Datenmodus etc.. und der DMA würde dann doch die Daten vom Array 
auf den GPIOA Port schreiben. Nur kann man den DMA auch sagen das er 
zwischen jeden Datenpaket kurz noch was anderes machen soll sprich 
WR_ACTIVE; WR_IDLE um auch die Daten auf dem Display dazustellen. Oder 
ist der DMA dafür nicht konzipiert?

Arduinoquäler schrieb:
>> Ein Ver-odern der Bits mit den Registern ist übrigens nicht
>> erforderlich. Das kann man erkennen wenn man die Funtionen
>> der SPL (z.B.) anschaut. Es gibt auch ein explizites Reset-
>> Register für die Port Bits .... spart alles ein paar Zyklen.

Ah danke. Ich habe um die Pins wieder auf LOW zu setzten von BSRR |= (x 
+16) auf BRR |= x; geändert. Glaube hat aber nicht wirklich was geändert 
ein kompletter Löschvorgang dauert immer noch gute 128ms, wie vorher 
auch.

Arduinoquäler schrieb:
> Alle Klarheiten beseitigt?

Ja danke für die Erklärung. Ich habe es umgesetzt jetzt weiß ich auch 
warum nur die Hälfte vom Bild gelöscht wurde das zweite WR_STROBE fehlte 
für das HIGH Byte.

Ich habe die Funktion "ili9341_clearScreenFast(bool white)" genannt. 
Damit kann man nur schwarz und weiß löschen im Gegensatz zur 
"ili9341_clearScreen" Funktion ist diese 18ms schneller also dauert ein 
Löschvorgang 110ms statt 128ms. Optisch konnte ich so gut wie kein 
Unterschied feststellen.

Allerdings scheinen Interrupts da auch schon sehr gewaltig sichtbar zu 
sein im Display. Ich habe den Timer2 als Overflow Interrupt Event 
aktiviert. So das er jede 1ms ein 32 Bit Integer hochzählt("millis") 
damit mache ich die Zeitmessung. Wenn ich das ganze runterschraube so 
das er jede Mikrosekunde auslöst und dann ein 32 Bit Integer namens 
"micros" hochzählt und wenn eine lokale Variable 1000 erreicht "millis" 
um eins hochzählt. Kann man die Interrupt Unterbrechungen im Display 
sehen. Es sieht so aus als würde es kurz stocken. Evtl. müsste ich den 
NVIC während am Display gearbeitet wird deaktivieren und dann wieder 
aktivieren, jedoch hätte das auch seine Nachteile dann mal sehen.

Walter T. schrieb:
> Genau. Und das auf Flex-Leiter. Ich habe es für mich als "unpraktikabel"
> abgestempelt.

Hätte ich schon gemacht wenn ich das nur gesehen hätte wo ich dran 
müsste :) Aber wahrscheinlich wäre es mir ein Versuch dennoch wert 
gewesen ...

olaf schrieb:
> http://www.criseis.ruhr.de/bilder/wenn_ihr_euch_dann_besser_fuehlt.jpg

Nicht schlecht.

m.n. schrieb:
> Entweder man braucht den µC, dann ist derzeit die Verfügbarkeit das
> wichtigste Kriterium, oder man braucht ihn nicht. Bei einem Einzelstück
> ist der Preis nicht so entscheidend.

Natürlich ist der Einzelpreis für mich als Hobbyelektroniker nicht so 
entscheidend ich nehme die Dinger ja nicht in 1000x Stück oder so ab. 
Nichts desto trotz möchte ich auch nicht unbedingt eine Nucleo Platine 
opfern nur um an zwei Chips anzukommen die nicht mal die Hälfte der 
Platine kosten. Da nehme ich dann doch die ganze Nucleo Platine und 
lasse sie so und integriere sie.

Wobei ich bei reichelt, wo ich hauptsächlich bestelle, gesehen habe das 
es dort durchaus noch STM32 Controller gibt welche auch Lieferbar sind 
wie zB. der STM32L476VGT6. 1MB Flash, 80MHz und 128kBytes an RAM.

Philipp K. schrieb:
> Welche Library wird denn benutzt?

Ich habe meine Treiberlib für den ILI9486 und den GFXlib in einer meiner 
Beiträge weiter oben Angehängt. Die GFXlib ähnelt der Adafruit GFX 
Library.

Peter D. schrieb:
> Neu Schreiben reicht völlig und dann bis zum Fensterende mit Leerzeichen
> auffüllen. Die Länge des neuen Strings läßt sich ja einfach ermitteln.

Geht aber auch nur, würde ich jetzt sagen, wenn man das Display als art 
"Konsole" nutzt.

Ich habe mal ein Bild von dem Projekt auf dem ATMega328P(Stand 11/2020) 
angehängt. Dort sieht man was es am Ende in etwa machen soll wobei ich 
dafür jetzt noch mehr Ideen habe als damals. Die maximale 
Aktualisierungsgeschwindigkeit für das Display lag irgendwo bei 
800-1000ms schneller gings nicht weil das Display einfach solange 
braucht. Dort ist es zB. so das wenn der Text von den Stellen gleich 
bleibt zB. "330W" und dann kommt "250W" dann wird das einfach direkt als 
String überschrieben und es flackert nicht. Wenn das aber von "330W" auf 
"80W" wechselt, generiere ich erst dahinter mit fillRect ein schwarzen 
Kasten der die 330W vollständig verdeckt und schreibe die 80W dann neu 
weil die Position auch wieder angepasst werden muss damit es wieder 
mittig ist.

Würde ich das mit dem fillRect nicht machen würde irgendwas von der 
alten Zahl stehen bleiben.

Peter D. schrieb:
> Bei einem 32Bit-Boliden lege ich einen Bildspeicher im RAM an und
> schreibe alle Änderungen dort hinein. Und dann wird der geänderte
> Fensterbereich ins Display kopiert.

Wenn ich in diesem Beispiel ein Display mit 480x320 und jeder Pixel ein 
16 Bit Farbwert haben kann müsste der Bildspeicher im RAM doch 2.457.600 
Bytes(~2,4MB) groß sein oder nicht (480pixel  320pixel  16bit)? Haben 
MCUs überhaupt solch riese SRAM Speicher?

Mfg

von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> ein Display mit 480x320 und jeder Pixel ein
> 16 Bit Farbwert haben kann müsste der Bildspeicher im RAM doch 2.457.600
> Bytes(~2,4MB) groß sein oder nicht (480pixel  320pixel  16bit)?

Ich behaupte mal dass meine Rechnung richtig war und ist ...

Arduinoquäler schrieb:
> Ja gut .... 480x320 Pixel á 16 Bit ergibt gut 300kByte.

von Felix N. (felix_n888)


Lesenswert?

Arduinoquäler schrieb:
> Ich behaupte mal dass meine Rechnung richtig war und ist ...

Jop, hab mich vertan. 16 bit sind ja 2 Bytes also mal 2 statt mal 16. 
Upps. dann passt das auch mit den 300kBytes. Trotzdem noch viel zu viel 
für die meisten MCUs

Mfg

von Johannes S. (Gast)


Lesenswert?

Gibt es schon, ist aber nicht unbedingt nötig. Lvgl hatte ich ja schon 
mehrfach erwähnt, da reicht ein Framebuffer von mindestens 10 Zeilen. 
Und solche runden Instrumente gibts da auch.

von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> Ah danke. Ich habe um die Pins wieder auf LOW zu setzten von BSRR |= (x
> +16) auf BRR |= x; geändert.

Dann hast du es immer noch nicht verstanden. Es war das
Ver-odern überflüssig ....

Bei mir ist ein Makro z.B. so definiert:
1
#define   WR_CYCLE    CTRL_PORT->BRR  = LCD_WR_Pin; \
2
                      CTRL_PORT->BSRR = LCD_WR_Pin;

von Felix N. (felix_n888)


Lesenswert?

Arduinoquäler schrieb:
> Es war das
> Ver-odern überflüssig ....

Okay. Ich wusste nicht das man das Bitschiften(x<<n) Ver-odern nennt.

Arduinoquäler schrieb:
> Bei mir ist ein Makro z.B. so definiert:

Ok. Nachdem ich mein WR_PIN von 11 auf (1<<11) geändert habe 
funktionierte der neue Makro auch. Das ganze hat massiv Zeit gespart von 
128ms auf 68ms bei der normalen Clear Funktionen. Und bei der 
"fastClear" von 110ms auf 52ms. Wenn ich das bei den anderen 
Steuerleitungen(CS und DC) komme ich auf 66/50ms.

Ich weiß jetzt jedoch nicht was das Steckbrett und die 
Steckbrettkabel(~17cm) für ein Einfluss darauf noch haben. Zumal auch 
nix abgeschirmt ist oder so am Kabel.

Mfg

von Arduinoquäler (Gast)


Lesenswert?

Felix N. schrieb:
> Okay. Ich wusste nicht das man das Bitschiften(x<<n) Ver-odern nennt.

Nein.

Ver-odern nennt man das wenn man |= anwendet. Mit Shiften
hat das überhaupt nichts zu tun.

von Otis W. (Gast)


Lesenswert?

Felix N. schrieb:
> Nur kann man den DMA auch sagen das er
> zwischen jeden Datenpaket kurz noch was anderes machen soll sprich
> WR_ACTIVE; WR_IDLE um auch die Daten auf dem Display dazustellen. Oder
> ist der DMA dafür nicht konzipiert?

Nein. Dafür bräuchte man den FSMC, der automatisch Schreibimpulse 
generiert.

Felix N. schrieb:
> Nichts desto trotz möchte ich auch nicht unbedingt eine Nucleo Platine
> opfern nur um an zwei Chips anzukommen die nicht mal die Hälfte der
> Platine kosten. Da nehme ich dann doch die ganze Nucleo Platine und
> lasse sie so und integriere sie.

Würde ich für Einzelstücke auch komplett verwenden, zumal die Bestückung 
schon fertig ist.

Felix N. schrieb:
> dann passt das auch mit den 300kBytes. Trotzdem noch viel zu viel
> für die meisten MCUs

Wenn Du schon bei STM32 bist, dann böte sich ein H750 mit 1 MB RAM an. 
Vor einiger Zeit waren die noch für rund 5 € zu bekommen. Zur Zeit sagen 
aber alle Preise: kauf mich nicht!
Oder man nimmt eben ein fertiges Board.

Langer Rede wenig Sinn: Du wirst sicherlich bei Deiner jetzigen Lösung 
bleiben, ob sie nun schnell oder langsam arbeitet und weil die 
Änderungen viel zu arbeitsintensiv wären ;-)

Beitrag #6796575 wurde vom Autor gelöscht.
von Walter T. (nicolas)


Lesenswert?

Walter T. schrieb:

> Es erweitert nicht meinen Horizont, aber es ist gut zu wissen, dass es
> diese Module endlich auch in preisgünstig gibt.

Ich habe mal eines der Module ausprobiert. Die Raspberry-Displays nutzen 
gar nicht die SPI-Fähigkeit des ILI9486, sondern haben zwei 
74HC4094-Schieberegister an Board und nutzen das 8080-Interface im 
16-Bit-Modus. Um einen Tristate-Treiber zu sparen, können Daten nur 
geschrieben und nicht gelesen werden. Für einen µC ohne Platz für einen 
Framebuffer sind die Dinger damit nahezu unbrauchbar.

Mit den oben beschriebenen Wartezeiten dürften sie auch nicht schneller 
als die 8-Bit-8080-Absteuerung sein. Nach dem obigen Frust habe ich 
keine Lust auf Benchmarks.

Den Grund für diese merkwürdige Konstruktion verstehe ich nicht. Die 
ILI9486 sind ja SPI-fähig und können sogar 3-Leiter-SPI, d.h. es gäbe 
keine Kollision mit dem MISO des Touch-Sensors. Bidirektionale 
Levelshifter dürften ja auch nicht wirklich teurer als diese merkwürdige 
Konstruktion sein.

Schade eigentlich. Es hätte so schön sein können.

von Bernd (Gast)


Lesenswert?

Walter T. schrieb:
> Schade eigentlich. Es hätte so schön sein können.
Das habe ich bei einigen Lösungen aus Fernost auch schon erlebt.

Wahrscheinlich gibt es dazu auch philosophische Betrachtungen, die 
erörtern, warum sich nicht die technische bessere Lösung, sondern nur 
das Mittelmaß durchsetzt...

von Walter T. (nicolas)


Lesenswert?

Nachtrag: Nachdem der Anfangsfrust verraucht ist, habe ich doch mal mit 
dem "SPI"-Raspberry-TFT etwas genauer hingeschaut:

Wie schon oben geschrieben wird nicht die SPI-Fähigkeit des ILI9486 
genutzt, sondern es sind Schieberegister auf dem Modul, und der 
Display-IC wird per 16-Bit-8080-Interface angesprochen. Das WR-Signal 
("strobe") wird dabei mit einem Zähler aus dem SPI-Clock erzeugt oder 
kann wahlweise mit einem Loslassen des Chip-Select-Signals erzwungen 
werden.

Die maximale Taktrate, die ich erfolgreich testen konnte, waren etwas 
mehr als 20 MHz. Ich habe aber nur jeweils in 2er-Teilungsfaktoren 
getestet, weil der SPI-Takt bei üblichen Kachelgrößen ohnehin die 
Schreibdauer kaum beeinflusst. (Bei mir sind die Kacheln üblicherweise 
32x32 oder 40x40 Pixel.) Wartezeiten sind da wichtiger. Wird die 
Wartezeit beim MemoryWriteContinue nicht eingehalten, ergeben sich 
falschfarbige Einzelpixel.

Einmal das Display komplett einfarbig füllen geht bei mir in knapp 150 
Millisekunden (untere Grenze). Das ließe sich ein wenig optimieren, 
indem man das WR-Signal am Schieberegister vorbei von Hand erzeugt, aber 
nicht viel. Und bei den üblichen Bitmaps hilft das auch nichts.

Einmal das Display komplett jeden Pixel einzeln mit einem Zufallsmuster 
füllen kostet ca. 500 Millisekunden (obere Grenze).

Eine gekachelte Anzeige fühlt sich doch ganz gut an. Aber dass man den 
Speicher nicht mehr auslesen kann, nervt natürlich. Einen Hintergrund 
einfach "ausgrauen", ohne das Bild komplett neu aufbauen zu müssen, kann 
man vergessen. (Das ist mein häufigster Anwendungsfall für 
Overlay-Effekte.) Als quasi Drop-In-Ersatz für die bekannten 
ILI9341-Module mit SPI-Anschluß ist es damit nicht geeignet.

Also: "Not great, not terrible", wie es so schön heißt.

: Bearbeitet durch User
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.