Salve!
Quando dici che i due bit non vanno a zero intendi che non si spengono i led? Se non si spengono i led, evidentemente sono connessi con l'anodo all'alimentazione e con il catodo ai vari pin del microcontrollore.
L'istruzione:
Code:
P2OUT &= ~(BIT0 + BIT1);
esegue la somma di BIT0 con BIT1 (ossia 00000011), poi l'inversione dei singoli bit con l'operatore ~ (ossia 11111100) e poi esegue l'AND logico (bit a bit) con il valore di P2OUT. In questo modo, gli unici bit di P2OUT che saranno forzati a zero saranno proprio quelli meno significativi, mentre tutti gli altri resteranno invariati.
Con l'istruzione:
Code:
P2OUT ^= BIT0 + BIT1
esegui la somma di BIT0 con BIT1 (ossia 00000011), poi calcoli l'OR ESCLUSIVO con i bit di P2OUT e il risultato lo assegni a P2OUT. Quando hai un bit generico X (di valore 0 o 1) ed esegui l'OR ESCLUSIVO con il valore 0, il risultato del bit X non cambia. Il risultato invece si inverte se esegui l'OR ESCLUSIVO con il bit 1.
Esempio - Se P2OUT vale 01001101, allora il risultato di P2OUT ^= BIT0 + BIT1 è 01001110.
Con l'istruzione:
Code:
P2OUT = !(BIT0 + BIT1)
esegui invece la somma di BIT0 con BIT1 (ossia 00000011), applichi l'operatore logico NOT a tutta la parentesi (ottenendo quindi 00000000) e il valore lo assegni a P2OUT. Nota che 00000011 è "un qualcosa di vero", perché diverso da zero, quindi lo rendi falso se applichi l'operatore logico NOT (tutto falso!, perché non è un operatore bit a bit), ottenendo quindi 00000000.
In quest'ultimo caso devi fare un po' più di attenzione, perché mentre con |= e &= vai a mettere mani sui singoli bit, con l'operatore = applicato alla porta vai a forzare tutti i bit, e spesso il valore di alcuni di questi non vanno modificati (ad esempio quando utilizzi i resistori di pull-up interni).
Per vedere cosa succede con questi operatori, puoi utilizzare lo strumento di debug di Code Composer Studio.
Saluti,
Cosimo