Forum: Mikrocontroller und Digitale Elektronik while-Schleife vorzeitig verlassen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Wolle G. (wolleg)


Bewertung
-1 lesenswert
nicht lesenswert
Mein Projekt befasst sich mit der Regelung der Temperatur mittels 
Thermostatventil.
Im Prinzip läuft die Regelung als PI-Regler schon nach meinen 
Vorstellungen.
Ein Problem  besteht allerdings darin, dass sich das Programm aufhängt, 
wenn das Ventil bis zur Endstellung fahren will, aber der Anschlag 
vorzeitig ereicht wird.
Verantwortlich mache ich die while schleife in der Funktion

void ventil_schliessen_regler(void)
{
ZU=1;           //zähler zählt herunter
while(hub >(ventilstellung_alt-umdrehung_zu ))
P3OUT &=~BIT0; // ZU-fahren
P3OUT |=BIT0;  // ZU-fahren HALT
ZU=0;

Zur Erklärung: Der hub entspricht der Anzahl der Umdrehungen eines 
Zahnrades des Getriebes.
Beim Schließen wird herunter gezählt.
Alle 8s wird die Hubstellung (ventilstellung_alt) abgefragt und über die 
Reglergleichung die Anzahl der Umdrehungen (umdrehung_zu) berechnet, die 
notwendig sind, um die neue Hubstellung anzufahren. Bisher alles gut.
Das Problem des Aufhängens tritt m. E. dann auf, wenn der Lauf durch 
Anschlag am Hubende  nicht bis zum Ende erfolgen kann.
Gibt es eine Möglichkeit, die Schleife vorzeitig zu verlassen, obwohl 
die errechnete Hubverstellung wegen Anschlag nicht erreichbar ist und 
deshalb die while-schleife nicht beendet wird.
Versuche mit Strommessungen waren bei mir  (programmiertechnisch)  nicht 
erfolgreich.
Aber vielleicht hat jemand eine Idee, wie das Aufhängen vermieden werden 
kann.
fragt ein Programmierlaie

: Bearbeitet durch User
von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
wolle g. schrieb:
> Aber vielleicht hat jemand eine Idee, wie das Aufhängen vermieden werden
> kann.

Eine while-Schleife wird genau dann unterbrochen, wenn die Bedingung 
nicht mehr erfüllt ist. Also schreibe die Abbruchbedingung mit rein.

von Stefan ⛄ F. (stefanus)


Bewertung
1 lesenswert
nicht lesenswert
Mit dem Schlüsselwort "break" kannst du die Schleife vorzeitig 
verlassen. Mit "continue" kannst du den aktuellen Durchlauf abbrechen 
und mit dem nächsten (von oben an) fortfahren.

von Mach (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Ein Timeout ist fuer blockierend wartende Routienen immer wichtig.

von Prozessor Dokter Schmunz (Gast)


Bewertung
6 lesenswert
nicht lesenswert
Wolfgang schrieb:
> Eine while-Schleife wird genau dann unterbrochen, wenn die Bedingung
> nicht mehr erfüllt ist. Also schreibe die Abbruchbedingung mit rein.

Quatsch. Das sind Weicheierschleifen.

Männerschleifen werden SO geschrieben:
1
While(1) {
2
  if(Abbruchbedingung)
3
     {break;}
4
}


http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/008_c_kontrollstrukturen_011.htm#mjd28218b0b10f4b2de0cf49a68ed3a79a

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Prozessor Dokter Schmunz schrieb:
> Männerschleifen werden SO geschrieben:While(1) {
>   if(Abbruchbedingung)
>      {break;}
> }

Schon wieder so ein C-Konstrukt, das irgendwo mitten aus einem Block 
rausspringt ...

von ... (Gast)


Bewertung
0 lesenswert
nicht lesenswert
wolle g. schrieb:
1
while(hub >(ventilstellung_alt-umdrehung_zu ))
2
P3OUT &=~BIT0; // ZU-fahren

Was denkst Du, was hier passiert?

von Prozessor Dokter Schmunz (Gast)


Bewertung
6 lesenswert
nicht lesenswert
Wolfgang schrieb:
> Schon wieder so ein C-Konstrukt, das irgendwo mitten aus einem Block
> rausspringt ...

Hab doch geschrieben, nichts für Weicheier. Also bleib devot und lies, 
was wir Männer schreiben.

von Wolle G. (wolleg)


Bewertung
0 lesenswert
nicht lesenswert
... schrieb:
> Was denkst Du, was hier passiert?

Ich weiß zwar nicht, was Du damit meinst, aber solange der Hubanschlag 
nicht erreicht ist, wird die berechnete Hubstellung angefahren.

von Prozessor Dokter Schmunz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
wolle g. schrieb:
> Ich weiß zwar nicht, was Du damit meinst,

Ganz einfach: Hier gibt es Antworter, die wissen noch weniger als der 
Frager ;)

von ... (Gast)


Bewertung
1 lesenswert
nicht lesenswert
... schrieb:
> hub >(ventilstellung_alt-umdrehung_zu

Woher kommen die Variablen?

Prozessor Dokter Schmunz schrieb:
> Ganz einfach: Hier gibt es Antworter, die wissen noch weniger als der
> Frager ;)

Genau ;)
Im Moment kenne ich nur den Codeschnipsel.

Und wenn der TO wirklich in einer Schleife immer wieder ein Bit löscht, 
welches schon längst gelöscht ist, denke ich mir, dass es im restlichen 
Programm ähnlich ausieht.

von Prozessor Dokter Schmunz (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
... schrieb:
> Und wenn der TO wirklich in einer Schleife immer wieder ein Bit löscht,
> welches schon längst gelöscht ist, denke ich mir

Manche Ecken bestehen nur aus Fett. Aber nur Joseph Beuys konnte damit 
Geld machen. Es liegt also nicht am Fett, sondern am User.

Anderer Vorschlag, frei nach Beuys:
1
while(1) {
2
  if(Abbruchbedingung)
3
     {digitalWrite(PIN, 1);} // PIN ist ohne Widerstand mit Masse verbunden
4
}
Wenn die Abbruchbedingung erfüllt ist, wird ein Kurzschluss erzeugt. Der 
Prozessor raucht ab, und die Schleife gilt damit als verlassen. In 
meiner Funktion als Prozessor Dokter Schmunz darf ich das zwar nicht 
schreiben, aber Beuys, wäre er Programmierer, würde das tun. Kurz darauf 
würden das vermutlich alle tun.

von Wolle G. (wolleg)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
... schrieb:
> Im Moment kenne ich nur den Codeschnipsel.

deshalb als Anhang mal das gesamte Hauptprogramm, auch wenn es 
vielleicht nicht allen Anforderungen entsprechen sollte.
Es enthält zusammen mit *.h Dateien u.a.:
Aufzeichnung von Daten auf SD-Karte
Uhrzeit
Temperaturmessung
Anzeige auf Flüssigkristallanzeige

Vielleicht könnte jemand die Abruchbedingungen an der richtigen Stelle 
einfügen.

mit break
oder if (ADW_P6_3 > 24)... //steht für Stromstärke am Anschlag ZU
hatte ich es versucht --> Programm reagierte nicht mehr
deshalb mein Hilferuf

: Bearbeitet durch User
von Code Betrachter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
wolle g. schrieb:
> deshalb als Anhang mal das gesamte Hauptprogramm

aaaahhhh jetzt ja

von Apollo M. (Firma: @home) (majortom)


Bewertung
-1 lesenswert
nicht lesenswert
wolle g. schrieb:
> Vielleicht könnte jemand die Abruchbedingungen an der richtigen Stelle
> einfügen.

ich schau mal wo platz ist ...
gehts noch?!


mt

von Code Betrachter (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
wolle g. schrieb:
> Vielleicht könnte jemand die Abruchbedingungen an der richtigen Stelle
> einfügen.

Bei solch chaotischer Tabulierung ..... nein danke.

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
1
void ventil_schliessen_regler(void)
2
      { 
3
       ZU=1;  //zähler zählt herunter
4
       while(hub >(ventilstellung_alt-umdrehung_zu ))
5
       {
6
       P3OUT &=~BIT0;  // ZU-fahren
7
if (Ventil doch schon Zu, wie auch immer das bemerkt wird ohne es in der Schleife abzufragen) break;
8
       }
9
       P3OUT |=BIT0;
10
       ZU=0;
11
      }

von Paul P. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
wenn Du ihm diesbezüglich nicht helfen willst, spar dir doch einfach 
deinen kommentar!

von leo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
wolle g. schrieb:
> deshalb als Anhang mal das gesamte Hauptprogramm,
1
...
2
void pause(void);
3
void pause1(void);
4
void pause2(void);
5
...

Du wiederholst oft aehnlichen Code. Statt 3 Funktionen kann du eine 
verwenden, die Wartezeit uebergibst du als Parameter. Damit wird der 
Code viel kuerzer und lesbarer/uebersichtlicher.

leo

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Wo kommt eigentlich hub her? Sehe dafür keine Deklaration... Und wenn 
sollte da ein volatile bei stehen.

von Wolle G. (wolleg)


Bewertung
0 lesenswert
nicht lesenswert
Tim T. schrieb:
> Wo kommt eigentlich hub her? Sehe dafür keine Deklaration... Und
> wenn
> sollte da ein volatile bei stehen.
Deklaration ist in DS10-g0107-LMK62-SD.h als volatile int  enthalten

Deinen Vorschlag habe ich wie folgt eingebaut:

void ventil_schliessen_regler(void)
      {
       ZU=1;  //zähler zählt herunter
       while(hub >(ventilstellung_alt-umdrehung_zu ))
       P3OUT &=~BIT0; // ZU-fahren
       if ( ADW_P6_3 > 24) break;      //hier Zeile 248
       P3OUT |=BIT0;  // ZU-fahren HALT
       ZU=0;
       }

Fehlermeldung: DS10-g0122-PID.c:248: break statement not within loop or 
switch

von Tim T. (tim_taylor) Benutzerseite


Bewertung
1 lesenswert
nicht lesenswert
Langsam wirds lächerlich:
1
       while(hub >(ventilstellung_alt-umdrehung_zu ))
2
{
3
       P3OUT &=~BIT0; // ZU-fahren
4
       if ( ADW_P6_3 > 24) break;      //hier Zeile 248
5
}

KLAMMERN!

von leo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Mein Editor wuerde dein Codesnippet so editieren:
1
void ventil_schliessen_regler(void)
2
{
3
  ZU=1;  //zähler zählt herunter
4
  while(hub >(ventilstellung_alt-umdrehung_zu ))
5
    P3OUT &=~BIT0; // ZU-fahren
6
  if ( ADW_P6_3 > 24) break;      //hier Zeile 248
7
  P3OUT |=BIT0;  // ZU-fahren HALT
8
  ZU=0;
9
}

Faellt der was auf?
Formatier deinen Code, streich Duplikate usw.

HTH leo

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Tim T. schrieb:
> Langsam wirds lächerlich:
>
>
1
>        while(hub >(ventilstellung_alt-umdrehung_zu ))
2
> {
3
>        P3OUT &=~BIT0; // ZU-fahren
4
>        if ( ADW_P6_3 > 24) break;      //hier Zeile 248
5
> }
6
>
>
> KLAMMERN!

Woher ADW_P6_3 den AKTUELLEN Wert hat, steht dann auch wieder in den 
Sternen. Wie kommt man eigentlich als so minderbegabt auf die Idee so 
ein Projekt zu machen? Dir fehlt es ja anscheinend an allem...

von Apollo M. (Firma: @home) (majortom)


Bewertung
0 lesenswert
nicht lesenswert
Tim T. schrieb:
> als so minderbegabt

oder einfach nur talentfrei! ... ist hier doch die mehrheit.
das du und andere sich hier reinhängen wundert mich.


mt

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Apollo M. schrieb:
> Tim T. schrieb:
>> als so minderbegabt
>
> oder einfach nur talentfrei! ... ist hier doch die mehrheit.
> das du und andere sich hier reinhängen wundert mich.
>
>
> mt

Ja, war wiedermal doof, dachte es wäre schon auf der Zielgeraden aber in 
Wirklichkeit gehts immer weiter in den Abgrund...

von Andreas H. (ahz)


Bewertung
0 lesenswert
nicht lesenswert
Prozessor Dokter Schmunz schrieb:
> Also bleib devot und lies,
> was wir Männer schreiben.

n1
Ymmd

/regards

von PittyJ (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Freitag abends schaue ich die Heute-Show.
Und wenn ich Montag morgens etwas zum Lachen brauche, dann kann ich 
diesen Thread nehmen. So fängt sich Woche fröhlich an.
Die Karnvevalszeit ist schon schön, selbst hier setzen sich die Leute 
Pappnasen auf.

von äxl (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> fragt ein Programmierlaie

Ging ja wieder heiss her hier, gestern abend.
Dafür, dass er 'n Laie ist auf dem Gebiet, geht das doch. Etwas holperig 
und ungelenk vielleicht.
Aber trotzdem muss man hier nicht soo arrogant reagieren. Schade...

von Wolle G. (wolleg)


Bewertung
0 lesenswert
nicht lesenswert
Wahrscheinlich war ich diesmal zur falschen Zeit am falschen Ort, denn 
normalerweise wird hier im Forum zumeist konkret auf  Fragen 
eingegangen.
Unabhängig von seinen "sinnlosen Kommentaren" führten die 
Programmschnipsel von Tim T. letztendlich zum Erfolg.
Auch wenn es "nur" die Klammern waren.
So was sieht nun mal ein Laie nicht, auch wenn es "lächerlich" 
erscheinen soll.
Vielen Dank.
Hier die aus meiner Sicht geänderte entscheidende Funktion.

void ventil_schliessen_regler(void)
      {
       ZU=1;                      //zähler zählt herunter
       while(hub >(ventilstellung_alt-umdrehung_zu ))
       {
       ADW_lesen();               // Stromaufnahmemessung übernehmen
       if ( ADW_P6_3 > 80) break; // ADW_6_3=Kanal 6.3; Stromaufnahme
       // wird am Anschlag überschritten; while-Schleife wird verlassen
       P3OUT &=~BIT0;             // ZU-fahren
       }
       P3OUT |=BIT0;              // ZU-fahren HALT
       ZU=0;
       }

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Wobei aber ADW_P6_3 WÄHREND der Schleife nicht aktualisiert wird, also 
entweder ist die Stromaufnahme schon vor der Schleife zu hoch und damit 
als Abbruchbedingung vorhanden oder es wirkt sich in der Schleife auch 
nicht aus...

von Christoph B. (bodi069)


Bewertung
0 lesenswert
nicht lesenswert
äxl schrieb:
>> fragt ein Programmierlaie
>
> Ging ja wieder heiss her hier, gestern abend.
> Dafür, dass er 'n Laie ist auf dem Gebiet, geht das doch. Etwas holperig
> und ungelenk vielleicht.
> Aber trotzdem muss man hier nicht soo arrogant reagieren. Schade...

Ich stimme dir zu äxl. Es ist schade, traurig und dumm. Jeder ist Mal 
Laie und Mal Fachmann auf einem Gebiet. Mit etwas mehr Verständnis 
füreinander würd's hier glatt noch Spass machen ... . Wahrscheinlich zu 
gut für einige.

von Wolle G. (wolleg)


Bewertung
0 lesenswert
nicht lesenswert
Tim T. schrieb:
>Wobei aber ADW_P6_3 WÄHREND der Schleife nicht aktualisiert wird,

Hat das programmiertechnische Gründe oder liegt es an der Arbeitsweise 
des MSP430F1611?
Ich hatte eigentlich gedacht, dass der AD-wandler die Abtastung der 
Kanäle mit
ADC12CTL0 |= ADC12SC+ ENC;
ständig wiederholt  und dass mit
ADW_P6_3 = ADC12MEM3;
der Speicher ADC12MEM3 abgefragt wird und damit ADW_P6_3 auch beim 
Durchlaufen der while-Schleife aktuell ist.

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
wolle g. schrieb:
> ADW_P6_3 = ADC12MEM3;

Das ist ne Zuweisung, mehr nicht. Und wann wird die in der Schleife 
gemacht? Richtig, garnicht.

von Roland E. (roland0815)


Bewertung
0 lesenswert
nicht lesenswert
Tim T. schrieb:
> Wobei aber ADW_P6_3 WÄHREND der Schleife nicht aktualisiert wird, also
> entweder ist die Stromaufnahme schon vor der Schleife zu hoch und damit
> als Abbruchbedingung vorhanden oder es wirkt sich in der Schleife auch
> nicht aus...

Das aktualisieren passiert neben der Main() im interrupt.

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Roland E. schrieb:
> Tim T. schrieb:
>> Wobei aber ADW_P6_3 WÄHREND der Schleife nicht aktualisiert wird, also
>> entweder ist die Stromaufnahme schon vor der Schleife zu hoch und damit
>> als Abbruchbedingung vorhanden oder es wirkt sich in der Schleife auch
>> nicht aus...
>
> Das aktualisieren passiert neben der Main() im interrupt.

Nö, ADW_P6_3 wird nur in der ADW_lesen() Funktion zugewiesen und die 
wird nirgends aufgerufen...

: Bearbeitet durch User
von Richard H. (richard_h27)


Bewertung
0 lesenswert
nicht lesenswert
while-Schleife vorzeitig verlassen:
unbedingt fristgerecht kündigen, sonst muss man ein weiteres Jahr drin 
bleiben.

von Wolle G. (wolleg)


Bewertung
0 lesenswert
nicht lesenswert
Roland E. schrieb:
>Das aktualisieren passiert neben der Main() im interrupt.
Könnte das hier so gemeint sein? (aus  SLAU049E)

Repeat-Sequence-of-Channels Mode
A sequence of channels is sampled and converted repeatedly. The ADC
results are written to the conversion memories starting with the 
ADC12MEMx defined by the CSTARTADDx bits. The sequence ends after the 
measurement
of the channel with a set EOS bit and the next trigger signal re-starts 
the
sequence. Figure 17−9 shows the repeat-sequence-of-channels mode.

wolle g. schrieb:
>> ADW_P6_3 = ADC12MEM3;

>Das ist ne Zuweisung, mehr nicht. Und wann wird die in der Schleife
>gemacht? Richtig, garnicht.
Gibt es eine Lösung, um an den aktuellen Wert von ADW_P6_3  innerhalb 
der while-Schleife zu kommen?

: Bearbeitet durch User
von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
> wolle g. schrieb:
> Gibt es eine Lösung, um an den aktuellen Wert von ADW_P6_3  innerhalb
> der while-Schleife zu kommen?

Argh, das ist echt so traurig.

ADW_P6_3 hat NATÜRLICH immer seinen aktuellen Wert, es ist ja nur ein 
verdammter int, geht auch garnicht anders, nur das ist überhaupt nicht 
was du willst!

Du willst nicht den aktuellen Wert von ADW_P6_3 wissen sondern den 
aktuellen Wert was bei der ADC Wandlung rausgekommen ist und jetzt 
Quizfrage, wo steht diese Information wohl?

Ob du den dann noch ADW_P6_3 zuweisen möchtest oder ob du ihn direkt 
nutzen willst ist dabei total egal...

von Eric B. (beric)


Bewertung
0 lesenswert
nicht lesenswert
wolle g. schrieb:
> ... schrieb:
>> Im Moment kenne ich nur den Codeschnipsel.
>
> deshalb als Anhang mal das gesamte Hauptprogramm, auch wenn es
> vielleicht nicht allen Anforderungen entsprechen sollte.

Nein, das ist nicht das gesamte Programm.
* Was verbirgt die includierte C-Datei namens "DS10-gP12-SD_MAINTI.c" ?
* Sind da vielleciht die Funktionen temp_messung_starten() und 
FKA_einrichten() definiert?

Ausserdem: Die pauseX() Funktionen werden wenn du Glück oder Pech hast, 
vom Compiler komplett wegoptimiert und bewirken allen das gleich, 
nämlich NIX. Du hast einen Timer - benutzt den!

von max123 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Das alte Pferd

XXX:
goto

läuft noch. Und sogar in der Bibel (K&R) wird es für tief
verschachtelten Schleifen empfohlen.
( Gültig für C/C++ und Arduino)

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
max123 schrieb:
> Hallo,
>
> Das alte Pferd
>
> XXX:
> goto
>
> läuft noch. Und sogar in der Bibel (K&R) wird es für tief
> verschachtelten Schleifen empfohlen.
> ( Gültig für C/C++ und Arduino)

Praktisch um dem toten Pferd den Rest zu geben? Gotos sind fast immer 
Unsinn, das einzige wofür ich die z.B. benutze ist um bei Treiber 
initialisierungen Stufenweise zu deinitialisieren wenn was schief läuft. 
Hier haben sie jedenfalls garnix zu suchen.

von Wolle G. (wolleg)


Bewertung
0 lesenswert
nicht lesenswert
Eric B. schrieb:
> Ausserdem: Die pauseX() Funktionen werden wenn du Glück oder Pech hast,
> vom Compiler komplett wegoptimiert und bewirken allen das gleich,
> nämlich NIX. Du hast einen Timer - benutzt den!

Das hat aber nichts mit dem Thema while ... zu tun.
Aber wenn man evtl. mein Programm verbessern möchte, dann bitte mit 
konkreten Zeilen (einschließlich Klammern usw.)

>Du hast einen Timer - benutzt den!
Damit kann ich z.B. in diesem Fall gar nichts anfangen.

Nach der oben gezeigten Korrektur läuft man Programm, wobei jetzt noch 
offen ist, welcher Wert der Stromaufnahme für den Abbruch der Schleife 
verwendet wird. Während des Lauf der while-Schleife oder vor Beginn der 
Schleife.
M.M. nach müsste es der ADW_P6_3 Wert sein, der während des 
Schleifenlaufs vom AD_Wandler (ADCM12EM3) gemessen wird.

: Bearbeitet durch User
von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
wolle g. schrieb:
> M.M. nach müsste es der ADW_P6_3 Wert sein, der während des
> Schleifenlaufs vom AD_Wandler (ADCM12EM3) gemessen wird.

-.-

ADW_P6_3 ist einfach nur eine Variable vom Typ int, die überhaupt nichts 
selber macht, der musst du, damit du irgendwas sinnvolles damit machen 
kannst, schon einen entsprechenden Wert zuweisen.
ADCM12EM3 ist ein Ergebnisregister wo die ADC-Einheit nach jedem 
Messvorgang ein Ergebniswert rein schreibt, komplett unabhängig von 
deinem sonstigen Programmablauf. Du machst die ganze Zeit den Fehler, 
dass du aus irgendwelchen Gründen erwartest, dass die Variable ADW_P6_3, 
warum auch immer, den gleichen Wert wie das Messergebnis im Register 
ADCM12EM3 besitzt. Die VARIABLE ADW_P6_3 muss der Wert aus dem REGISTER 
ADCM12EM3 zugewisen werden ( ADW_P6_3 = ADCM12EM3 ) und das musst du vor 
jeder Prüfung innerhalb der Schleife machen, sonst testest du jeweils 
nur gegen den alten Wert der Variablen ADW_P6_3. Wobei sich da natürlich 
dann die Frage stellt, warum du nicht direkt das REGISTER ADCM12EM3 
testest (z.B. if ( ADCM12EM3 > 80 ) break;) !?

Und jetzt hab ich keine Lust mehr...

von Carl D. (jcw2)


Bewertung
0 lesenswert
nicht lesenswert
Nach kurzem Überflügen des DB:
ADCM12EM3 scheint das Register im ADC zu sein, in dem der gewandelte 
Wert hinterlegt wird. Einfach dort abholen:
1
    if ( ADCM12EM3 > 80) break; // ADW_6_3=Kanal 6.3; Stromaufnahme
Das Register dürfte "volatile" deklariert sein, also der Zugriff darauf 
auch aggressiv optimierende Compiler überlebt.

: Bearbeitet durch User
von Wolle G. (wolleg)


Bewertung
0 lesenswert
nicht lesenswert
Tim T. schrieb:
>Und jetzt hab ich keine Lust mehr...
Nicht so schnell aufgeben!

> Die VARIABLE ADW_P6_3 muss der Wert aus dem REGISTER
> ADCM12EM3 zugewiesen werden ( ADW_P6_3 = ADCM12EM3 )

Wahrscheinlich hast Du es übersehen.
In der Funktion:    int ADW_lesen(void)
werden  die ADW-Register gelesen.
Das soll jetzt kein Vorwurf sein, denn mein Programm lädt vermutlich 
nicht zum Studium ein.

>Wobei sich da natürlich dann die Frage stellt, warum du nicht direkt das 
>REGISTER ADCM12EM3 testest (z.B. if ( ADCM12EM3 > 80 ) break;) !?
Die Frage ist berechtigt. Hier bin ich dem Holzweg gelandet. Vor 
gewisser Zeit hatte ich etwas zur Funktionsweise des AD-Wandlers falsch 
gedeutet.

von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
wolle g. schrieb:
> Wahrscheinlich hast Du es übersehen.
> In der Funktion:    int ADW_lesen(void)
> werden  die ADW-Register gelesen.
> Das soll jetzt kein Vorwurf sein, denn mein Programm lädt vermutlich
> nicht zum Studium ein.

Nein, wenn du mal weiter oben genau gelesen hättest, wäre dir 
aufgefallen das ich die schon gefunden hab, aber sie wird nirgendwo 
aufgerufen, was ich aber auch oben geschrieben hab.
Jetzt bin ich aber wirklich raus, ist müßig wenn nichtmal der ganze Text 
gelesen wird...

von Adam P. (adamap)


Bewertung
0 lesenswert
nicht lesenswert
Prozessor Dokter Schmunz schrieb:
> Quatsch. Das sind Weicheierschleifen.
>
> Männerschleifen werden SO geschrieben:While(1) {
>   if(Abbruchbedingung)
>      {break;}
> }

Echt lustig, dass du Männerschleifen und Rheinwerk (Jürgen Wolf) in 
einem Beitrag gemeins erwähnst.

Ich sage nicht, dass du falsch liegst, aber es kommt auf das Problem 
drauf an, man kann vieles nicht einfach über ein Kamm scheren.
Manchmal ist es Sinnvoller beides oder doch nur das eine zu 
machen...oder vllt. doch eine

do
{
/* */
} while (x);

Deine while(1) ist nämlich in deinem Link nicht zu finden...
DORT steht die Abbruchbedingung auch im Kopf der while().

Naja, sei es drum.

Und nun geht es seid 2 Tagen und hab in allen Beiträgen keine Anständige 
Antwort gesehen, die dem TO als Lösung dienen könnte...

: Bearbeitet durch User
von Wolle G. (wolleg)


Bewertung
0 lesenswert
nicht lesenswert
Adam P. schrieb:
> in allen Beiträgen keine Anständige
> Antwort gesehen, die dem TO als Antwort dienen könnte...

Wie kommst Du darauf? Mit Hilfe von Tim T. wurde das Problem im Prinzip 
gelöst.
siehe meinen Beitrag 05.03.2019 13:48

von Adam P. (adamap)


Bewertung
0 lesenswert
nicht lesenswert
wolle g. schrieb:
> Wie kommst Du darauf? Mit Hilfe von Tim T. wurde das Problem im Prinzip
> gelöst.
> siehe meinen Beitrag 05.03.2019 13:48

Ja OK,

Ich bin davon ausgegangen, dass du die Klammern nicht gesetzt hast, da 
du wolltest das die while nur die nächste Anweisung einbezieht.
( Hatte den geposteten C Code nicht gesehen) lediglich dein ersten 
Code-Schnipsel.

: Bearbeitet durch User
von Wolle G. (wolleg)


Bewertung
0 lesenswert
nicht lesenswert
Tim T. schrieb:
>aber sie wird nirgendwo aufgerufen,

Ich denke, im Programmschnipsel vom 05.03.2019 13:48 wird mit
ADW_lesen();  ADC12MEM3 abgerufen.

void ventil_schliessen_regler(void)
      {
       ZU=1;                      //zähler zählt herunter
       while(hub >(ventilstellung_alt-umdrehung_zu ))
       {
       ADW_lesen();               // Stromaufnahmemessung übernehmen
       if ( ADW_P6_3 > 80) break; // ADW_6_3=Kanal 6.3; Stromaufnahme
       // wird am Anschlag überschritten; while-Schleife wird verlassen
       P3OUT &=~BIT0;             // ZU-fahren
       }
       P3OUT |=BIT0;              // ZU-fahren HALT
       ZU=0;
       }


Mit  ADW_P6_3 = ADC12MEM3;
enthält m. E. ADW_P6_3 das Messergebnis, welches in ADC12MEM3 aktuell 
steht.

>Jetzt bin ich aber wirklich raus,

Nee, nee; Das ist erst möglich, wenn Du mich überzeugt hast.

von Brummbär (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Du solltest dringend lernen, lokale Variablen und Funktionsaufrufe zu 
benutzen.

von Brummbär (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ach ja, Variablen dürfen auf längere sprechende Namen haben, welche die 
genaue Funktion beschreiben.
1
stromaufnahme = stromaufnahme_stellmotor();
2
if (stromaufname > 80) break;

oder auch gleich
1
if (stromaufnahme_stellmotor() > 80) break;

hört sich schon besser an als
1
ADW_lesen();               // Stromaufnahmemessung übernehmen
2
if ( ADW_P6_3 > 80) break;

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.