Wenn du mit
PORTx^=(1<<Pxn);
einen Pin togglest, macht der Compiler (sofern er den Trick mit dem PIN-Register nicht kennt) folgendes:
PORTx einlesen
gelesenen Wert mit (1<<Pxn) verXODERn
Ergebnis auf PORTx ausgeben
Das sind drei Takte, und wenn zwischendurch ein Interrupt auftritt, der ebenfalls PORTx beschreibt, wird der vom Interrupt veränderte Wert sofort wieder überschrieben.
EDIT:
PINB=(1<<PB3);
PORTB^=(1<<PB3);
wird zu
Code:
62: 98 e0 ldi r25, 0x08 ; 8
64: 96 bb out 0x16, r25 ; 22
66: 88 b3 in r24, 0x18 ; 24
68: 89 27 eor r24, r25
6a: 88 bb out 0x18, r24 ; 24
WinAVR 20071221 kennt diese Möglichkeit zum toggeln eines Pins also noch nicht. Aber etwas hat er schon optimiert: das Ergebnis von (1<<PB3) wurde in r25 abgelegt und beim zweiten Mal wiederverwendet. Normalerweise würde die zweite Variante also sogar vier Takte brauchen.
Lesezeichen