Цитата(Syber @ Jan 12 2012, 22:17)

Но не могу понять строки из примера с моргающим диодом:
LED_OUT &= ~(LED_0 + LED_1)
Это типаж, когда устанавливают биты по маске. Маска - это определение набора битов в виде двоичного числа, в котором нужные биты установлены в 1.
Например, маски для каждого из пинов 8-битного порта будут такими:
#define PIN1 1
#define PIN2 2
#define PIN3 4
#define PIN4 8
#define PIN5 16
#define PIN6 32
#define PIN7 64
#define PIN8 128
Если к пину PIN3 присоединен светодиод LED_0, то LED_0=8 будет маской, его зажигающей.
Чтобы зажечь этот светодиод, надо подать напряжение на этот пин, а для этого нужно эту маску установить в порту:
LED_OUT |= PIN3;
или
LED_OUT |= LED_0;
Это тоже типаж, т.к. операция |=осуществляет логическое сложение. А поскольку у нас в маске только один бит, то только он и ДОБАВИТСЯ!
Присваивать напрямую
LED_OUT = LED_0;
в таких случаях нельзя, т.к. тогда обнулятся другие биты, а вместе с этим исчезнут напряжения на остальных пинах.
А вот если надо СТЕРЕТЬ какой-то один бит, то стирают его так:
LED_OUT &= ~LED_0;
Выглядит вычурно

, но делает то, что нужно. Т.е. сначала инвертирует маску, а потом "фильтрует" через нее старое значение. В результате чего из LED_OUT сотрется только бит LED_0, а остальные биты в нем сохранятся неизменными.
Тот же механизм работает, если в маске более одного бита. Например, выражение LED_0+LED_1 - это маска обоих светодиодов. Ее можно записать и так LED_0|LED_1.
Поэтому, если надо зажечь СРАЗУ оба светодиода, то зажигают их так:
LED_OUT |= (LED_0+LED_1);
а гасят так:
LED_OUT &= ~(LED_0+LED_1);
Но так светодиоды зажигаются, если они горят на напряжении, выдаваемом контроллером. Но можно (и даже лучше) зажигать светодиод, присоединяя один из его выводов через гасящий резитор к плюсу питания, а другой его вывод заземлять через пин контроллера. В этом случае наши операции станут работать наоборот.
LED_OUT |= (LED_0+LED_1); будет гасить, а LED_OUT &= ~(LED_0+LED_1); будет зажигать.