Forum: Compiler & IDEs Problem mit Structs für LCD Menü


von gcc anfänger (Gast)


Lesenswert?

Hallo

Ich schreibe seit einiger Zeit eine Bibliothek für ein LCD Menü.
Leider bin heute auf ein Problem gestoßen bei dem ich nicht weiter weis. 
Vielleicht stehe ich auch nur auf dem Schlauch, aber es will einfach 
nicht funktionieren.

Ich habe das Menü mit Structs aufgebaut:

Auszug aus der H Datei
1
// Einzelner Menüeintrag
2
typedef struct menuItem
3
{
4
  const char *itemName; // Name des Menüitems
5
  uint16_t config; // Daten zu Lesen und Speichern der Änderungen
6
  struct menuStruct *subMenu; // Pointer zu einem Untermenü, null wenn nicht verwendet
7
} menuItem;
8
9
// Menüstruktur
10
typedef struct menuStruct
11
{
12
  const char *menuName; // Name des Menüs
13
  unsigned short numberMenuItems; // Anzahl der Menüeinträge
14
  menuItem *items; // Zeiger zu einem Array von Menüeinträgen
15
}menuStruct;

Es gibt also folglich zwei Structs. Ein menuItem Struct und ein 
menuStruct, das aus diesen menuItem Structs besteht. Diese 
Verschachtelung kann beliebig weiter ausgeführt werden.

Doch nun zu meinem Problem:

Ich hab die Idee, die Menüstruktur so aufzubauen, von einem Projekt hier 
im Forum übernommen. Das Menü Funktioniert soweit problemlos. Man kann 
Scrollen und auch die Zurückfunktion, um wieder ein Menü höher zu 
kommen, ist implementiert. Nun hab ich aber anstatt eines 
Funktionspointers, wie in der ursprünglichen Version eine uint16_t 
Variable verwendet. Das Word ist in einzelne Bits unterteilt, und dient 
dazu aus dem richtigen array im EEPROM die Einstellungen die im Menü 
gemacht wurden zu laden oder zu speichern. Diese uint16_t Variable macht 
mir Probleme. Ich bekomme es einfach nicht hin auf sie ordnungsgemäß 
zuzugreifen. GCC zeigt keine Fehler an, jedoch wird anscheinend nur Mist 
ausgelesen, da sich dann das Programm irgenwohin verabschiedet, was man 
daran erkennt dass sich das Display langsam mit einem Buchstabenwirrwar 
füllt, und sich der AVR kurze Zeit danach neu startet.

Hier der Code
1
//*************************************************************************************
2
// Click auf einen Menüeintrag
3
//*************************************************************************************
4
// Hier wird falls vorhanden eine Funktion ausgeführt, die dem Eintrag zugewiesen ist,
5
// oder es wird ein Untermenü aufgerufen. Ist beides nicht der Fall passiert nichts. 
6
//*************************************************************************************
7
8
menuStruct *SubMenuClick(menuStruct *menuToShow, short selectedIndex)
9
{
10
11
uint16_t menu_handler = (menuToShow->items[selectedIndex]).config;
12
// Falls dem Menüeintrag ein Ereignis zugewiesen wurde, das ausführen
13
// Dazu überprüfen ob der Datentyp nicht 0 ist. Ansonsten Untermenü
14
// ausführen. 
15
if ( (menu_handler & mask_datatype) != 0) 
16
{
17
  Menu_Config(menu_handler);
18
}
19
// falls zu dem aktuellen Menüeintrag ein Untermenüeintrag existiert
20
else 
21
{
22
Write_Menu_FILO(menuToShow,active_menu_index); // Aktuelle Menüebene auf den FILO sichern
23
// Menü zeichnen
24
drawMenu((menuStruct*)(&menuToShow->items[selectedIndex])->subMenu, selectedIndex);
25
// Pointer auf neue Menüstruktur zurückgeben. Die wird dann der Input für die folgenden
26
// Funktionen. 
27
return (menuStruct*)(&menuToShow->items[selectedIndex])->subMenu;
28
}
29
return 0;
30
}

Hoffe ihr könnt mir helfen wie ich auf die Variable config ohne Fehler 
zugreifen kann.

Die Struktur wäre wie Folgt:

menuStruct->menuItems[Index]->config.


MfG

von Markus E. (engelmarkus)


Lesenswert?

Wie liest du denn das Array aus dem EEPROM überhaupt ein? Da scheint 
doch der Fehler zu liegen, oder versteh ich dich nicht richtig?

von gcc anfänger (Gast)


Lesenswert?

Markus E. schrieb:
> Wie liest du denn das Array aus dem EEPROM überhaupt ein? Da scheint
> doch der Fehler zu liegen, oder versteh ich dich nicht richtig?

Diese Funktion ist noch gar nicht implementiert. Sollte jedoch 
funktionieren. Wenn man auf einen Menüeintrag klickt sollte sich dann 
ein Einstellungsfenster öffnen (Grafik LCD) wo man die entsprechenden 
Werte verändern kann. Wenn man das Einstellungsfenster wieder verlässt, 
werden die Werte oder der Wert, je nach dem ins EEPROM gespeichert. 
Damit der AVR aber weis wohin er es speichern soll gibt es eben die 
"config" Variable im Struct Menuitem.

Doch auf diese Variable ist es mir bisher (vll. aufgrund meiner noch 
nicht so herausragenden Pointerkenntnisse va. bei structs) noch nicht 
gelungen.

Ich möchte eigentlich nur wissen wie ich auf diesen Datenwert in dem 
entsprechenden Struct zugreifen kann.

SO wie ich es gemacht habe:
1
uint16_t menu_handler = (menuToShow->items[selectedIndex]).config;

funktioniert es ja anscheinend gar nicht. Nur zur Erläuterung: 
menuToShow ist ein Pointer vom typ menuStruct.

Ich greife also auf ein menuStruct über den Pointer menuToShow zu. Von 
diesem Menüstruct, will ich den Pointer auf den menuItem mit aktuellen 
Index haben, greife also auf das Pointerarray "*items" vom typ *menuItem 
zu. Von diesem Pointer auf dieses menuItem struct  will ich nun den 
Datenwert config erhalten.

Das ist es, was mir genau Probleme bereitet

MfG

von Markus E. (engelmarkus)


Lesenswert?

Die Zeile, auf der du immer rumreitest, ist vollkommen richtig :) . Der 
Fehler muss schon weiter vorne sein, wo du das Menü erzeugst. Benutzt du 
auch einen nullbasierten Index?
Du erzeugst aber nicht deine items-Arrays als lokale Variablen, und 
weist dem menuStruct dann darauf einen Zeiger zu, oder sowas?

von gcc anfänger (Gast)


Lesenswert?

Markus E. schrieb:
> Die Zeile, auf der du immer rumreitest, ist vollkommen richtig :) . Der
> Fehler muss schon weiter vorne sein, wo du das Menü erzeugst. Benutzt du
> auch einen nullbasierten Index?

Ja ich benutze ich.

Wenn das richtig ist, dann muss irgendetwas in der Funktion SubMenuClick 
falsch sein. (siehe oben) Denn hier entsteht der Fehler. Denn sobald 
einem Menüeintrag ein Ereignis zugewiesen wird (config != 0), dann tritt 
der Fehler auf. Bis jetzt hatte ich aber immer angenommen, dass es 
aufgrund eines falsch ausgelsenen config Wertes passiert ist.

Ich werd gleich die Funktion kontrollieren. Vielleicht finde ich den 
Fehler.

MfG

von gcc anfänger (Gast)


Lesenswert?

Ja gefunden.

Ein saublöder Fehler. Ich hab den vom Benutzer auswählbaren Menüindex 
mit dem mitlaufenden internen Index verwechselt. Da war es klar dass es 
einen Chrash geben musste.

Nochmal danke für eure bzw. deine Hilfe Markus

MfG

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.