PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : While Schleife funktioniert nicht!



Wiederstand
15.08.2010, 17:30
Hallo Roboterfreunde,
Es tut mir leid, dass ich euch mit einer so Frage belästige, aber ich schaffe es nicht einmal eine normale While-Schleife zu programmieren.

Ich benutze Avr Studio 4 und habe folgenden Code programmiert:

#include <avr/io.h>
#include <util/delay.h>
uint16_t ms;

void long_delay(uint16_t ms)
{
for(; ms>0; ms--) _delay_ms(1);
}


int main(void){
DDRB |= 0xff;
DDRD |= 0x00;

while(PIND |= 0x00){
PORTB |= 0x00;
long_delay(1000);
PORTB |= 0xff;
long_delay(1000);
}
return 0;
}

Allerdings spielt der Code keine Rolle, denn bei jeder While-Schleife funktionert es nicht.
Sie funktioniert weder im Simulator, noch auf dem Controller.
Alles, was in der Schleife steht wird einmal ausgeführt und dann ist das Programm zuende.

Ich hoffe ihr könnt mit diesen wenigen Informationen etwas anfangen

askazo
15.08.2010, 17:57
Die Bedingung für die while-Schleife ist auch totaler nonsens.
Der Compiler wird daraus ein while(0) gemacht haben, von daher wird die Schleife auch nur einmal aufgerufen, danach ist das Programm zuende.

Es sieht so aus, als würdest Du PORTB blinken lassen wollen, solange kein Eingang auf PORTD gesetzt ist, richtig? Dann versuchs mal mit while(PIND == 0x00).

Allerdings funktioniert mit PORTB |= 0x00; auch das abschalten des Ports nicht. Das müsste PORTB &= 0x00; heißen. Ich denke, Du solltest Dich noch mal ein wenig mit Logik-Operatoren befassen... ;)

Gruß,
askazo

Wiederstand
15.08.2010, 18:25
Danke für deine Antwort, aber es funktioniert immer noch nicht.
Der Code ist jetzt folgender:

#include <avr/io.h>
#include <util/delay.h>
uint16_t ms;

void long_delay(uint16_t ms)
{
for(; ms>0; ms--) _delay_ms(1);
}


int main(void){
DDRB |= 0xff;
DDRD |= 0x00;

while(PIND == 0x00){
PORTB &= 0x00;
long_delay(1000);
PORTB |= 0xff;
long_delay(1000);
}
return 0;
}
Die Led's bleiben einfach an.

Aber wie gesagt ist es egal welchen Code ich ver wende. Auch wenn ich eine while(1) Schleife verwende geht das nicht...

[edit:]
Im Simulator funktioniert der Code jetzt.
Und falls das wichtig ist: ich benutze die Optimierung -01

Wiederstand
15.08.2010, 20:24
Ich habs jetzt geschafft, indem ich die while Bedinung auf (PIND == 0xff) geändert habe. Und while(1) geht jetzt auch.
Komisch, dass es vorher nicht ging.

Gock
16.08.2010, 00:41
Komisch ist das nicht, wenn man die BauteilBeschaltung nicht kennt.
Mögliche Erklärungen sind floatende Pins, angeschlossene Quellen mit hochohmigen Ausgängen oder Störungen durch netzfrequente Einflüsse.
Dass es scheinbar geht, kann immernoch bedeuten, dass es in einem von 1000 Fällen "geht", was Du nicht merken würdest, falls Deine Taktfrequenz zB 1000 mal höher liegt.
So etwas sollte man genauer untersuchen, zB indem man eine Bedingung einfügt, die klar macht, dass es wirklich bei JEDEM mal funktioniert.
Gruß

MichaF
18.08.2010, 10:58
Also der gepostede Code erweckt garantiert nur den Eindruck das alles funktioniert, auch mit PIND == 0xff als while Bedingung. In wirklichkeit rennt der Controller jedes mal in einen Rest sobald PIND == 0xff nicht mehr erfüllt ist. Das ist hochgradiger Pfusch ;)

Programme die innerhalb von main keine while(1) Schleife enthalten, sind meistens böse.

Was du machen möchtest, sollte man so realisieren.


#include <avr/io.h>
#include <util/delay.h>


int main(void){
DDRB |= 0xff;
DDRD |= 0x00;

while(1){
if(PIND == 0x00){
PORTB &= ~0xff;
_delay_ms(1000);
PORTB |= 0xff;
_delay_ms(1000);
}
}
return 0; //Diese Zeile darf niemals ausgeführt werden! Ansonsten -> undefiniert, meist Reset
}

Gock
18.08.2010, 18:37
Hihi,
war wohl spät, dass ich das nicht erkannt habe. Aber MichaF hat natürlich vollkommen recht.
Trotzdem oder gerade jetzt sollte man sich immer dem Scheinbaren nicht hingeben und es durch Tatsachen ersetzen.
Gruß