www.mikrocontroller.net

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


Autor: gcc anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
// Einzelner Menüeintrag
typedef struct menuItem
{
  const char *itemName; // Name des Menüitems
  uint16_t config; // Daten zu Lesen und Speichern der Änderungen
  struct menuStruct *subMenu; // Pointer zu einem Untermenü, null wenn nicht verwendet
} menuItem;

// Menüstruktur
typedef struct menuStruct
{
  const char *menuName; // Name des Menüs
  unsigned short numberMenuItems; // Anzahl der Menüeinträge
  menuItem *items; // Zeiger zu einem Array von Menüeinträgen
}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
//*************************************************************************************
// Click auf einen Menüeintrag
//*************************************************************************************
// Hier wird falls vorhanden eine Funktion ausgeführt, die dem Eintrag zugewiesen ist,
// oder es wird ein Untermenü aufgerufen. Ist beides nicht der Fall passiert nichts. 
//*************************************************************************************

menuStruct *SubMenuClick(menuStruct *menuToShow, short selectedIndex)
{

uint16_t menu_handler = (menuToShow->items[selectedIndex]).config;
// Falls dem Menüeintrag ein Ereignis zugewiesen wurde, das ausführen
// Dazu überprüfen ob der Datentyp nicht 0 ist. Ansonsten Untermenü
// ausführen. 
if ( (menu_handler & mask_datatype) != 0) 
{
  Menu_Config(menu_handler);
}
// falls zu dem aktuellen Menüeintrag ein Untermenüeintrag existiert
else 
{
Write_Menu_FILO(menuToShow,active_menu_index); // Aktuelle Menüebene auf den FILO sichern
// Menü zeichnen
drawMenu((menuStruct*)(&menuToShow->items[selectedIndex])->subMenu, selectedIndex);
// Pointer auf neue Menüstruktur zurückgeben. Die wird dann der Input für die folgenden
// Funktionen. 
return (menuStruct*)(&menuToShow->items[selectedIndex])->subMenu;
}
return 0;
}

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

Autor: Markus E. (engelmarkus)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: gcc anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
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

Autor: Markus E. (engelmarkus)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: gcc anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: gcc anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.