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
Schon mal von Hilfsmitteln wie einem Programmablaufplan gehört? Deine Frage sollte sich dann von alleine klären.
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.
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
>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.
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.
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...
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; > } >}
und wieder ne endlosschleife. oder wo wird messen auf 0 gesetzt? 2 tens den scope von messen nicht beachtet.
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
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.
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...
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.
ich meinte deklariert. und klar weiß ich, was eine schleife ist. versteh grad nicht ganz, womit ich mich so "lächerlich" mach
>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.
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
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)
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
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.
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 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.