Tag. Ich brauche etwas Anregung. Ich habe mir eine Dot-matrix anzeige gebaut, wo ich mittlerweile auch schon animationen (Bilder liegen im Flash) mit ablaufen lassen kann. Nun dachte ich mir aber, dass ich einen reinen Text übergebe, und das Display selbstständig scrollt. Ok. Etwas gegrübelt, da ist das im Anhang bei rausgekommen. Stellen wir uns das als RAM vor, in dem ein fertiger Text steht Die ersten 4 Bytes (die "x"e sind immer Bits) sind meine 32 Spalten, die ersten 16 Reihen sind meine Reihen. Also ist nur der erste 4*16 Teil auf dem Display sichtbar. Jetzt habe ich mir gedacht, schiebe ich einfach mit einem festen Takt immer (ROL beim AVR) eins nach links und lasse links ein carry rausfallen und schiebe es rechts wieder rein. Das ganze müsste sich also endlos im Kreis schieben. Nun ist das Problem, dass wenn ich den ganzen Speicher (4 Vollbilder a 32 Spalten macht 128 Spalten. Es wären also 128/6=21 Zeichen mit 6bit Breite möglich) schieben möchte, dass ích 16*16 Bytes nach links schieben muss. Blöderweise dauert das RAM->Register und Register->RAM beim AVR jeweils 2 Takte, sodass ich MINDESTENS auf 5 Takte pro Schiebebefehl komme. Macht schon 1280 Befehle, das ist natürlich nicht tragbar. Also was tun? Hat jemand von euch schonmal ein Lauflicht in Assembler realisiert? Eventuell kann man hier was mit Pointerarithmetik machen, allerdings sollte man beachten, dass ich die Schrift direkt hintereinander gescrollt haben will. Also nicht, dass wenn die Schrift rausgeschoben ist, erst noch ein ganzer leerer Bildschirm kommt.
Wieso muss das denn so schnell sein? Wenn du 1280 Befehle fürs Schieben brauchst, dauert das bei (z.B.) 4 MHz nur 0.32 ms. Also wenn das nicht schnell genug ist. MFG Kai
hallo, ich habe sowas schon gemacht. in der software lauft ein character-generator welcher den text in ein ram image der anzeige wandelt dann shifte ich einfach alle 200ms das ganze um eine spalte versetzt. das zeitaufwendigste von allem war der zeichensatz.
Ich gehe mal davon aus, dass dein Text länger ist, als deine Anzeige. Sonst macht scrollen ja keinen sinn. Ansonsten gehts eigentlich auch was ich mir gedacht hab. Wenn du konsequent das ganze Display scrollen willst, dann sollte es so gehen: Du verschiebst einfach den bereich in dem deine Daten abgelesen werden. Statt bei Adresse 0x0000 fängst du nach ein paar Durchläufen halt bei 0x0001 das auslesen an. Irgendwo muss stehen, wo die letzte Adresse ist, in der Information steht. Wenn du bei der angekommen bist, fängst du wieder vorne an. Aber nicht bei 0x0000, sondern da, wo du das letzte mal angefangen hast bzw. eins weiter, wenn sich das bild gerade schieben soll. Wenn dein Startpunkt hinten angekommen ist, dann springt er natürlich sofort wieder auf 0x0000. Wenn du die Daten wie ein Bild am Stück hast gehst natürlich am einfachsten, aber auch wenn du nur einen Schriftsatz hinterlegt hast sollte es gehn. Muss man halt noch bisschen drumrum proggen... Sebastian
Den Character Generator bastel ich schon.. Das ist nicht das Problem. Aber ich hab hier noch einen Ansatz. Ursprungssituation wie oben, String liegt schon fertig in Bitmap codiert im Speicher (nach obiger Excel Tabelle). Jetzt leg ich den Pointer auf 0 und gebe das Bild ein paar mal aus. Und wie schon Sebastian sagte, erhöhe ich nach ein paar Durchläufen diesen Zeiger und gebe alles erst ab Spalte 1 aus. ABER: Ich muss, nachdem ich bei Spalte F angekommen bin (Erst 15 Spalten ausgegeben bis jetzt), Spalte 0 noch hinten dran hängen.. Anschließend den Pointer wieder erhöhen, und das Bild von 2 bis F ausgeben und 0-1 wieder dranhängen. Mal schauen ob ich das mit reiner Addition/Subtraktion so gebacken kriege. PS: Ja, dachte das so, dass der String länger ist, als das Display breit. Aber: Es soll auch gehen, wenn der String kleiner ist. Wenn Linksbündig nur 3 Zeichen im RAM stehen, dann ist der Rest ja eh auf 0. Also die mindest-Scroll Menge wäre ja dann ein Screen...
Die Frage ist was bekommst du schneller programmiert: a.) eine Font-zeichen-routine die auch mit einem X Offset die Zeichen darstellen kann b.) die Rotation eines ziemlich großen Display-Buffers im SRAM Angenommen du willst auf einem 16 Zeichen Display einen Text mit 256 Zeichen scrollen lassen, so wäre das Display RAM 16 mal größer als notwendig. Dieses muß bei Methode b.) immer vollständig Pixelweise rotiert werden. Oder aber eine bessere Font-zeichen-routine die mit einem Pixelweisen X,Y-Offset arbeiten kann. Dieser Offset kann negativ sein. Der Display RAM ist nicht mehr notwendig da du nun die Texte direkt an das Display senden kannst. Als erstes wird der Berech im Text berechnet der garantiert auf dem Display sichtbar sein muß. Also zb. bei X Offset von 24 Pixel würde dies in einem Text zb. das 5. Zeichen halb darstellen. Also muß ab dem 5. Textzeichen gezeichnet werden. Dein Zeichengernator zeichnet nun die Zeichen Spaltenweise und inkrementiert den X-Offset. Ist X-Offset >= 0 so wird diese Spalte an das Display gesendet, und das dann solang bis X-Offset >= Display Breite ist. Dh. bei dieser Methode verlagerst du die Intelligenz des "Rotierens" in die Fontzeichen Routine. Diese wird im schölechtesten Falle komplett 1 Display an Pixel setzen müssen und enthält ein bischen mehr Overhead bei der Dekodierung der Texte. Deine Bitmap Lösung muß immer mindestens 1 Display voll Pixel beackern, aber im schlechtesten Falle eben einen DisplayRAM der den kompletten Text enthält. Zusätzlich benötigst du also einen Display Buffer im SRAM. Ich meine das eine bessere Fontzeichenroutine die mit einem virtuellen X-Y-Offset arbeiten kann besser ist. Diesen X-Y-Offset kannst du auch einfach als die X,Y Position des Textes auf dem Display betrachten. Es muß halt möglich sein das X und Y auch negative Werte enthalten können. Du zeichnest dann einfach jedesmal deinen Text neu, aber veränderst die X Position. Die Zeichenroutine überprüft dabei welche Zeichen/Pixel im sichtbaren Bereich des Displays liegen und zeichnet auch nur diese Pixel. Gruß Hagen
Diese "Überprüfung" innerhalb der Fontzeichenroutine nennt man auch Clipping. Wenn du nämlich statt 0...DisplayBreite-1 als hardcoded Clipping stattdessen mit Variablen arbeitest hast du in deiner Funktion auch ein dynamisches Clipping ohne großen Aufwand integriert. Nun ist es nicht mehr nur möglich einen Text in allen Richtungen auf dem kompletten Display zu scrollen, sondern mit der gleichen Funktion kannst du auf dem Display gleich mehrere Texte in eigenen rechteckigen Bereichen scrollen lassen. Du hast also eine recht flexible Fontzeichenroutine die du eh in irgendeiner Form benötigst. Nur mit dem Unterschied das diese Routine 1.) ein Clipping enthält 2.) über die X,Y Koordinaten dann ein Scrolling ermöglicht Der zeitliche Aufwand sowas dann per Hand in Asembler zu optimieren lohnt sich dann auch. Performancetechnisch sollte das nicht langsmmer als das Rotieren großer Speicherbereiche sein. Speichertechnisch benötigt das keinen Puffer im SRAM mehr. Gruß Hagen
Puh, guter Tipp. Was mir dabei aber nicht so gefällt, ist, dass ich nicht Bilder rotieren kann, aber die Idee ist tatsächlich nicht übel. grübel
Könntest du die Daten evtl auch anders ablegen? also dass die Bytes "um 90° gedreht" sind, also 2 Byte sind für die erste Spalte zuständig. Dann musst um zu shiften nur um eine Spalte später anfangen, die ganzen ROL's kannst dir dann sparen, da dur nur einen Offset auf nen Pointer hinzuaddieren musst. Gruß Roland
@Roland: das könnte man, fragt sich was erreicht man damit. Aus meiner Sicht versuche ich immer dort den "Hebel" anzusetzen bei dem mit dem vergleichsweise geringsten Programmieraufwand die größte Funktionalität zu erwarten ist. Lange Rede, deine Lösung ist eine hochspezialisierte die davon ausgeht das man ein horizontales Scrolling am effizientesten hinbekommt. Das Problem ? so kann man nur horizontal effizient scrollen und öfters stellt man später fest das es eventuell besser gewesen wäre es gleich richtig zu machen. Die Optimierung der Fontzeichenroutinen ermöglicht nicht nur das gewünschte Scrolling horizontal in beide Richtungen, sondern auch vertikal oder diagonal und das mit beliebigen Fonts/Zeichen/Icons, in beliebigen Farben, ohne extra Buffer im RAM, auf eingeschänkten Bildschirmbereichen->Clipping. Wird, nebenbei gesagt, noch eine Koordinatentransformation beim Pixelsetzen dazwischen geschaltet, so kann man die Fonts auch rotieren. Der programmtechnische Overhead beschränkt sich auf: - Koordinaten X,Y und Clipping Rechteck als neue Parameter - das Berücksichtigen des Clipping - das Berechnen gegebener Koordinate in den zu zeichneden Text relativ zum sichtbaren Display Bereich ansonsten bleibt es beim gewohnten Zeichengenerator wie in jeder Library. Obige Änderungen sind in den meisten Fällen eine Form des Precomputing, also einmal pro Textausgabe zu berechnen für alle zu zeichnenden Zeichen. Ergo: im Grunde vernachlässigenbar in der Performance. Einzigst die Frage des Aufbaus der Fonts im Speicher, also deren Kodierung ist noch wichtig und eventuell abhängig vom Displaytypus. Die Zwischenspeicherung von halbfertigen Screens, wie bei Games üblich, verbraucht viel an schnellen Speicher und immernoch effiziente CPUs. Jede Form der Zischenspeicherung über Buffer macht im Grunde nur dann Sinn wenn der Bildliche Inhalt dieser Buffer mehrfach benötigt wird und denoch veränderlich ist. Gutes Beispiel sind Sprites die sich von Zeit zu Zeit verändern und neu berechnet werden. Solche Sache bekommt man mit Buffern effizient. Aber eine Fontzeichenroutine wird durch Bitmaps nicht wesentlich schneller sondern nur einfacher zu programmieren. Gruß Hagen
Ich wollte jetzt mal testweise meine Variante (RAM rotieren) ausprobiern, aber mir fällt da gerade ein Problem auf: Wo soll ich anfangen zu schieben? fange ich links an, dann ist doch der Carry garnicht bekannt. Fange ich rechts an, habe ich das gleiche Problem.. Irgndeiner ne Idee, wie ich vorher das carry laden kann?
Ok, habs gelöst. Springe beim Scrollen jeder Zeile einmal an den Anfang um mir das Carry zu holen, und gehe dann zurück nach hinten und schiebe von da aus.
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.