Forum: Mikrocontroller und Digitale Elektronik Zwei FOR-Schleifen hintereinander??


von Rush (Gast)


Lesenswert?

Hi Leute...

Könnt ihr mir vielleicht sagen warum diese zwei FOR-Schleifen 
hintereinander nicht funktionieren, jede einzelne seperat aber ohne 
Probleme funktioniert?
1
void flush(void)
2
{
3
  for (CH1 = 0; CH1 <= 1023; CH1++) {_delay_ms(3);}
4
  for (CH1 = 1023; CH1 >= 0; CH1--) {_delay_ms(3);}
5
}

CH1 ist OCR1A eines Tiny2313. Die funktion soll lediglich eine LED auf- 
und wieder abdimmen.

Vielen Dank schoneinmal.
Konrad

von Gast (Gast)


Lesenswert?

WAS funktioniert denn nicht?

von Sandro K. (maexchen)


Lesenswert?

Ist das deine ganze Codesezuenz oder hast du da noch was 
rausgeschnitten?
Das, was du da hingeschriben hast ist eine Zeitverzögerung von sechs 
sekunden und ein paar zerqueschten.

von Rush (Gast)


Lesenswert?

Oh hab ich ja garnicht geschrieben ;-)
also die erste wird ausgeführt, die zweite anscheinend übersprungen.
sprich die led dimmt von dunkel auf hell und dann wieder schlagartig von 
dunkel auf hell. dimmt also von hell nicht auf dunkel runter

von Gast (Gast)


Lesenswert?

... led dimmt ...

Ach, so!

von Rush (Gast)


Lesenswert?

Nein das ist nur die Funktion zum dimmen. Die 3ms delay hab ich nur 
reingehängt weils sonst zu schnell geht. Das OCR1A-Register (CH1) soll 
nur von 0 auf 1023 zählen und dann von 1023 auf 0 zurück. Die Funktion 
wird in der main in der while(1) Schleife aufgerufen, läuft also "im 
Kreis".

von Werner (Gast)


Lesenswert?

Die Laufbedingung "CH1 <=" und "CH1 >=" ist falsch.

Das Gleichheitszeichen muß weg.

von Rush (Gast)


Lesenswert?

super so gehts, danke.
aber warum ist das falsch ??
CH1 <= 1023 bedeutet doch dass so lange hochgezählt wird, solange CH 
eben kleiner oder gleich 1023 ist. also bei z. B. CH1 = 1000 zählt er 
hoch weil 1000 <= 1023 ist

CH1 >= 0 bedeutet doch dass so lange runtergezählt wird, solange CH eben 
größer oder gleich ist. Also bei z. B. CH1 = 1000 zähler er runter weil
1000 <= 0 ist.

Und jede von den oben genannten Schleifen einzeln funktioniert ja auch.

von Dominik (Gast)


Lesenswert?

wenn du eine zahl hast, die typenbedinngt nicht kleiner null werden 
kann, aber als bedinnung <= 0 setzt, widerspricht du dir selbst, da dies 
bei dieser konstellation gar nie möglich ist...

von Rush (Gast)


Lesenswert?

ja gut ok, aber der Werner sagt ja ein Beitrag weiter oben ich soll das 
= wegmachen und nich das < und >.

von Werner (Gast)


Lesenswert?

>super so gehts, danke.
>aber warum ist das falsch ??

Wenn Du schreibst "CH1 <= 1023", dann wird bei 1023 nochmal hochgezählt,
weil ja die Bedingung erfüllt ist.
1023 ist  11 1111 1111 binär,
1024 ist 100 0000 0000.

von Werner (Gast)


Lesenswert?

>1023 ist  11 1111 1111 binär,
>1024 ist 100 0000 0000.

Das ist zwar richtig, hat aber mit dem Fehler nichts zu tun, ich war in 
Gedanken bei einem Portausgang ;-)

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

Das ist aber der Punkt, es kommt zum wrap around wegen der Typegrenze
in dem Falle ist 1024 == 0,

Weshalb beim Aufruf der nächsten for-Schleife, deren Abbruchbedingundung 
bereits erfüllt ist, sie somit übersprungen wir, die suppe somit für 
diese Runde gegessen ist.

von Peter (Gast)


Lesenswert?

> Das ist aber der Punkt, es kommt zum wrap around wegen der Typegrenze
> in dem Falle ist 1024 == 0,
kann ich mir auch nicht vorstelle, weil ja in beiden for-Schleifen die 
Variable CH1 konstant auf einen wert gesetzt wird.

@autor
Zeige mal den assembler code dazu

von Gast (Gast)


Lesenswert?

>Das ist aber der Punkt, es kommt zum wrap around wegen der Typegrenze
>in dem Falle ist 1024 == 0,

korrekt!

>Weshalb beim Aufruf der nächsten for-Schleife, deren Abbruchbedingundung
>bereits erfüllt ist, sie somit übersprungen wir, die suppe somit für
>diese Runde gegessen ist.

falsch!

Aufgrund des wrap arounds wird die erste Schleife niemals beendet!

Weil 1023 + 1 --> (1024 == 0) --> (0 <= 1023) --> Schleife wird 
fortgesetzt!

von Gast (Gast)


Lesenswert?

Eine sehr schöne Prüfungsfrage an der sich wohl viele die Zähne 
ausbeißen würden :-)

von Karl H. (kbuchegg)


Lesenswert?

> Das ist aber der Punkt, es kommt zum wrap around wegen der Typegrenze
> in dem Falle ist 1024 == 0,

Welche Typgrenze?
In C gibt es keinen Datentyp, der nur 10 Bit umfasst (Ausser man macht 
sich da selbst was mit Bitfeldern in einer Struktur)
Das einzige was jetzt sein kann, ist, dass das Register OCR1A beim 
Beschreiben nur 10 Bit annimmt, weil es nicht breiter ist. Aber sowas 
findet man im Datenblatt des Prozessors. C hat dazu nichts zu sagen.

Jungs. Ohne zu wissen wie CH1 exakt definiert ist, ist das alles 
Kaffesatzleserei.

von Werner (Gast)


Lesenswert?

>Das einzige was jetzt sein kann, ist, dass das Register OCR1A beim
>Beschreiben nur 10 Bit annimmt

Das ist ein 16-Bit Register.

von Karl H. (kbuchegg)


Lesenswert?

Werner wrote:
>>Das einzige was jetzt sein kann, ist, dass das Register OCR1A beim
>>Beschreiben nur 10 Bit annimmt
>
> Das ist ein 16-Bit Register.

Was nicht unbedingt heissen muss, das tatsächlich auch alle 16 Bit 
relevant sind und gespeichert werden (OK. klingt widersinnig, ist es 
IMHO auch, aber wäre prinzipiell möglich). Darum auch der Hinweis aufs 
Datenblatt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> for (CH1 = 1023; CH1 >= 0; CH1--)
Angenommen CH1 wäre unsigned, dann ist CH1 >= 0 immer erfüllt, weil CH1 
nicht kleiner als 0 werden kann. Die Schleife wird also nie beendet.

von P. S. (Gast)


Lesenswert?

Karl heinz Buchegger wrote:

> Was nicht unbedingt heissen muss, das tatsächlich auch alle 16 Bit
> relevant sind und gespeichert werden (OK. klingt widersinnig, ist es
> IMHO auch, aber wäre prinzipiell möglich).

Finde ich gar nicht so widersinnig - wenn's nur ein 10-Bit-Timer waere 
und die oberen 6 Bit nicht gebraucht wuerden, warum diese dann 
speichern? Ich bin auch schon Registern begegnet, die beim Schreiben A 
gemacht und beim Lesen B geliefert haben...

> Darum auch der Hinweis aufs Datenblatt.

Sieht nach einem ganz "normalen" 16-Bit Register aus. Trotzdem wuerde 
ich nie so direkt auf dem Register arbeiten, sondern immer in einer 
eigenen Variable zaehlen und dann zuweisen. Einfach aus Prinzip...

von Werner (Gast)


Lesenswert?

>Angenommen CH1 wäre unsigned, dann ist CH1 >= 0 immer erfüllt, weil CH1
>nicht kleiner als 0 werden kann. Die Schleife wird also nie beendet.

Aber sie müßte einmal herunterdimmen.
Siehe Fehlerbeschreibung:

>sprich die led dimmt von dunkel auf hell und dann wieder schlagartig von
>dunkel auf hell. dimmt also von hell nicht auf dunkel runter

von Karl H. (kbuchegg)


Lesenswert?

Ich wette mal, dass seine LED gegen Vcc angeschlossen ist.
Was er also als 'von hell nach dunkel dimmen' interpretiert,
also

  for (CH1 = 1023; CH1 >= 0; CH1--) {_delay_ms(3);}

ist in Wirklichkeit dimmen von 'dunkel nach hell'.

Und da CH1 wahrscheinlich unsigned ist (zumindest deuten die spärlichen 
Aussagen darauf hin), wird sie nie verlassen. Und damit hat er den 
Effekt, dass die LED ständig immer nur von dunkel nach hell dimmt und 
das Programm in dieser Schleife hängt.

Aber ohne Aussage darüber, wie die LED angeschlossen ist, bzw. wie die 
PWM konkret eingestellt ist, ist das alles wiederrum Kaffesatzleserei.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> jede einzelne seperat aber ohne Probleme funktioniert?
Das möchte ich aber mal sehen ;-)

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.