Array of String Arrays

#3445119
Lesenswert?

Hi,ich möchte auf meinem LCD eine Menüstruktur mit Untermenüs einbauen.
Hierzu habe ich mir gedacht ich nehme ein 2 Dimensionales String Array,
welches ich im Flash ablege.
Das ganze lässt sich zwar Compilieren, aber nach Abruf des Strings zeigt 
das LCD nur noch mist an.
Nun würde ich gerne von euch wissen, ob folgende Code-Zeilen korrekt 
sind.
Zum einen das Ablegen im Flash:
1
const char menue_unter1_strings[5][4][16] PROGMEM = {
2
  {"AA", "AB", "AC", "AD"}, { "BA", "BB", "BC"}, { "CA", "CB", "CC"}};
und das lesen aus dem Flash und ablegen im Array Buffer (char):
1
strcpy_P (buffer, (const char*) pgm_read_word (menue_unter1_strings[0][1]));
Controller ist ein ATMEGA 644 dürfte also Flashmäßig eigentlich keine 
Probleme geben.

Gruß Miche
#3445192
Lesenswert?

Danke schon mal,
nun habe ich auch verstanden, warum das so nicht ging ;)
Ich habe nun aber 3 Arrays welche ich wie im Beispiel abespeichert habe.
Jetzt müsste ich also wiederum ein Array i Speicher ablegen, welches die 
Zeiger der Arrays (welche die Zeiger enthalten, die auf die Strings 
zeigen) enthalten.
Wenn ich allerdings so verfahre und es mit:
1
 
2
PGM_P ...[] PROGMEM = { strarray1, strarray2, strarray3};
versuche, so liefert mir der Compiler:
Warning: initialization from incompatible pointer type.
Weiters, wie rufe ich dann solch ein Array auf ( mit ...[][] geht es ja 
wohl kaum)? Ich stehe da irgendwie ein wenig auf der Leitung und bin mit 
Zeigern, wie ich zugeben muss wohl noch nicht so fit.

Gruß
#3445254
Lesenswert?

>Weiters, wie rufe ich dann solch ein Array auf ( mit ...[][] geht es ja
>wohl kaum)? Ich stehe da irgendwie ein wenig auf der Leitung und bin mit
>Zeigern, wie ich zugeben muss wohl noch nicht so fit.

Wenn du in unserer Lieblingssuchsmaschine einfach mal alle deine 
Keywords eingibst, also z.B. "progmem avr multi dimensional array 
Flash", findest du alle Informationen, die du brauchst und Beispiele, an 
denen du dich orientieren kannst, z.B. hier, sogar mit einer ganz 
ausführlichen Erklärung des Großmeisters KHB.


Beitrag "PROGMEM und 2 dimensionaler array"


Gruss, Rainer
#3445397
Lesenswert?

Ein wie in dem Link beschriebenes 2 Dimensionales Char Array habe ich 
auch schon hinbekommen. Bei mir hakt es allerdings an einem 2 
Dimensionalen String Array oder 3 Dimensionalen Char Array, je nach 
Betrachtungsweise.
meine komplette aktuelle Definition:
1
char UMEN1_1[] PROGMEM = "Adresse";
2
char UMEN1_2[] PROGMEM = "Modus";
3
char UMEN1_3[] PROGMEM = "Busausfall";
4
char UMEN1_4[] PROGMEM = "Adressierung";
5
PGM_P menue_unter1_strings1[] PROGMEM = {UMEN1_1, UMEN1_2, UMEN1_3, UMEN1_4};
6
char UMEN2_1[] PROGMEM = "Programm";
7
char UMEN2_2[] PROGMEM = "Geschwindigkeit";
8
char UMEN2_3[] PROGMEM = "Aktiv";
9
PGM_P menue_unter1_strings2[] PROGMEM = {UMEN2_1, UMEN2_2, UMEN2_3};
10
char UMEN3_1[] PROGMEM = "ROT";
11
char UMEN3_2[] PROGMEM = "GRUEN";
12
char UMEN3_3[] PROGMEM = "BLAU";
13
PGM_P menue_unter1_strings3[] PROGMEM = {UMEN3_1, UMEN3_2, UMEN3_3};
14
PGM_P menue_unter1_strings[] PROGMEM = { menue_unter1_strings1, menue_unter1_strings2, menue_unter1_strings3};
Ich hoffe, so könnt Ihr mich besser verstehen. Und was ich überhaupt 
machen will. Beispiele zu 3 Dimensionalen Arrays habe ich bis jetzt aber 
auch noch fast nicht gefunden.

Gruß Miche
#3445401
Lesenswert?

Johann L. schrieb:
> Doch tun sie. menue_unter1_strings liegt komplett im Flash.

Tatsächlich! Sorry, da habe ich zu schnell in eine bestimmte Richtung 
gedacht! Dann ist die Lösung ja viel einfacher als gedacht:

Miche, in deiner ersten Lösung nur diese eine Zeile anpassen.
1
strcpy_P (buffer, menue_unter1_strings[0][1]);

Der ganze andere Babel mit Arrays von Zeigern auf Zeichenketten kommt 
erst dann zum Tragen, wenn du Zeichenketten mit unterschiedlicher Länge 
im Flash ablegen willst. Wenn du das nicht brauchst, dann vergiss es.
Und: Danke, Johann.
Gruss, Rainer
#3445427
Lesenswert?

..andererseits, du warst ja auf dem Weg "Array von Zeigern auf 
Zeichenketten" auch schon fast fertig.
Das einzige was dir noch fehlt, ist die richtige Initialisierung des 
Array. Das geht genauso wie immer:
1
PGM_P menue_unter1_strings[3][4] PROGMEM = 
2
  { {UMEN1_1, UMEN1_2, UMEN1_3, UMEN1_4}, 
3
    {UMEN2_1, UMEN2_2, UMEN2_3},
4
    {UMEN3_1, UMEN3_2, UMEN3_3} 
5
  };
Der Zugriff auf das passende Element erfolgt genauso wie oben:
1
    strcpy_P(buffer, menue_unter1_strings[1][2]);

>Ich weiß zwar nun, dass es tatsächlich funktioniert, nur noch nicht
>genau wie und warum zuvor nicht... Das werde ich mir bei Zeiten wohl
>nochmal ansehen :)
1
strcpy_P (buffer, (const char*) pgm_read_word (menue_unter1_strings[0][1]));
Dort hast du einmal zuviel dereferenziert
- menue_unter1_strings[0][1] : Liefert die Adresse, an der im Flash 
deine Zeichenkette "AB\0\0\0...." abgelegt ist.
- pgm_read_word Liest den Inhalt dieser Adresse, also die beiden Bytes 
0x41 und 0x42 ( das entspricht A und B )
- (const char *) zwingt den Compiler, das wiederum als einen Zeiger auf 
eine Zeichenkette zu interpretieren, dh. diese beiden Bytes werden jetzt 
als Zeiger, der auf 0x4241 zeigt, interpretiert.
Ab hier geht's also schief.
- strcpy_P versucht dann den Inhalt der Flashspeicherzellen 0x4241 ff in 
den entsprechenden RAM-Bereich von "buffer" zu kopieren, solange bis \0 
gelesen wird.

Du brauchst also das pgm_read_word an dieser stelle nicht, da der 
Compiler weiß, dass menue_unter1_strings im Flash liegt und aus 
menue_unter1_strings[0][1] gleich eine Flash-Adresse macht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren