Hallo!
Ich muss viel Text auf einem Display ausgeben. Dazu habe ich mehrere
über 1000 Zeichen lange Strings im Flash (PROGMEM) meines Atmega168.
Ich möchte nun den Text scrollen, brauche also einen Zeiger auf die
aktuelle Position im Flash, ab der dann ausgegeben wird.
Ich möchte der Ausgaberoutine übergeben, ab welchem Buchstaben sie den
Text darstellen soll. Diese soll dann soviel text wie möglich auf einem
Bildschirm darstellen und zurückgeben, wo der nächste Ausgabebildschirm
beginnt. Einfach abzählen geht leider nicht, da u.A. Zeilenumbrüche im
Text sind.
Vorher müsste ich noch auswählen, welches "Kapitel", also welcher
Strings angezeigt werden muss.
Wie kann ich das machen?
Heinz schrieb:> Hallo!> Ich muss viel Text auf einem Display ausgeben. Dazu habe ich mehrere> über 1000 Zeichen lange Strings im Flash (PROGMEM) meines Atmega168.> Ich möchte nun den Text scrollen, brauche also einen Zeiger auf die> aktuelle Position im Flash, ab der dann ausgegeben wird.
Soweit richtig
> Ich möchte der Ausgaberoutine übergeben, ab welchem Buchstaben sie den> Text darstellen soll. Diese soll dann soviel text wie möglich auf einem> Bildschirm darstellen und zurückgeben, wo der nächste Ausgabebildschirm> beginnt. Einfach abzählen geht leider nicht, da u.A. Zeilenumbrüche im> Text sind.
Dann muss die Ausgaberoutine sowas wie eine rudimentäre Screenverwaltung
machen um festzustellen, wann der Screen voll ist.
Das sind:
* Zeichen mitzählen um zu wissen, wann ein erzwungener Umbruch erfolgen
wird
* Umbrüche mitzählen
Kommt die Ausgaberoutine zur Erkentnis, das mit dem nächsten Zeichen
seine eigene virtuelle Cursorposition unter den sichtbaren Bereich
fällt, dann hört sie auf auszugeben und liefert die aktuelle
Flashposition als Returnwert. Ist der String zu Ende, liefert sie NULL
Ist doch nicht so schwer. Ein bischen mitzählen und sich das Zeichen
ansehen, ehe es zum Display geschickt wird.
Der Fall "runterscrollen" ist leicht.
Interessanter ist der Fall: raufscrollen.
Hallo Heinz,
Welcher Compiler? avr-gcc?
Warum machst du das nicht mit Zeigern? Aufruf der Routine mit Zeiger auf
das erste auszugebende Zeichen, Rückgabe eines Zeigers mit dem nächsten
auszugebenden Zeichen. Der wird dann beim nächsten Aufruf verwendet.
Eventuell Rückgabe von "nil" als Signal, dass der String komplett
ausgegeben wurde.
Gruß, DetlevT
Ich würde das schon gerne mit Zeigern machen, weiß aber eben nicht wie.
Die Erkennung ob der Bildschirm voll ist klappt schon. Ist ein
Grafikdisplay und wird dort gleich mit erledigt.
Die Frage ist eben wie ich die Zeiger machen soll (global?) damit ich
damit auf einen String im Flash zeigen und den Zeiger weiterschalten
kann...
Heinz schrieb:> Ich würde das schon gerne mit Zeigern machen, weiß aber eben nicht wie.> Die Erkennung ob der Bildschirm voll ist klappt schon. Ist ein> Grafikdisplay und wird dort gleich mit erledigt.> Die Frage ist eben wie ich die Zeiger machen soll (global?) damit ich> damit auf einen String im Flash zeigen und den Zeiger weiterschalten> kann...
Ähm
Das Problem ist dass ich die Zeichenketten im Flash speichern muss also
const char Text1[] PROGMEM = "123...";
und da weiß ich eben nicht wie mit Zeigern umgehen...
Heinz schrieb:> da weiß ich eben nicht wie mit Zeigern umgehen...
Das ist halt das frustrierende an Deiner Fragestellung: Wir wissen nicht
und können nicht wissen was Du mit "umgehen" meinst. Dir hier erstmal
eine Einführung in Zeiger zu geben habe zumindest ich keine Lust. Dafür
gibt es Bücher.
Von den verbleibenden, nicht-trivialen Möglichkeiten gibt es soviele das
die wiederrum ganze Bücher füllen könnten. Im allgemeinen leitet man
sich die auch aus den Grundlagen her. Was also, verd... nochmal, ist
konkret Dein Problem?
@ Heinz (Gast)
>Das Problem ist dass ich die Zeichenketten im Flash speichern muss also>const char Text1[] PROGMEM = "123...";
Das const kannst du weglassen, bringt nix.
>und da weiß ich eben nicht wie mit Zeigern umgehen...
Dann musst du ein C-Buch lesen, dort steht das drin. Und wird 1:1 auch
auf dem AVR so angewandt. Naja, nicht ganz, der Typ ist dann halt PGM_P
anstatt char*. Aber das macht vom logischen Gebrauch keinen Unterschied.
MFG
Falk
Und im Zweifel gibt es dann immer noch das AVR-GCC-Tutorial das einen
ganzen Abschnitt über den Flash Speicher und wie man ihn benutzt bietet.
Mit dem Wissen und dem Studium von zb der dort angegebenen Funktion
uart_puts_p schreibt man sich dann als Ausgangspunkt ganz fix eine
Ausgabefunktion für Texte, basierend auf einer Ausgabefunktion für
einzelne Nicht-Flash-Zeichen, die man eh schon hat
1
voiddrawText_p(PGM_PflashText)
2
{
3
charc;
4
5
c=pgm_read_byte(flashText++);
6
while(c!='\0'){
7
drawChar(c);
8
c=pgm_read_byte(flashText++);
9
}
10
}
teste die und baut sie dann zur Scroll Maschine aus.