Forum: Mikrocontroller und Digitale Elektronik welche schleife?


von lehrling (Gast)


Lesenswert?

Hallo zusammen.
Folgendes Problem:

void Mainmenu3 (int arg){
  ClearScreen();
  LCDSoftText("Temperatur",0,0,BLACK);
  uint16_t mess1=0;
  uint16_t mess2=0;
  char puffer1[16];
  char puffer2[16];
  while(1){
    mess1 = adc_messung(0);
    itoa(mess1,puffer1,10);
    LCDSoftText(puffer1,0,54,BLACK);
  }
  tasterback();
}

void tasterback(void){
  while(1){
    if (get_key_short(1<<T6)){
      ClearScreen();
      LCDSoftText("Hauptmenu",0,0,BLACK);
      DoMenu (ARRAY_SIZE (MainMenu), MainMenu);
    }
  }
}

In der Funktion(mainmenu3) soll ständig eine ADC-Messung erfolgen.
Durch die Funktion(tasterback) soll die ADC-Messung unterbrochen werden.
Wie kann ich das am besten schreiben.?

Danke schonmal...

: Verschoben durch User
von ich (Gast)


Lesenswert?

Schon mal von Hilfsmitteln wie einem Programmablaufplan gehört?

Deine Frage sollte sich dann von alleine klären.

von Bitflüsterer (Gast)


Lesenswert?

Ich würde Dir einen Schritt zurück von dem geposteten Problem empfehlen 
und zunächst einmal diese Form der Schleife
1
  while(1){
2
    abc();
3
  }
4
  xyz ();

noch einmal genauer betrachten. abc () und xyz () seien einfach zwei 
beliebige Funktionen.

Sie beschreibt eine "Endlosschleife". Was heisst das aber nun genau?
Es heisst, das die Funktion abc () "endlos", d.h. immer wieder 
aufgerufen wird und das die Funktion xyz () "niemals" aufgerufen wird.
Die Endlosschleife wird dadurch erzeugt, das die Bedingung "1" immer 
wahr ist.

Soweit klar?

Was heisst das nun wieder für den von Dir geposteten Quelltext?

Es heisst, das die erste Schleife
1
  while(1){
2
    mess1 = adc_messung(0);
3
    itoa(mess1,puffer1,10);
4
    LCDSoftText(puffer1,0,54,BLACK);
5
  }
6
  tasterback();

immer und immer wieder (endlos) ausgeführt wird, und das die Funktion 
"tasterback ()" _niemals ausgeführt wird.
Das ist sicherlich nicht Deine Absicht.

Genauso wird in der Funktion "tasterback ()" (kannst Du mir zu Gefallen 
mal den Namen ändern und Dich entweder für Englisch oder Deutsch 
entscheiden? Oder geht es um die "Back", die Küche auf einem Schiff?)
eine Endlosschleife beschrieben.
1
  while(1){
2
    if (get_key_short(1<<T6)){
3
      ClearScreen();
4
      LCDSoftText("Hauptmenu",0,0,BLACK);
5
      DoMenu (ARRAY_SIZE (MainMenu), MainMenu);
6
    }
7
  }

D.h. die Funktion würde, falls sie denn jemals aufgerufen wird, _niemals 
wieder verlassen. Das ist auch nicht Deine Absicht, wie ich annehme.

Du musst jetzt mal einen gedanklichen Schritt weg von den 
Endlos-Schleifen machen und die Bedingung in while kreativ benutzen.
Ich sage Dir das nicht vor, weil ich meine, dass Deine eigenen 
Bemühungen zu einem wesentlich nachhaltigeren Aha-Erlebnis führt.

Falls es aber garnicht geht, schreib noch mal.

von lehrling (Gast)


Lesenswert?

Das ist ja mein Problem, dass er nie aus der Endlosschleife springt. Es 
würde ja ganz einfach gehen, aber dann misst das Programm nur einmal den 
ADC-Wert.
Das soll er nicht.

Das war ja jetzt eigentlich auch meine Frage, wie ich aus der 
Endlosschleife wieder heraus komme. Bzw, diese mit tasterback abbrechen 
kann

und sorry für das deutsch/englisch

von Bitflüsterer (Gast)


Lesenswert?

>Das war ja jetzt eigentlich auch meine Frage, wie ich aus der
>Endlosschleife wieder heraus komme.

Nein. Deine Ausgangsfrage lautete: "Welche Schleife?

Dein Problem ist aber nicht eigentlich die Frage welche Art von Schleife 
Du anwenden sollst, sondern wie Du die Bedingung formulierst.

Deswegen meine Erklärung. Was folgt aus meiner Antwort: Du musst die 
Bedingung anders gestalten! Das überlege Dir mal. Ich möchte Dir das 
nicht einfach vorsagen. Aber ich gebe doch mal eine Tip.
while wird mit der Bedingung "1" zu einer Endlosschleife. Wie wird dann 
ein while zu einer Niemals-Schleife? Was ist sozusagen eine 
Manchmal-Schleife? Wie sieht die aus?

>und sorry für das deutsch/englisch
Mit Schuld hat das nichts zu tun. Es liest sich einfach grauslich.

von Achim H. (anymouse)


Lesenswert?

Ich würde vorschlagen, die Funktion "tasterback" so umzubauen, dass sie 
einen Rückgabewert liefert, an dem man erkennen kann, ob die Schleife 
abgebrochen werden soll oder nicht.

Und dann diese Funktion in die Überprüfung der Schleifenbedingung 
einzubauen: Also statt "while(1) { ... }" ein "while( tasterback() ) { 
... }". Dazu solltest Du aber auch die Endlosschleife in der 
tasterback-Funktion auflösen.

Alternativ könntest Du auch mitten im Schleifenrumpf diese Funkion 
abfragen und anhand des Ergebnis ein Flag setzen, welches dann später 
den Abbruch veranlasst:
1
boolean loop = true;
2
while( loop ) {
3
   ...
4
   if ( tasterback() == 13 ) {
5
      loop = false;
6
   }
7
}

P.S.: Bei manchen Sprachen gibt es für Schleifen noch eine 
"break"-Anweisung.

von Bitflüsterer (Gast)


Lesenswert?

Na da hast Du aber Glück gehabt, das noch ein Vorsager daherkam.
Viel Erfolg.

von 123 (Gast)


Lesenswert?

Moin

Ich glaub du hast grundlegende Probeme des system aufbaus / Programm 
aufbaus. Ich vermute selbst wenn es funktionieren würde, hättest du 
irgend wann einen stacoverflow. DoMenu wird vermutlich Menue3 aufrufen, 
der dann duMenu wirder aufruft.

Du hast ein sub menue das immer wieder einen wert aktualisieren soll bis 
eine taste gedrückt wird.

so. dann bauen wir mal um.
1
uint32_t doSomething( uint32_t param)
2
{
3
   uint32_t loop = true;
4
   uint32_t ret = 0;
5
6
   do
7
   {
8
      updateValue();    
9
10
      loop = ! isKeyPresssed();
11
   } while (loop)
12
13
14
   return ret;
15
}



ps ich würd sagen falsches forum...

von ge-nka (Gast)


Lesenswert?

void Mainmenu3 (int arg){
  ClearScreen();
  LCDSoftText("Temperatur",0,0,BLACK);
  uint16_t mess1=0;
  uint16_t mess2=0;
  char puffer1[16];
  char puffer2[16];
  uint16_t messen=1;
  while(messen){
    mess1 = adc_messung(0);
    itoa(mess1,puffer1,10);
    LCDSoftText(puffer1,0,54,BLACK);

   tasterback();
  }

}

void tasterback(void){
    if (get_key_short(1<<T6)){
      ClearScreen();
      LCDSoftText("Hauptmenu",0,0,BLACK);
     DoMenu (ARRAY_SIZE (MainMenu), MainMenu);

>      messen=0;
>  }
>}

von 123 (Gast)


Lesenswert?

und wieder ne endlosschleife.

oder wo wird messen auf 0 gesetzt?
2 tens den scope von messen nicht beachtet.

von lehrling (Gast)


Lesenswert?

aber eigentlich müsste das doch gehen:

void Mainmenu3 (int arg){
  ClearScreen();
  LCDSoftText("Temperatur",0,0,BLACK);
  uint16_t mess1=0;
  uint16_t mess2=0;
  char puffer1[16];
  char puffer2[16];
  while(x){
      mess1 = adc_messung(0);
      itoa(mess1,puffer1,10);
      LCDSoftText(puffer1,0,54,BLACK);
      tasterback();
  }

}

void tasterback(void){
  while(1){
    if (get_key_short(1<<T6)){
      ClearScreen();
      LCDSoftText("Hauptmenu",0,0,BLACK);
      DoMenu (ARRAY_SIZE (MainMenu), MainMenu);
      x=0;
    }
    else{
      x=1;
    }
  }
}

x=1, führt die while aus, springt irgendwann in tasterback, der 
sagt(wenn nicht gedrückt)x ist immer noch eins.

ist doch logisch oder.? aber warum macht er das nicht.? der misst nur 
einmal und dann wars das

von 123 (Gast)


Lesenswert?

ja ja ja die blutigen anfänger und die blöden compiler.

wo ist X definiert? wieso sehe ich immer noch ein while(x)?
ggf könne ein definiertes break an einer stelle helfen.
ggf mal über return values nachdenken.

und was DoMenu macht hast du uns auch nicht erzählt. ich vermute mal das 
wird eine rekursive katastrophe.

von lehrling (Gast)


Lesenswert?

x ist in der datei als 1 definiert. wie es ge-nka mit "messen" 
geschrieben hat.

domenu hat nichts zusagen, das löscht nur das lcd und listet mir wieder 
meine menupunkte auf...

von Bitflüsterer (Gast)


Lesenswert?

Aber ich bitte Dich. Das ist ja geradezu lächerlich.
Was eine Definition in C ist, solltest Du natürlich wissen, bevor Du 
solche Fragen stellst. Und auch, was eine Schleife ist und was die 
Bedingung für eine Rolle spielt.

Aber nur Geduld. Irgendein Vorsager wird schon daherkommen.

von lehrling (Gast)


Lesenswert?

ich meinte deklariert.
und klar weiß ich, was eine schleife ist.

versteh grad nicht ganz, womit ich mich so "lächerlich" mach

von Bitflüsterer (Gast)


Lesenswert?

>ich meinte deklariert.
Nein. Meintest Du nicht.

>und klar weiß ich, was eine schleife ist.
Nein. Weisst Du nicht.

Ich bitte Dich, höflich und in aller Form, lies erstmal gründlich ein 
C-Buch von Anfang an. Vollziehe die Beispiel nach. Erst dann versuche 
eigenen Code zu schreiben.

von Kaj (Gast)


Lesenswert?

Tu dir selbst einen Gefallen und lies bitte ein C-Buch! Was anderes 
kann man dazu nicht sagen.
Wenn Du jetzt sowas antwortest wie "Ja hab ich aber, und ich kann voll 
super Programmieren und so..." Nein, hast du nicht, und kannst du 
nicht! Das sieht hier jeder! Lies ein C-Buch, besonders was Schleifen 
und gültigkeitsbereiche von Variablen angeht, dann solltest du 
zwangsläufig dein Problem von alleine erkennen. Hilfe zur selbst Hilfe!

Grüße

von 123 (Gast)


Lesenswert?

So wies aussieht (oder auch nicht) vermute ich das x global definiert 
ist.

Und wenn wir nicht weiter wissen, dann machen wir das halt global das 
jeder dran kommen kann. (auch wenn es anders gehen würde)

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

lehrling schrieb:
> und klar weiß ich, was eine schleife ist.
>
> versteh grad nicht ganz, womit ich mich so "lächerlich" mach

anscheinend hast du das mit der Schleife doch noch nicht so voll 
verinnerlicht:

lehrling schrieb:
> void tasterback(void){
>   while(1){
>     if (get_key_short(1<<T6)){
>       ClearScreen();
>       LCDSoftText("Hauptmenu",0,0,BLACK);
>       DoMenu (ARRAY_SIZE (MainMenu), MainMenu);
>       x=0;
>     }
>     else{
>       x=1;
>     }
>   }
> }

vereinfacht heißt das:

void tasterback(void){
while(1){
   if (irgendwas zutrifft) mache "irgendwas zutreffendes"
   else (mache was anderes)
}

das while(1) heißt: Mache solange bis die Erde untergeht....

d.h. sobald einmal deise Funktion "tasterback" von irgendwo her 
aufgerufen wird, versinkt dein Programmablauf in dieser Funktion und 
wartet auf den Weltuntergang. Erst dann wird der weitere Programmablauf 
durchgeführt.



Nachtrag: So sieht eine Taster-Back in Hardware aus ;-)

http://m.unibw.de/etti4/Lehre/Abschlussarbeiten/abgeschlossen/entwicklung-einer-bewegungssteuerung-fuer-das-autonome-radfahrzeug-panda/taster-back.png/view

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

Das  while(1) wird auf einem µC bei main benutzt, da es dort kein 
Betriebssystem gibt, zu dem das Programm am Ende zurückkehren kann.

In einer normalen Funktion ist es nur sehr sehr selten sinnvoll.

von ge-nka (Gast)


Lesenswert?

Man kann ja sein Programm in etwa so strukturieren, wenn man mit 
While-Schleifen arbeiten will.
1
void main (void){
2
 bool messen=1;
3
 bool etwas_anderes=1;
4
 while(1){ // zyklisch beide while(messen), while(etwas_anderes) ausführen.
5
   while(messen){
6
    irgend_was_machen();
7
    pruefen_ob_messen_abbrechen();     // prüfen, ob Schleife abgebrochen werden soll
8
   }
9
10
   while(etwas_anderes){
11
    irgend_etwas_anderes_machen();
12
    etwas_anderes=0;                // Schleife abbrechen
13
   }
14
15
 }
16
17
}
18
19
void irgend_was_machen(void){
20
   
21
}
22
void irgend_etwas_anderes_machen(void){
23
   
24
}
25
void pruefen_ob_messen_abbrechen(void){
26
 
27
    if (abbruch){
28
      messen=0;
29
    } 
30
}

von Georg G. (df2au)


Lesenswert?

Etwas einfacher, dafür (hoffentlich) lauffähiger:

void main (void){
   bool messen=1;

   while(1){ // messen bis Abbruch, dann einmal was_anderes, wieder 
messen ausführen.
   while(messen){
      irgend_was_machen();
      pruefen_ob_messen_abbrechen();     // prüfen, ob Schleife 
abgebrochen werden soll
      }
// hier kommen wir nur an, wenn abgebrochen wurde
   irgend_etwas_anderes_machen();
   messen = 1; // wieder mit messen weitermachen
   }

 void irgend_was_machen(void){

 }
 void irgend_etwas_anderes_machen(void){

 }
 void pruefen_ob_messen_abbrechen(void){

     if (abbruch){
       messen=0;
     }
 }

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.