Forum: Mikrocontroller und Digitale Elektronik Allgemeine Codegestaltung von mehreren Programmen im Code


von Johannes (Gast)


Lesenswert?

Hallo,

ich weis die Überschrift klingt komisch aber ich meine was ganz
einfaches. An meinem Roboter soll ein LCD (funktioniert bereits) und 2
Taster angeschlossen werden. Man kommt zunächst in ein Menü kann dann
wählen (per Taster), kommt dann in Programm B oder alternativ Programm
C (beim anderen Taster), bei erneutem drücken wieder in Programm A.
Dabei bezeichnet "Programm" eine Ausgabe auf dem LCD und evtl
Steuerungsabläufe des Roboters.

Nur wie mache ich sowas überhaupt am besten. Irgendwie stehe ich da
etwas auf dem Schlauch wie ich diese Sprünge in den Programmen
realisieren könnte.
Ich hoffe mir kann das jemand recht anschaulich erklären (Bin noch neu
und unerfahren auf dem Gebiet!)

Vielen Dank !
mfg
Johannes

von Frank Linde (Gast)


Lesenswert?

Womit programmierst Du denn und auf welchem Microcontroller?

Gruß, Frank

von Johannes (Gast)


Lesenswert?

sorry ganz vergessen ... in c (avr-gcc)

von Oryx (Gast)


Lesenswert?

Hallo Johannes,
hoffentlich habe ich Deine Frage richtig verstanden.

Du hast dein Problem doch so beschrieben:

3 unterschiedliche Funktionen:
Der bietet sich ein Aufzählungstyp an (enum)
Der ist auf FUNKTION_LCD gesetzt.
in main wird ein switch mit den möglichen funktionen durchlaufen.
Solange Du nichts anderes auswählst halt Deine LCD.
Die Funktion LCD läuft solange, bis eine Taste gedrückt wird.
Bei diesem Tastendruck wird die globale Variable neue_funktion mit dem
wert der Funktion beschrieben und die LCD-Funktion wird verlassen.
Beim Durchlauf der switches in main wird nun die neue Funktion
aufgerufen.

Der Programmablauf verkompliziert sich noch etwas, wenn Du tatsächlich
mit der gleichen Taste aud der Funktion herausspringen wie
hineinspringen möchtest. Dann must Du noch eine Sperre gegen das
sofortige herausspringen einbauen. Ich mache in C++, also evtl. bool
usw. umschreiben.
Der nachstehende Code ist nicht compiliert oder gar getestet worden.
Nur als Anregung und Stichwortlieferant zu verstehen.


enum welche_funktion
{
  FUNKTION_LCD,
  FUNKTION_A,
  FUNKTION_B
};

welche_funktion neue_funktion;

bool tastenabfrage(void)
{
  bool retval = false;
  if (taste1 || taste2)
  {
    retval = true;
    if (taste1)
    {
      neue_funktion = FUNKTION_A;
    }else
    {
      if (taste2)
      {
        neue_funktion = FUNKTION_B;
      }
    }
  }
  return retval;
}

void lcd(void)
{
  while (!tastenabfrage())
  {
    // halt das Display verarbeiten
  }
}

void a_funktion(void)
{
  while (!tastenabfrage())
  {
    // halt Deine Funktion a ausführen
  }
  neue_funktion = FUNKTION_LCD;
}

// Die Funktion B genauso aufbauen

int main(void)
{
  for(;;)
  {
    switch (neue_funktion)
    {
      case FUNKTION_A:
        a_funktion();
        break;

      case FUNKTION_B:
        b_funktion();
        break;

      default:
        lcd();
        break;
    }
  }
}

Viel Spass
Oryx

von Johannes (Gast)


Lesenswert?

Okay das scheint mir n wirklich sehr brauchbares Konzept zu sein und
vielen dank für die mühe mit dem code, is echt gut verständlich. hab
echt selten so ne hilfsbereitschaft erlebt - 1A !!!

Riiiiießen Dankeschön !

mfg
johannes

von Peter D. (peda)


Lesenswert?

Solche Menüführungen kann man am besten mit einem großen switch machen.
Hier mal ein Beispiel (main.c51):

http://www.specs.de/users/danni/appl/soft/c51/thclock/index.htm


Peter

von Stefan May (Gast)


Angehängte Dateien:

Lesenswert?

Ich versuche das mal etwas theoretischer und vielleicht auch allgemeiner
darzustellen:

Zunächst mal einen endlichen Automaten aufstellen. In dem oberen Fall
benötigt man 3 Zustände: ST_START, ST_A und ST_B. Im Anhang der Automat
als Grafik. Folgende Tabelle gibt die Übergänge an (für jede Eingabe in
einem Zustand der Folgezustand):

Eingabe  ST_START     ST_A       ST_B

   1       ST_A     ST_START     ST_A
   2       ST_B       ST_B     ST_START

Man darf auch Folgezustände leer lassen, muß dann aber aufpassen.

Als nächstes werden alle Zustände in ein enum gepackt und der
Startzustand definiert.

  enum state { ST_START, ST_A, ST_B } = ST_START;

Nun kann man den Automaten sehr einfach mit switch Statements
implementieren:

for(;;) {
  switch(state) {
     case ST_START:
        switch(eingabe) {
           case 1:
               state = ST_A;
               break;
           case 2:
               state = ST_B;
               break;
        }
        break;
     case ST_A:
        switch(eingabe) {
           case 1:
               state = ST_START;
               break;
           case 2:
               state = ST_B;
               break;
        }
        break;
     case ST_B:
        switch(eingabe) {
           case 1:
               state = ST_A;
               break;
           case 2:
               state = ST_START;
               break;
        }
        break;
  }
}

Als Schmankerl kann man das ganze auch noch minimieren, da spare ich
mir jetzt aber die Ausführungen dazu.

ciao, Stefan.

P.S. Solche Grundtechniken lernt man entweder im Studium (Technische)
Informatik oder auch in jeder Programmiererausbildung.

von Jens (Gast)


Lesenswert?

ich habe mir da vorhin auch Gedanken drüber gemacht und bin auf das
gekommen.

Und zwar habe ich einen Taster den man lang oder kurz drücken kann.
Bei kurzen drücken will ich nur durch die Menüs scrollen. menu wird um
eins erhöht.
Bleibt der taster länger gedrückt, soll etwas spwezielles ausgeführt
werden. menu wird um 10 erhöht.

Hab jetzt nur die ersten Untermenüs ausgeführt. was da im einzelnen
passiert ist ja auch egal..
1
switch (menu){
2
      case 0: TID8("-KMH    ");break;
3
  case 1: menu=100;break; 
4
  case 10: kmhmess();break;
5
  case 20: menu=10;break; //falls lang gedrückt wird, passiert nichts
6
  case 11: kmhmax();break;
7
  case 21: maxkmh=0;break;
8
  case 12: kmhschnitt();break;
9
  case 13: TID8("ZURUECK ");break;
10
  case 23: menu=0;break;
11
  
12
      case 100: TID8("-KM     ");break;
13
  case 101: menu=200;break;
14
15
  
16
  case 200: TID8("ZEITEN  ");break;
17
  case 201: menu=0;break;

ist das so auch mödlich oder gar schlecht?
gruss
Jens

von Matthias Friedrich (Gast)


Lesenswert?

Switches sind zwar für den anfang ganz nett, aber für umfangreichere
menus eignen sich dann wohl eher callbacks. Vielfach verschachtelte
Menus sind mit einfachen swich-blocks nicht mehr sinnvoll zu handeln.
Das komplette Menu inklusive Aktionen kann man dann in ein großes Array
packen und hat so alle menu-spezifischen Daten an einem Fleck (->
Information Hiding).

Gruß,
Matthias

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.