mikrocontroller.net

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


Autor: Rush (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute...

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

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

Vielen Dank schoneinmal.
Konrad

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
WAS funktioniert denn nicht?

Autor: Sandro K. (maexchen)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rush (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... led dimmt ...

Ach, so!

Autor: Rush (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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".

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Laufbedingung "CH1 <=" und "CH1 >=" ist falsch.

Das Gleichheitszeichen muß weg.

Autor: Rush (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Rush (Gast)
Datum:

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

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;-)

Autor: Winfried J. (Firma: Nisch-Aufzüge) (winne)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Gast (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Werner (Gast)
Datum:

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

Das ist ein 16-Bit Register.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.