mikrocontroller.net

Forum: Compiler & IDEs LCD-Menü Pointerfrage


Autor: Marcus M (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

nachdem ich die Thread:

    http://www.mikrocontroller.net/forum/read-2-40721.html#40721
    http://www.mikrocontroller.net/forum/read-2-18413.html#18413

und

    http://www.mikrocontroller.net/forum/read-2-78266.html

gelesen habe, hab ich noch eine kleine Frage.
Wenn ich mein Menü mit
static const char menu0[] PROGMEM = "Hauptmenu";
static const char menu1[] PROGMEN = "zweites Menü";

im Flash abgelegt habe, wie bekomme ich dann die folgenden Pointer?
Das sind doch IMHO dann funktion - Pointer und keine Datapointer.

typedef struct{

  const char *name; //This one!
  const menustruktur* next; // This one
  const menustruktur* previous; //This one
  const menustruktur* sub; //This one
  const menustruktur* up;  // This one
  void ( *funktion )( void );
}menustruktur;

menustruktur Menu[240];

Somit könnte ich direkt mit einer Funktion z.B.


void do_Next(menustruktur entrie){

  if (TASTER_NEXT) {
    if (entrie.next != 0x0) { //sonst wird die Funktion ausgeführt
      LCD_Write((entrie.next).name);
      return (entrie.next);
    }
    else {
     entrie.funktion();
     return (entrie.this());
    }
  }
  else
   if (entrie.prev != 0x0) {
      LCD_Write((entrie.prev).name);
      return (entrie.prev);
   }
   else {
      entrie.funktion();
      return (entrie.this());
   }
  }

}

die Sache auf das Display zaubern und dann auch die passende Funktion
ausführen.

in Main würde das dann so aussehen:

int main (void) {


// do something
menustruktur temp_ent = Menu[0];

temp_ent = do_Next(temp_ent);

}

Ich hoffe, jedem ist jetzt klar, was ich da vor habe.
Ich kenne mich so halbwegs mit Pointern aus und glaube das auch
verstanden zu haben. Wenn da jetzt irgendwelche groben Fehler drin
sind, sagt mir das bitte.

Geht das so überhaupt?

Gruß Marcus

PS: Sorry, das diese Frage versehendlich in die Codesammlung gekommen
ist!

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Marcus,

Deine typedef muss schonmal anders aussehen, damit die
Selbst-Referenzierung funktioniert. Das const gehört nicht in die
typedef, sondern in die Variablen-Deklaration, mit PROG_MEM:

typedef struct def_menustruktur{
  struct def_menustruktur* next;
  struct def_menustruktur* previous;
  struct def_menustruktur* sub;
  struct def_menustruktur* up;
  void ( *funktion )( void );
}menustruktur;


void do_anything(void);
void do_everything(void);
void do_nothing(void);


PROGMEM menustruktur menu[3] =
{
  { &menu[1], &menu[2], &menu[0], &menu[0], do_anything},
  { &menu[2], &menu[0], &menu[1], &menu[1], do_everything},
  { &menu[0], &menu[1], &menu[2], &menu[2], do_nothing}
};


void do_anything(void){
}

void do_everything(void){
}

void do_nothing(void){
}


In den Bearbeitungsroutinen musst Du bei JEDEM Zugriff auf die
Struktur-Daten pgm_read_word bzw. pgm_read_byte verwenden, hier mal
Deine Function etwas gekürzt:


int do_Next(menustruktur entrie){
  void (*my_func_ptr)(void);

  if (TASTER_NEXT) {
    if (pgm_read_word(entrie.next) != 0x0) { //sonst wird die Funktion
ausgeführt
      return (pgm_read_word(entrie.next));
    }
    else {
     my_func_ptr = (void*) pgm_read_word(entrie.funktion);
     my_func_ptr();
     return (pgm_read_word(entrie.sub));
    }
  }
}


gcc übersatzt das Ganze so fehlerfrei, ob der Aufruf der Funktion so
richtig klappt, habe ich jetzt mal nicht praktisch ausprobiert.

Die Art das Menu zu programmieren, ist richtig. Mit den Pointern auf
Funktionen kann man richtig klasse Sachen machen. Du kannst übrigens
den Funktionen auch Werte mitgeben ...

Viel Spass, Stefan

Autor: Marcus M (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

langsam raff ich, warum ich mich immer nur im Kreis gedreht habe -
leider! Ich bin zwar viel "Pointern" gewohnt, denn bei so richtig
großen Arrays (> 200MB) wid die ganze Sache richtig spassig ;-).
Leider bin ich bisher immer x86er gewöhnt und der nahm einen diesen
Kram ab. Ich fand bisher nur nicht heraus, wann und wie ich die Pointer
auf das Flash bekomme.

THX, werd mal mein Glück versuchen.

Danke

Gruß Marcus

Autor: Marcus M (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

leider komme ich mit dem speichern im Flash nicht ganz weiter.
Egal wie ich es wende, entweder läuft der Code und das Display zeigt
ausschnitte aus dem Programm oder der Mega16 dreht vor lauter resetten
durch ;-).

Wär jemand mal so lieb und würde auf den C - Code einen kleinen Blick
werfen?

ich raff nicht, wo der Fehler liegt!

Danke!

Gruß Marcus

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void menu (void) {

  menustruktur my_struct;
  char temp[16];
  strcpy_P(temp, (char*)pgm_read_word(Hauptmenu.name));
  for (int i = 0; i < 4; i++) {
    LCD_write(i, temp);
    my_struct = pgm_read_word(my_struct.down);
                ^                         ^
                I                         I
                I                         my_struct scheint im 1.
                I                         Durchlauf nicht
                I                          initialisiert zu sein
                I
                deshalb wird my_struct
                hier mit Schrott beschrieben

    strcpy_P(temp, (char*)pgm_read_word(my_struct.name));
                                                    ^
                                                    I
                                                    Und hier ist dann
                                                    leider auch Müll
                                                    drin

Stefan

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nur als "Einwurf" (und weil das Ding mein "Steckepferd" ist/war): Im
Quellcode der vorinstallierten Anwendung des AVR-Butterfly findet sich
einiges an nutzlichen Informationen zu Menustrukturen, Initialsierung
und Pointern. Das avr-gcc-spezifische (progmem) kann man sich im
gcc-port anschauen. ("Eigenwerbung":)
www.siwawi.arubi.uni-kl.de/avr_projects

Autor: Marcus M (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

das Problem habe ich mitlerweile gelöst.
Mein Problem scheint aber ganz wo anders zu liegen.

Schau Dir mal "Version 2" an.

Meine ganz dumme Frage ist folgende:
Wenn ich den z.B. (my_structur -> up) -> name bekommmen will, muß ich
doch folgendes tun:

1. Adresse von my_struct herausbekommen
2. Addresse von my_struct -> up herausbekommen mit:
     pgm_read_word(my_struct -> up)
3. Inhalt von my_struct -> up lesen mit:
     pgm_read_byte(pgm_read_word(my_struct-> up));
4. Danach irgendwie my_struct diesen Wert zuweisen:
     my_struct = pgm_read_byte(pgm_read_word(my_struct -> up);
5. Nun die Addresse von my_struct -> name herausbekommen mit:
     pgm_read_word(my_struct->name);
7. diesen Inhalt einer temporären Variablen zuweisen mit:
     char temp[16];
     strcpy_P (temp, pgm_read_word(my_struct->name);

Irgendwo hier liegt mein Fehler.
Ich hoffe, jemand von Euch kann mir den Denkfehler mal kurz erklären
und mir vom Schlauch helfen. Danke

Gruß Marcus

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Marcus,

ich arbeite gerade in meinem eigenen Projekt mit dem Flash und da ist
mir nachträglich eingefallen, dass bei Dir fast überall die
Adress-Operatoren "&" fehlen:

my_struct = pgm_read_word(&(my_struct.down));
                          ^
                          I
                           hier z.B. fehlt er

pgm_read_word und pgm_read_byte sind ja Makros und liefern deshalb
leider keinen Fehler, wenn man sie mit den falschen Typen benutzt.

Stefan

Autor: Marcus M (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

Danke, ich hab Deinen Beitrag erst heute gelesen, weil ich derzeit
Fliegertage habe - Segelflug ;-)

Ich dachte immer, das Makro würde von sich aus die Adresse auflösen.
Aber egal, werd mal mein Glück probeiren. THX!!

Gruß Marcus

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.