LCD Menü Routine funktioniert nicht

OP #1415775
Guten Morgen,

bin im Moment eine kleine Menü Routine für ein 2x16 LCD am schreiben. µC 
ist ein ATMega 16.
Hier mal die wichtigen Ausschnitte:
1
//Menü
2
//Menü Texte
3
static const char menu_string0[] PROGMEM = "New Record";
4
static const char menu_string1[] PROGMEM = "Profiles";
5
static const char menu_string2[] PROGMEM = "Free space";
6
static const char menu_string3[] PROGMEM = "Choose Profile";
7
//Menü Struct
8
typedef struct MENU {
9
  const unsigned char *text;
10
  uint8_t previous;
11
  uint8_t next;
12
  uint8_t up;
13
  uint8_t down;
14
  void ( *fp )( void );
15
} MENU_ENTRY;
16
//Menü Funktionen
17
void menu_function01( void )
18
{
19

20
}
21
//Menü Struktur
22
const MENU_ENTRY menue[] PROGMEM= {
23
  { menu_string0, 0, 1, 0, 3, menu_function01 },
24
  { menu_string1, 0, 2, 0, 0, menu_function01 },
25
  { menu_string2, 1, 2, 0, 0, menu_function01 },
26
  { menu_string3, 0, 0, 0, 0, menu_function01 }
27
 };
28
uint8_t menu_count = 0;
29

30
...
31

32
  //Menü scrollen
33
  if (debounce(&PINA, PINA0)) {
34
    menu_count = menue[menu_count].next;
35
    //menu_count = 0;
36
  }
37
  if (debounce(&PINA, PINA1)) {
38
    menu_count = menue[menu_count].up;
39
    //menu_count = 1;
40
  }
41
  if (debounce(&PINA, PINA2)) {
42
    menu_count = menue[menu_count].down;
43
    //menu_count = 2;
44
  }
45
  if (debounce(&PINA, PINA3)) {
46
    menu_count = menue[menu_count].previous;
47
    //menu_count = 3;
48
  }
49

50
  lcd_clrscr();
51
  //Text für Menü ausgeben
52
  strcpy_P(firstLine, (char*)pgm_read_word(&menue[menu_count].text));
53
  lcd_gotoxy(0,0);
54
  lcd_puts(firstLine);

Leider funktioniert das ganze nicht so. Wenn ich z.B. in Menü 0 die 
Taste A2 drücke springt er nicht wie gewünscht auf Menü 3.
Vielleicht findet ihr den Fehler. Danke schonmal!

Gruß,
Patrick
Patrick Franken schrieb:

> Vielleicht findet ihr den Fehler. Danke schonmal!

Dein Fehler ist, dass du die Menüdaten komplett ins Flash ausgelagert 
hast, beim Zugriff auf die Daten dies aber nicht berücksichtigst.
1
  menu_count = pgm_read_byte( &menue[menu_count].next );

und alle anderen Stellen an denen du Werte von menue holst.
OP
Wow, vielen Dank für die super schnelle Antwort! Es funktioniert jetzt. 
Habe aber noch eine kleine Frage im Bezug auf den Function Pointer im 
Struct:
Wie kann man die Funktionen aufrufen?
Habe es schon mit
1
(*menue[menu_counter].fp)();
versucht, was aber leider nicht funktionierte. Wenn ich die Funktion 
sofort aufrufe funktioniert es hingegen.

Gruß,
Patrick
Patrick Franken schrieb:
> Hm... Weis keiner was? Hab schon alles getestet, aber es geht nicht :-(

Schon ein starkes Stück, wenn man dir zu erklären versucht, dass ALLES, 
was du von menu holst, über read_pgm_xxx gemacht werden muss, du zum 
AUsdruck bringst es verstanden zu haben und dann ein paar Stunden später 
schon wieder denselben Fehler machst und ihn nicht erkennst.

const MENU_ENTRY menue[] PROGMEM= {

das komplette menue liegt im Flash!
Egal, was du von dort lesen willst, du musst
* festlegen, von welcher Adresse du lesen willst
* einen read_pgm_xxx Aufruf machen, damit der Lesezugriff von dieser
  Adresse im Flash und nicht im SRAM passiert.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.