hallo! was habt ihr für erfahrung mit rechenzeit von 8-bitter in verbindung mit grafik-lcds? das ding ist: ich hab an meinem atmega328 ein lcd mit 122x32 pixel drangeklatscht. es gibt ein menü. in den einzelnen menüs werden bis jetzt nur grafic-primitives like lines, points und rechtecke gezeichnet. außerdem werden asci-zeichen dargestellt. für einen screen braucht er (20MHz takt) so um die 35ms. d.h. ca. 120 befehle pro pixel, bzw. 700000 befehle pro screen. ist das normal? wie lange dauert das bei euren projekten? kann das noch spürbar verbessert werden (ich hab das ganze projekt selbst programmiert, deswegen wollte ich mal wissen wies im groben so aussieht mit der effizienz).
M. M. schrieb: > für einen screen braucht er (20MHz takt) so um die 35ms. Und? Ist das ein Problem? Welche Aufgabe hat das Display? Soll es für eine Benutzerschnittstelle da sein, d.h. auf Benutzereingaben reagieren und irgendwelche Werte anzeigen? Welche Aktualisierungsrate meinst Du denn, in so einem Fall zu benötigen?
Rufus Τ. F. schrieb: > M. M. schrieb: >> für einen screen braucht er (20MHz takt) so um die 35ms. > > Und? Ist das ein Problem? > > Welche Aufgabe hat das Display? Soll es für eine Benutzerschnittstelle > da sein, d.h. auf Benutzereingaben reagieren und irgendwelche Werte > anzeigen? > > Welche Aktualisierungsrate meinst Du denn, in so einem Fall zu > benötigen? Nachdem ich die Tastatur jetzt repariert habe: Die Aktualisierungsrate reicht ja mit 10 Bildern/Sekunde dicke bei einem LCD. Mich interessiert einfach nur die Effizienz meines Codes.
Kommt darauf an, wie das Display arbeitet. Ich habe aus einem DOGXL160 quasi ein Text-Display mit 20x13 Zeichen gemacht. https://www.mikrocontroller.net/attachment/212667/DSC00245.JPG Das ist eine Weile her aber ich meine mich zu erinnern, dass aleine 28 SPI Übertragungen notwendig waren um ein einzelnes Zeichen zu malen. Das kam daher das für jeden Pixel zwei Bit zu senden waren. Dazu kam noch die Daten für jedes Zeichen aus dem Zeichensatz im FLASH auszurechnen.
M. M. schrieb: > Mich interessiert einfach nur die Effizienz meines Codes. Wie kann das jemand beurteilen wenn du ihn nicht angehängt hast?
M. M. schrieb: > Mich interessiert einfach nur die Effizienz meines Codes. Das Pinseln einzelner Pixel ist langsamer als das Übertragen kompletter Bytes. Das Berücksichtigen des bereits vorhandenen Bildschirminhalts ist langsamer als das Überschreiben. Sofern Dein µC ausreichend Speicher hat, kann es sogar effizienter sein, ein komplettes Abbild des Bildschirminhalts im Speicher vorzuhalten und den nach Änderungen per DMA auf das Display auszugeben. Dein Display ist 122x32 Pixel = 488 Byte groß und Dein Atmega 328 hat 2 kByte RAM (aber anscheinend kein DMA). Je nachdem, wie das Display anzusteuern ist, kann es effektiver sein, nach jeder Änderung des Inhaltes komplette 488 Bytes zu übertragen (wenn der Displaycontroller ein sequentielles Beschreiben mit automatischem Inkrementieren des Adressregisters unterstützt). Auch ohne DMA sollte das in einer einfachen Schleife recht flott gehen. Was für ein Display (mit was für einem Controller) verwendest Du und wie ist das angeschlossen?
> ein komplettes Abbild des Bildschirminhalts im Speicher vorzuhalten
Volle Zustimmung, es wird eine Funktion benötigt, welche den Buffer ins
Display schiebt. Falls sich die Display-Routinen die niedrigste und die
höchste veränderte Adresse seit dem letzten Copy-Befehl merken, kann man
unter Umständen die Ausführung von Curser/Menüs nochmal deutlich
beschleunigen.
Wenn man kein DMA hat hilft auch folgender Programmaufbau. Das Hauptprogramm besteht aus einer kurzen Schleife, die nichts anderes tut als so schnell wie möglich den Bildinhalt zyklisch vom internen RAM zum Display zu übertragen. Alle anderen Funktionen und Berechnungen werden komplett in einem Timer-Interrupt abgearbeitet. Vorteil ist, die Bildausgabe behindert niemals die Berechnungsarbeit oder das Tastenhandling. Sie wird nur langsamer wenn der Controller viel rechnen muss.
Rufus Τ. F. schrieb: > Sofern Dein µC ausreichend Speicher hat, kann es sogar effizienter sein, > ein komplettes Abbild des Bildschirminhalts im Speicher vorzuhalten und > den nach Änderungen per DMA auf das Display auszugeben. > Dein Display ist 122x32 Pixel = 488 Byte groß und Dein Atmega 328 hat 2 > kByte RAM (aber anscheinend kein DMA). > > Je nachdem, wie das Display anzusteuern ist, kann es effektiver sein, > nach jeder Änderung des Inhaltes komplette 488 Bytes zu übertragen (wenn > der Displaycontroller ein sequentielles Beschreiben mit automatischem > Inkrementieren des Adressregisters unterstützt). > > Auch ohne DMA sollte das in einer einfachen Schleife recht flott gehen. > > Was für ein Display (mit was für einem Controller) verwendest Du und wie > ist das angeschlossen? Also, die Daten kommen per 8 Bit breitem Interface in den LCD-Controller. Das Display ist in 4 horizontale "Pages" aufgeteilt. Wenn ich nun eine Page übertragen möchte, so addressiere ich zuerst die Page, leg dann dein Byte an und gebe einen Bestätigungsflanke aufs clk-Signal. Der Controller inkrementiert dann die X-Koordinate. Die übertragung geht so sehr schnell. Ich hab in meinem Controller den Displayinhalt in einem Array im SRAM gespeichert. Dann hab ich außerdem noch ein Pointer-Array, in dem die jeweiligen Funktionen adressiert sind, die ein bestimmtes Fenster im Display-Array erzeugen. Nachdem eine solche Funktion aufgerufen wurde, wird das gesamte Display-Array ausgegeben. Was mich aber hauptsächlich interessiert ist die Berechnungszeit des Inhalts. Also die Effizienz meiner printf-, line- oder rectangularfunktionen und deren zusammenspiel im ganzen. Ich hätte halt gerne gewusst ob ich um 10er-Potenzen zu langsam bin oder nicht. So sieht z.B. ein Bildschirminhalt bei mir aus:
Auch bei Zugriffen auf Dein Bildschirmspeicherabbild sind Manipulationen einzelner Bits ineffizienter als auf Bytegrenzen ausgerichtete Zugriffe. Wenn Du beispielsweise einen 8x8-Zeichensatz verwendest, ist das Ausgeben eines einzelnen Zeichens mit 8 Schreibzugriffen erledigt, sofern die Zielkoordinaten ins Byteraster passen. Wird das Zeichen nur um ein Pixel versetzt ausgegeben, musst Du aufwendige Bitmanipulationen betreiben - zwei Byte des Bildschirmspeicherabbildes lesen, mit dem zurechtgeschobenen Byte aus der Zeichentabelle verknüpfen und wieder in das Bildschirmspeicherabbild zurückschreiben. Klar: Proportionalschrift sieht natürlich schicker aus, aber sie ist prinzipbedingt langsamer. Und jede Schriftgröße, die nicht ein vielfaches von 8 beträgt (in der Achse, in der die einzelnen Bits eines Bytes angeordnet sind), ist entsprechend auch langsam.
Also, die Berechnung des Bildinhaltes dauert 10ms. Die Übertragung ans LCD nur 15us.
Ingo schrieb: > Du hast nicht wirklich n Hex hochgeladen... Ja, mit dem Array-Inhalt. Das Format weiß ich jetzt auch nicht sicher, aber ich bin selbst drauf gekommen, dass es nicht ganz Zielführend ist...
Hi
>Hmm, des .hex-file is nich so der bringer...
Das Bild aber auch nicht.
MfG Spess
M. M. schrieb: > was habt ihr für erfahrung mit rechenzeit von 8-bitter in verbindung mit > grafik-lcds? das ding ist: ich hab an meinem atmega328 ein lcd mit > 122x32 pixel drangeklatscht. Klatsch! Ja, 8 Bitter und Grafik-Displays sind zumeist Antagonisten. Bei kleinen monochromen Displays geht es zwar, aber man sollte in jedem Fall überlegen, welche Strategie man fährt: Strategie 1 (grottenschlecht) besteht darin, jedes Pixel und jeden Furz direkt über den Controller des Displays zu fahren, also Byte mit Pixel auslesen, modifizieren, zurückschreiben. Sowas dauert ewig und ist nur was für Leute, die viel zu wenig RAM im System haben. Ist typisch für zu kleine 8 Bitter. Strategie 2 (deutlich besser) besteht darin, im RAM einen Bildspeicher zu haben, auf den sämtliche Zeichenoperationen arbeiten. Jede Zeichenoperation setzt eine boolean Variable, die von Zeit zu Zeit abgefragt wird (so alle 10 ms oder so) und wenn diese gesetzt ist, wird der gesamte Bildspeicher en bloc in das Display geschaufelt und die Variable zurückgesetzt. Wie konkret tun? Lernbetty lesen. (tibetanische Gebetsmühle...) W.S.
Hi Strategie 3 Im Rom passende 'Bitmaps' hinterlegen Beitrag "Re: Zeigt her Eure Kunstwerke !" Da wird außer auf der Karte kein einzelnes Bit angefaßt. MfG Spess
M. M. schrieb: > für einen screen > braucht er (20MHz takt) so um die 35ms. d.h. ca. 120 befehle pro pixel, > bzw. 700000 befehle pro screen. Ja, ist normal. Selbst schwarz/weiss Graphik ist unter 8 bit immer etwas sluggish, wenn man nicht hochoptimiert in Assembler programmiert (Apple ][/C64 Sprites etc.)
Hi M. M., trotz geputzter Brille - ich finde nicht, welches GLCD Du verwendest (Controller Type? und wirklich 122 Pixel breit o. doch 128?); und auch nicht, ob Du eine der Bibliotheken zur Ansteuerung des GLCDs verwendest oder ob Du Dir das auch selber erarbeitet hast. Nun ich hatte ein KS0108 kompatibles Display, und war mit dem Zeitbedarf zur Ansteuerung (fertige Bibliothek) auch unzufrieden. Also habe ich auch erst einen GLCD Buffer implementiert..Der Vorteil dabei ist, dass der Bufferinhalt auch über den UART an ein Terminal ausgegeben werden kann http://www.roboter.cc/index.php?option=com_kunena&view=topic&catid=13&id=2411&Itemid=20#3016. Aber wie jetzt den Buffer an das GLCD ausgeben, ohne für jedes Pixel eine Funktion aufzurufen und nur die geänderten Daten zu berücksichtigen?! Also Datenblatt her und selber probiert.. Jetzt brauche ich keinen RAM Buffer mehr, jedenfalls nicht mehr für das gesamte Display. Und 35ms sind normal, wenn man es so macht, wie all die anderen (phantasielosen und abgeschriebenen) Bibliotheken: Adresse schreiben -> Warten -> Daten ausgeben -> Warten -> Adresse schreiben.. usw. Aber so war das wohl nicht im Sinne der GLCD Controller Entwickler. Wie gibst Du ein ASCII Zeichen aus? Ich kenne auch nur eine GLCD Lib, die das Zeichnen z.Bsp. im XOR Mode unterstützt, alle anderen können nur Pixel auf 1 oder auf 0 setzen.
Im Prinzip kann man es doch machen, wie man will. Ob man den Bildspeicher für XOR zurückliest oder nicht, hängt letztlich von der Zugriffzeit darauf ab. Wenn ein read-modify-write im 1-3 µs-Bereich liegt, ist das schnell genug.
BirgerT schrieb: > Hi M. M., > > trotz geputzter Brille - ich finde nicht, welches GLCD Du verwendest > (Controller Type? und wirklich 122 Pixel breit o. doch 128?); und auch > nicht, ob Du eine der Bibliotheken zur Ansteuerung des GLCDs verwendest > oder ob Du Dir das auch selber erarbeitet hast. LCD: http://www.produktinfo.conrad.com/datenblaetter/175000-199999/187399-da-01-en-Grafik_122x32_LDC_Modul.pdf Controller: http://www.lcd-module.de/fileadmin/eng/pdf/zubehoer/ax6120.pdf > Nun ich hatte ein KS0108 kompatibles Display, und war mit dem Zeitbedarf > zur Ansteuerung (fertige Bibliothek) auch unzufrieden. > Also habe ich auch erst einen GLCD Buffer implementiert..Der Vorteil > dabei ist, dass der Bufferinhalt auch über den UART an ein Terminal > ausgegeben werden kann > http://www.roboter.cc/index.php?option=com_kunena&view=topic&catid=13&id=2411&Itemid=20#3016. Also wie oben schon gesagt, ich habe alles selber programmiert. Mit internem Buffer im SRAM und komplette Übertragung, nachdem ein Bild komplett gezeichnet wurde. > Wie gibst Du ein ASCII Zeichen aus? Ich hab im FLASH eine Zeichentabelle für Asci-Zeichen 32-126 für zwei Schriftgrößen. Hab ich mit Excel in verbindung mit VBA erstellt :-D In meinem Programm hab ich eine Funktion printf(), der übergebe ich die Anfangskoordinaten, Schriftgröße und den Pointer auf einen String. Diese rechnet dann für jedes Zeichen die Koordinaten aus und gibt diese weiter an eine Funktion printchar(). Diese Springt dann zur richtigen Position der Zeichentabelle und berechnet jede Koordinate des zu zeichnenden Pixels des Zeichens extra. Das wird dann an die Funktion setpoint() weitergegeben. Diese setzt einfach das betreffende Pixel im SRAM-Display-Buffer. Ausgegeben ans Display wird das ganze erst, nachdem ein komplettes Bild fertig ist. Eine Verbesserung, die weiter oben schon wer genannt hat wäre, in der Funktion printchar() nicht einzelne Pixel zu setzen, sondern komplette Bytes zu setzen. Halt vorher entsprechend shiften. Das muss ich mir noch genauer überlegen obs mir der Aufwand Wert ist. Was ich auch schon gemacht habe: Ich hatte das gleiche Display und nur einen Attiny2313. Dumm wie ich damals war, ist mir beim Bestellen gar nicht aufgefallen, das der nicht genug SRAM für einen Buffer hat. Es war auf der Platine auch nicht vorgesehen das man den Displayinhalt auslesen konnte. Letztendlich hab ich mit gefühlten hundert schmutzigen Tricks doch geschafft das ganze ohne Buffer umzusetzen. Das ganze hab ich natürlich auch noch in Assembler schreiben müssen :-D Der Flash wurde unterm programmieren immer voller. Zum Schluss war ich dann bei 98%. Mann hab ich damals geschwitzt. Auf jedenfall ist das Erzeugnis ein absolut unwartbarer Spagetticode. Sowas werde ich nie wieder machen!!! Ein hoch auf C und genug RAM!!!
M. M. schrieb: > In meinem Programm hab ich eine Funktion printf(), benutzt Du die printf Funktion aus C (sprintf())? Das ist zwar komfortabel aber Speicherhungrig und langsam.. > Ausgegeben ans Display wird das ganze erst, nachdem ein komplettes Bild > fertig ist. OK - und wie, immer kompletter Buffer am Stück? Du hast das im Datenblatt auch mit dem Adressen Auto inkrement gelesen? Du kannst also die Ausgabeadresse immer an den Pageanfang (0) stellen, und dann eine Page komplett mit Daten schreiben, ohne für jedes Byte die Adresse neu zu setzen.. > Eine Verbesserung, die weiter oben schon wer genannt hat wäre, in der > Funktion printchar() nicht einzelne Pixel zu setzen, sondern komplette > Bytes zu setzen. Halt vorher entsprechend shiften. Das muss ich mir noch > genauer überlegen obs mir der Aufwand Wert ist. Ist es - bestimmt.. Jetzt kommt es darauf an, wie der Font und der Buffer aufgebaut sind. Idealerweise sind die Zeichenbits horizontal angeordnet, d.h. ein Byte entspricht einer Pixelspalte des LCDs. Je nach dem, wie "hoch" der Font ist, das Font Byte/Word in eine doppelt so "hohe" Variable laden, und dann y-Offset mal shiften und Byte für Byte auf der richtigen Page ausgeben. Was auch Speed bringt, erst das Enable-Bit setzen, dann Daten holen und auf den Controller schreiben, dann Enable-Bit löschen. Geht bei mir mit 16MHz und KS0108 kompatiblen Controller, der nur 450ns für das Enablebit braucht.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.