Forum: Mikrocontroller und Digitale Elektronik Laufschrift


von Simon K. (simon) Benutzerseite


Angehängte Dateien:

Lesenswert?

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.

von Kai R. (kairiek)


Lesenswert?

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

von Sebastian Heyn (Gast)


Lesenswert?

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.

von Sebastian (Gast)


Lesenswert?

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

von Simon K. (simon) Benutzerseite


Lesenswert?

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...

von Hagen (Gast)


Lesenswert?

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

von Hagen (Gast)


Lesenswert?

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

von Simon K. (simon) Benutzerseite


Lesenswert?

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

von Roland P. (pram)


Lesenswert?

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

von Hagen (Gast)


Lesenswert?

@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

von Simon K. (simon) Benutzerseite


Lesenswert?

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?

von Simon K. (simon) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.