aaahaalso.. =)

| bedeutet oder.
0|0 = 0
0|1 = 1
1|0 = 1
1|1 = 1

& bedeutet und.
0|0 = 0
0|1 = 0
1|0 = 0
1|1 = 1

~ bedeutet NICHT.

~1 = 0
~0 = 1


<< bedeutet linksschiebung, >> bedeutet rechtsschiebung.

1<<3 = 1000
1<<4 = 10000
1<<1 = 10
1<<0 = 1 usw.

das wort, ws dahinter steht ist eingentlich auch bloß eine zahl, die dem compiler vorher mitgeteilt wurde, oder eine variable.

0101 << 3 = 0101000

es werden also ganze zahlen verschoben. so kann man zB eine eins durch einen port wandern lassen mit einer einzigen schleife:

PORTB = 0x01 //00000001
PORTB = PORTB<<1 //00000010
PORTB = PORTB<<1 //00000100
PORTB = PORTB<<1 //00001000
PORTB = PORTB<<1 //00010000
PORTB = PORTB<<1 //00100000
usw. immer mit edm gleicheb befehl wird der wert nach links geschoben.

jetzt zu den kompleyxeren sachen.


stell dir vor, du hast ein register (zB PORTB), dessen inhalt du nicht exakt kennst bzw der veränderlich ist. du willst das bit 2 setzen. du könntest folgendes machen:
PORTB = 1<<2;
nachteil: alle anderen bits im register werden auf null gesetzt, denn 1<<2 = 00000100. das ist aber selten das ziel. folgendes ist besser:
PORTB = PORTB | (1<<2);
es wird also jedes bit aktiviert, was vorher schon aktiviert war ODER durch 1<<2 definiert wurde. die kurzvorm davon ist
PORTB |= (1<<2);

jetzt wollen wir das bit löschen. wir könnten scheiben:
PORTB = 0;
jetzt sind aber alle bits null.alternative:
PORTB = ~(1<<2);
wir schreiben hier also 00000100, invertieren das zu 11111011, und schreiben das rein. auch nicht besonders gut.besser so:
PORTB = PORTB & ~(1<<2);
es werden also nur die bits aktiv, die vorher aktiv waren UND duch ~(1<<2) definiert sind. das bit an stelle zwei wird also gelöscht, alle anderen bleiben. auch davon eine kurzform:
PORTB &= ~(1<<2);

also:

bit setzen:
REGISTER |= (1<<STELLE);
bit löschen:
REGISTER &= ~(1<<STELLE);