Hallo,
ich arbeite mich gerade in STRUCTS ein.
Ziel ist ein Menü auf einem Grafikdisplay mittels AVR auszugeben.
Mein erstes Menü bestand aus mehreren STRUCTS, in denen die Strings
auch im FLASH hinterlegt wurden. Das Auslesen hat wunderbar geklappt.
Nun möchte ich aber nur noch ein STRUCT haben, in dem die Strings
stehen und nicht über eine Art Indexzähler aus einem anderen STRUCT
geladen werden müssen.
Im Anhang ist mein erster Versuch dazu.
Folgend die Probleme, die ich noch nicht durchschaue...
Beim Compilieren bekomme ich mit:
1
ks0108Puts_P(menu_rom_data[0].menu_text);
keinen Fehler.
Compiliere ich mit
1
ks0108Puts_P(&menu_rom_data[0].menu_text);
dann erscheint folgende Warnung:
1
warning: passing argument 1 of 'ks0108Puts_P' from incompatible pointer type
Es wird aber in beiden Fällen nur ein Zeichenwirrwarr auf dem Display
ausgegeben.
Könnte mir bitte jemand auf die Sprünge helfen?! Wäre sehr nett!
Das Tutorial hat mir leider nicht sehr weitergeholfen.
Ein Unbeteiligter sieht den Fehler bestimmt schneller als jemand, der
sich festprogrammiert hat! ;)
Besten Dank,
Marc
Was für einen AVR hast du denn? Dein Array braucht ohne die Strings
schon 4kB Flash.
Marc L. schrieb:> Folgend die Probleme, die ich noch nicht durchschaue...> Beim Compilieren bekomme ich mit:> ks0108Puts_P(menu_rom_data[0].menu_text);> keinen Fehler.
Warum auch? Die Funktion erwartet einen Zeiger auf char, und du
übergibst einen solchen.
> Compiliere ich mit> ks0108Puts_P(&menu_rom_data[0].menu_text);> dann erscheint folgende Warnung:> warning: passing argument 1 of 'ks0108Puts_P' from incompatible pointer type
Klar, du übergibst ja nicht mehr einen Zeiger auf char, sondern einen
Zeiger auf einen Zeiger.
> Es wird aber in beiden Fällen nur ein Zeichenwirrwarr auf dem Display> ausgegeben.
Das liegt daran, daß du nur die Zeiger auf deine Strings im Flash stehen
hast, aber nicht die Strings selbst. Die sind ja nicht Teil der
Struktur.
Danke für die Antworten!
Rolf Magnus schrieb:> Was für einen AVR hast du denn? Dein Array braucht ohne die Strings> schon 4kB Flash.
Sorry, hatte das Array für ein Hauptmenü mit 10 Punkten und 50
Untermenüs mit jeweils 9 Unterpunkten erstellt.
Ist noch ein Überbleibsel von den mehreren STRUCTS.
Darum möchte ich nur ein STRUCT erstellen, damit es Übersichtlicher und
speicherschonender wird, da ich dann keine leeren Bereiche als Reserve
einfügen muss.
Es handelt sich übrigens um einen ATmega1284P.
Rolf Magnus schrieb:> Das liegt daran, daß du nur die Zeiger auf deine Strings im Flash stehen> hast, aber nicht die Strings selbst. Die sind ja nicht Teil der> Struktur.
Klick. Ja, das stimmt.
Aber wie bekomme ich denn die einzelnen Strings in das STRUCT?
Hilft da wirklich nur der Umweg über ein zweites STRUCT? Hoffe nicht.
So sah u.a. ein weiteres STRUCT aus:
Wie bekomme ich also dieses STRUCT in das STRUCT vom Anfangspost?
Habe da schon einiges probiert, jedoch alles ohne Erfolg. :(
Johann L. schrieb:> Strings wie "Drehzhal" werden im RAM abgelegt, nicht im Flash.
Okay, habs mir schon fast gedacht. Wie sieht denn der Aufruf auf, wenn
man die Strings in den FLASH ablegen will?
Bekomme das irgendie nicht hin. Mit PROGMEM funktioniert das nicht.
Ist vielleicht auch der falsche Ansatz?!
Danke,
Marc
Marc L. schrieb:> Johann L. schrieb:>> Strings wie "Drehzhal" werden im RAM abgelegt, nicht im Flash.> Okay, habs mir schon fast gedacht. Wie sieht denn der Aufruf auf, wenn> man die Strings in den FLASH ablegen will?> Bekomme das irgendie nicht hin. Mit PROGMEM funktioniert das nicht.> Ist vielleicht auch der falsche Ansatz?!
Also ich kann mir nicht vorstellen, daß du 510 (in Worten:
fünfhundertundzehn) Menü-Punkte hast!
Davon ab ist es leider nicht so einfach, String-Literals ausserhalb von
Funktionen in den Flash zu bekommen:
1
const char str1[] PROGMEM = "str1"; // in Flash
2
const char* str2[] PROGMEM = "str2"; // "str2" im RAM, str2 im Flash
Das muss man umständlich über Zwischenvariablen erlegigen:
Marc L. schrieb:> So sah u.a. ein weiteres STRUCT aus:> const unsigned char PROGMEM menu_text[510][20+1] = {> // Hauptmenü -----------------------------------------------> {"Text1 "}, // Text Nr. 0> {"Test2 "}, // Text Nr. 1> {"Text3 "}, // Text Nr. 2> {"Text4 "}, // Text Nr. 3> {" "}, // Text Nr. 4> {" "}, // Text Nr. 5> {" "}, // Text Nr. 6> {" "}, // Text Nr. 7> {" "}, // Text Nr. 8> {" "} // Text Nr. 9> };
Struct? Wo? Das ist ein Array.
Du mußt es im Prinzip so machen, wie Johann schreibt, also jeden String
einzeln mit PROGRMEM definieren, und dann die Zeiger deiner Menüeinträge
damit initialisieren.
Marc L. schrieb:> Folgend die Probleme, die ich noch nicht durchschaue...> Beim Compilieren bekomme ich mit:>
1
ks0108Puts_P(menu_rom_data[0].menu_text);
> keinen Fehler.>> Compiliere ich mit>
1
ks0108Puts_P(&menu_rom_data[0].menu_text);
> dann erscheint folgende Warnung:>
1
warning: passing argument 1 of 'ks0108Puts_P' from incompatible
2
> pointer type
> Es wird aber in beiden Fällen nur ein Zeichenwirrwarr auf dem Display> ausgegeben.
Da ist dann auch noch etwas anderes falsch. (Die Sache mit den Strings
wurde ja schon angesprochen)
Dein menu_rom_data liegt als solches im Flash. Das bedeutet aber auch,
dass du darauf nicht mittels menu_rom_data[0] darauf zugreifen kannst um
dir dann von diesem einen Array Eintrag den Member menu_text zu holen.
Wenn immer Dinge im Flash liegen, muss der Zugriff über die pgm_read_xxx
Funktionen erfolgen. Dein menu_rom_data liegt im Flash, also musst du
auch die pgm_read_xxx Funktion dafür benutzen um an den Pointer zu
kommen, den du dann an ks108Puts_P weitergeben kannst.
Karl Heinz Buchegger schrieb:>> Compiliere ich mit>> ks0108Puts_P(&menu_rom_data[0].menu_text);> dann erscheint folgende>> Warnung:>> warning: passing argument 1 of 'ks0108Puts_P' from incompatible>> pointer type> Da ist dann auch noch etwas anderes falsch.
Ja, und zwar erwartet die Funktion
1
ks0108Puts_P(...);
ein char und kein unsigned char.
So hat es geklappt:
1
constcharPROGMEMmenu_text[510][20+1]={
Johann L. schrieb:> Also ich kann mir nicht vorstellen, daß du 510 (in Worten:> fünfhundertundzehn) Menü-Punkte hast!
Doch, so war es geplant:
Hauptmenü: 10 Einträge
Untermenü: 1x Maschinenauswahl + 9x Datenbereiche = 10 Einträge
Da ich 50 Maschinen erstellen wollte: Hauptmenü (10) + Untermenüs
(50*10) = 510 Einträge!
Das habe ich wieder verworfen.
Nun habe ich es wiefolgt gelöst:
Ich habe mir eine Sprungtabelle als STRUCT erstellt.
In der ersten Spalte steht jeweils der Laufindex, den ich dazu verwende
Strings aus einem Array auszulesen. Das geht sehr gut.
Habe zwei Arrays definiert: einmal den Haupttext, der angezeigt wird und
einmal den Infotext passend zum Haupttext. Gemanaged wird das über den
Laufindex.
Und vor allem: Es liegt alles im Flash!
Danke an alle, jetzt ist mir so einiges klar geworden!
Marc