Shift-Problem?

Gast #898877
Lesenswert?

Hallo zusammen,

ich bin blutiger Anfänger, also bitte um Nachsicht ;-)

In einem Programm möchte ich warten, bis auf PIND die letzten drei Bits 
1 sind. Meine Frage:

Warum tut es so:
1
while(~PIND & 0b00000111){warte();}

aber nicht so:
1
while((PIND << 5) != 0b11100000){warte();}

Die obere Bedingung wird false, wenn alle drei Bits 1 sind, wie 
gewünscht. Die untere Bedingung wird aber nie false, also die 
while-Schleife nie verlassen.

Danke schonmal,
Martin
#898909
Lesenswert?

Ich würde sagen, dass das ein Compilerfehler ist, der optimiert hier 
etwas zu clever. Der Code sieht nämlich so aus:
1
+0000002F:   C001        RJMP    PC+0x0002        Relative jump
2
+00000030:   D006        RCALL   PC+0x0007        Relative call subroutine
3
+00000031:   B380        IN      R24,0x10         In from I/O location
4
+00000032:   3087        CPI     R24,0x07         Compare with immediate
5
+00000033:   F7E1        BRNE    PC-0x03          Branch if not equal
#898955
Lesenswert?

Hallo.
Es gibt auch noch einen interessanten Unterschied: In der ersten Version 
überprüfst du mit Bitoperatoren, ob die unteren 3 Bit gesetzt sind. Das 
ist ok. Die Anderen Bits von PINx spielen dadurch keine rolle.

Bei der unteren Variante, vergleichst du logisch. Dabei zählen alle 
Bits.
Soweit ich weiß, arbeitet der Compiler bei so einem Vergleich mit ganzen 
ints. Also in dem fall 16bit. Das Shift5 löscht somit die anderen bits 
nicht.
Sie werden einfach ins HighByte verschoben. Dein 8bit Konstanten 
ausdruck ist auch ein int. sein HighByte ist 0.
Somit spielen die anderen Bits von PINx plötzlich eine Rolle.
Ich vermute das alles nur ;-) Bitte nicht lachen ;-)
Bei dem gezeigtes ASM weiß ich leider nicht, welche Version das ist. 
vermutlich die untere.. das all mein gebrabbel widerlegen würde :-D

Ich würde es nochmal mit:

while((unsigned char)(((unsigned char)PIND) << 5) != (unsigned 
char)0b11100000){warte();}
probieren. Das ist Nummer sicher ;-)

oder:

while(((PIND&0x07) << 5) != 0b11100000){warte();}

So.
MFG
Gast #898984
Lesenswert?

Ich kann die Erklärung von Der Albi und Jörg (promotet zu was mit 16bit) 
bestätigen. Habe es jetzt (fast) wie von Der Albi vorgeschlagen:
1
while(( (PIND & 0b00000111) << 5) != 0b11100000){...}

Klappt wunderbar.

Danke Leute!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren