Ich hab mir mal gedacht, nutze die Sache, die mich beim AVR immer ärgert (setze 1 damits 0 wird) und schon falle ich auf die Nase. Wenn ich eine Zuweisung teste, müßte doch eine Kopie der Zuweisung ausgewertet werden ? Aber der Compiler liest das GIFR nochmal ein, was natürlich in die Hose geht. Hier mal der Code: if( PIND & 1<<PD2 || (GIFR &= 1<<INTF0) ){ // check hanging on SDA low b2a: 82 99 sbic 0x10, 2 ; 16 b2c: 06 c0 rjmp .+12 ; 0xb3a b2e: 8a b7 in r24, 0x3a ; 58 b30: 80 74 andi r24, 0x40 ; 64 b32: 8a bf out 0x3a, r24 ; 58 b34: 8a b7 in r24, 0x3a ; 58 b36: 88 23 and r24, r24 b38: 29 f0 breq .+10 ; 0xb44 Timeout_sda = time; Mit anderen Worten, man kann nicht eine Zuweisung testen, wenn das Register nicht 100% identisch rücklesbar ist. Peter
Anderes Problem: In diesem Beispiel verlässt Du Dich darauf, dass alle Teile in der if-Abfrage ausgeführt werden. Ist der erste Teil (PIND & 1<<PD2) aber true, dann wird sofort in den Ausführungsteil gesprungen (was übrigens C-konform ist). Die Zuweisung (GIFR &= 1<<INTF0) wird also garnicht ausgeführt, wenn (PIND & 1<<PD2) true ist! Viele Grüße, Stefan
@peter: So ist die Sprache C nun einmal definiert. Das Ergebnis einer Zuweisung ist der Wert der linken Seite, d.h der Inhalt der Variablen oder des Registers, nach der Zuweisung. Wenn die als "volatile" deklariert ist, dann sagt das dem Compiler, dass er noch einmal lesen muss. Jeder andere korrekte Compiler verhält sich genauso (z.B. Microsoft, Digital Mars).
Btw., warum man 1 setzen muss, um ein Interrupt-Flag zu löschen, steht in der FAQ. Hat beim näheren Hinsehen richtig Sinn.
@Jörg, "warum man 1 setzen muss..." ja, daß weiß ich längst, ärgere mich jedesmal darüber. Ich wollte ja nur das Testen und Löschen in einem Abwasch erledigen. Aber das Beispiel hat mir gezeigt, daß Mehrfachzuweisungen sehr gefährlich sein können und deshalb besser vermieden werden sollten. Ein hübsches Beispiel ist noch: x = UDR = y: Dann enthält x alles mögliche, aber bloß nicht den Wert von y. Peter
@Stefan, das ist korrekt und auch so gewollt. Der richtige Code sieht jetzt so aus: if( PIND & 1<<PD2 || GIFR & 1<<INTF0 ){ GIFR = 1<<INTF0; Peter
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.