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!
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
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
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
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
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
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.