Hi Leute...
Könnt ihr mir vielleicht sagen warum diese zwei FOR-Schleifen
hintereinander nicht funktionieren, jede einzelne seperat aber ohne
Probleme funktioniert?
1
voidflush(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
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.
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
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".
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.
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...
>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.
>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 ;-)
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.
> 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
>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!
> 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.
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.
> 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.
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...
>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
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.