Forum: Mikrocontroller und Digitale Elektronik Menüstruktur aufbauen in C mit Unermenüs


von Markus O. (maxmaxmax82)


Lesenswert?

Hallo,

Ich habe mich mitlerweile durch die verschidensten Beiträge gelesen.
Switch, Case und struct bzw Funktionszeiger.

Ich will auf einem Display ein Menu aufbauen das in der Hauptanzeige im 
unteren Bereich nur die Funktion der Tasten anzeigt.
Und zwar: Ich habe 3 Tasten (Interruptfähig)
Linke Taste Pfeil hinauf, mittlere "Menu" und rechte Pfeil hinunter.
PS: Habe zur Zeit nur eine Taste für Pfeil hinunter.
Wenn ich die Taste Menu drücke will ich in das Hauptmenu aufrufen das 
mehrere Untermenus zeigt.
z.B Einstellungen usw. Diese Untermenüs will ich wiederrum mit der 
mittleren Taste aufrufen die ab dem Untermenü den Namen OK bzw Enter 
erhalten soll.

Ich habe es mal mit Switch un Case aufgebaut aber ich glaube etwas zu 
umständlich.
Und zwar mache ich das ganze mit einer Variable die rauf oder runter 
zählt.(für Pfeil rauf oder runter) Das heist im Untermenü kann ich mit 
der Variable (Vor dem jeweiligen Untermenü ist ein Pfeil nach rechts) 
den Pfeil vor den Untermenüeinträgen positionieren.
Mein Problem:
Wie komme ich weiter in das Untermenü?
Muss ich abfragen wo der Pfeil gerade steht?

Der aufruf des Hauptmenüs ist auch nicht wirklich gut gemacht. Ich zähle 
mit der mittleren Taste auch eine Variable hoch aber die Taste soll ja 
im Untermenü dann eine andere Funktion haben (auswahl des Untermenus) 
und in der Hauptanzeige Auswahl des Hauptmenüs.

int main (void)
{

  PORTD = 0xFF; // all pull ups on
  DDRD = 0x00; // all pins set as input

  PORTC = 0x0C;  // pull ups on at pin 2 and 3
  DDRC = 0xF3; // pin 2 and 3 set as input

  PORTB = 0xFF; // set pins
  DDRB = 0xFF; // all pins set as output

  ExtIntInit (EXT_INT_2, EXT_INT_MODE_FALLING_EDGE);
  ExtIntInit (EXT_INT_3, EXT_INT_MODE_FALLING_EDGE);

  ExtIntEnable(EXT_INT_2);
  ExtIntEnable(EXT_INT_3);

  sei(); // (set enable interrupt) globale enable interrupts


while(1)
{
  switch (m) // Variable zum auswählen der Hauptanzeige bzw Untermenü
  {
    case 0:
    LCDGrafikInit ();
    LCDGrafikSetScr (0);
    LCDGrafikSetCursorMode (0);
    LCDGrafikSetCursor (0);
    LCDGrafikPutCharExtended(8,4,0x80); // Pfeil nach oben in Zeile 8 / 
Spalte 4
    LCDGrafikPutString (8,9,"Menue"); // Menu in Zeile 8 ab Spalte 9
    LCDGrafikPutCharExtended(8,18,0x81); // Pfeil nach oben in Zeile 8 / 
Spalte 18
    break;
    case 1:
    LCDGrafikInit ();
    LCDGrafikSetScr (0);
    LCDGrafikSetCursorMode (0);
    LCDGrafikSetCursor (0);

    LCDGrafikPutString (1,2,"Anzeige 1"); // Untermenüeintrag Zeile 1 ab 
Spalte 2
    LCDGrafikPutString (2,2,"Anzeige 2"); // Untermenüeintrag Zeile 2 ab 
Spalte 2
    LCDGrafikPutString (3,2,"Einstellungen"); // Untermenüeintrag Zeile 
3 ab Spalte 2
    LCDGrafikPutString (4,2,"Zurueck"); // Untermenüeintrag Zeile 4 ab 
Spalte 2

    LCDGrafikPutCharExtended(8,4,0x80); // Pfeil nach unten Untermenü 
Zeile 8 Spalte 4
    LCDGrafikPutCharExtended(8,18,0x81); // Pfeil nach oben Untermenü 
Zeile 8 Spalte 18

      switch (c) // Varialbe c zum Auswählen an welcher Stelle der Pfeil 
nach rechts stehen soll
      {
        case 0: LCDGrafikPutCharExtended(1,1,0x82); // Pfeil nach rechts 
vor Untermenu in Zeile 1
        break;
        case 1: LCDGrafikPutCharExtended(2,1,0x82); // Pfeil nach rechts 
vor Untermenu in Zeile 2
        break;
        case 2: LCDGrafikPutCharExtended(3,1,0x82); // Pfeil nach rechts 
vor Untermenu in Zeile 3
        break;
        case 3: LCDGrafikPutCharExtended(4,1,0x82); // Pfeil nach rechts 
vor Untermenu in Zeile 4
        break;
        case 4: c=0; // Variable c wird auf 0 zurückgesetzt
        break;
      }
    break;
  } // while (1)
} // main

Besten Dank für jede Hilfe.

von Achim M. (minifloat)


Lesenswert?

Kennst du das MVC-Prinzip?
mfg mf

von Markus O. (maxmaxmax82)


Lesenswert?

Nein das kenne ich noch nicht!

von Achim M. (minifloat)


Lesenswert?

Ich denk nämlich, dass eine Abstraktionsebene dir helfen kann, die 
einzelnen Menüpunkte erstmal strukturiert zu bekommen und nachher 
strukturiert in den Speicher zu packen.

Dazu kann man -tadaa- Strukturen in C benutzen. Die Namen von 
Menüpunkten, "Was tatsächlich getan werden muss", benachbarte Menüpunkte 
etc. würde ich mit Pointern auf einen Stringbereich und Pointern auf 
Funktionen und Pointern auf Menüpunkte lösen. Das kann dann ja alles im 
Flash platz finden.

Irgendwo hier im Forum gab es auch schon mal einen Ansatz mit einer 
Headerdatei, die einem mit ein bisschen GCC-Magie selbst aus einer Art 
"Beschreibungsdatei" dynamisch erzeugt hat. Weiß aber nimmer, wo...

mfg mf

von Karl H. (kbuchegg)


Lesenswert?

Markus Obermüller schrieb:

> Ich habe es mal mit Switch un Case aufgebaut aber ich glaube etwas zu
> umständlich.

Fang erst mal damit an, dir eine FUNKTION zu schreiben, die dir ein Menü 
hinmalt bzw. behandelt.

Und dann überlegst du dir erst mal, wie du ein Menü (= die Anzeige) 
allgemein beschreiben kannst. So wie du das hast, ist das viel zu 
speziell auf deinen konkreten Anwendungsfall zu geschnitten.

> Wie komme ich weiter in das Untermenü?

Das wird dann wohl wieder eine eigene Funktion sein, die sich um das 
Submenü kümmert.

> Muss ich abfragen wo der Pfeil gerade steht?

Darauf wirds wohl hinauslaifen. Wobei du nicht 'abfragst' wo der Pfeil 
gerade steht, sondern du hast eine Variable, die bestimmt wo der Pfeil 
hingemalt werden muss, bzw. welcher Menüpunkt eigentlich der aktive ist.

von sum (Gast)


Lesenswert?


von W.S. (Gast)


Lesenswert?

Markus Obermüller schrieb:
> Ich will auf einem Display ein Menu aufbauen

... und da fängst du als allererstes an, in die Tasten zu hauen und 
irgendetwa in C hinzuschreiben ohne dir zuvor irgendeinen Gedanken zum 
Prinzip zu machen.

Wie soll das Ganze aussehen? Grafisch oder AlphaNum?
Brauchst du Koordinaten für die Menüpunkte?
Brauchst du geometrische Navigation oder reicht es eindimensional?
Was sollen die Tasten bei den diversen Menüpunkte bewirken?
Sind Editierfelder dabei (wo du zwischen navigieren und Editieren 
unterscheiden mußt)?

Versuch erstmal, dir Klarheit über die von dir gewünschte Funktionalität 
zu verschaffen bevor du darüber nachdenkst, wie du es implementierst.

Dein Ansatz
(while(1)
{
  switch (m)
   ....
)

ist übrigens grottenschlecht weil prozedural gedacht. Menüs sind Dinge, 
die auf Ereignisse reagieren sollen und in der Zwischenzeit den 
Rechner nicht belasten sollen. Also wäre ein ereignisgesteuerter 
Denkansatz die weitaus bessere Wahl.

W.S.

von A. B. (funky)


Lesenswert?

quak nicht rum...das ist seine main-controller schleife

von Karl H. (kbuchegg)


Lesenswert?

Im Prinzip hat W.S. schon recht.
Nur dürfte das für den TO noch zu schwer sein, bzw. da findet er sich 
noch nicht zurecht.
Meistens ist es kein Problem, wenn man Menüs mittels Polling in der 
Hauptschleife macht. Wenn der Rest, der unbedingt laufen muss, in einen 
Timerinterrupt packt, dann ist das Gesamtsystem gut genug.

Das Hauptproblem, darüber sind wir uns alle einig, besteht darin, dass 
'Menü' denken und "Tastatur zur Hand nehmen und coden" der Weg ist, den 
er im Endeffekt nicht beschreiten sollte. Erst mal gehört ein Konzept 
her, dann eine Datenstruktur und erst dann wird mit Coden angefangen. 
Auf der anderen Seite wissen wir auch alle, dass man von Fehlschlägen 
auch was lernt. Auch Radfahren lernt man nicht dadurch, dass man vorher 
alles durchdenkt, sondern indem  man aufs Rad steigt und runterfällt.

von Emphator (Gast)


Lesenswert?

W.S. schrieb:
> ... und da fängst du als allererstes an, in die Tasten zu hauen und
> irgendetwa in C hinzuschreiben ohne dir zuvor irgendeinen Gedanken zum
> Prinzip zu machen.
> ...

Manche machen sich die Gedanken, indem sie ihre Idee erst mal in ein 
wenig Code strukturieren, und so ganz von selbst auf die (von Dir 
genannten) möglichen Probleme treffen. - Ob das Pseudocode oder C ist, 
ist dabei relativ egal.

Wenn man dan merkt, dass der Code zur Ausgabe eines Menüs immer ähnlich 
aussieht, kommt man dann schon von selbst auf den Gedanken, dass man mit 
Hilfe von Funktionen Code sparen kann.

Die einen planen/denken lieber in Prosa, die anderen in C. Soll doch 
jeder mit dem glücklich werden, was zu ihm oder zum Umfang des Projektes 
am besten passt, gerade bei Miniprojekten wie diesem.

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.