Побитовые операции в C

В нашем первом уроке (/nachalo-raboty-s-mikrokontrollerami-atmel-avr/) мы ознакомились с принципом работы с микроконтроллерами. Но, естественно, не совсем удобно просто писать в регистры числа в двоичной или шестнадцатиричной форме. А что, если надо не тронуть всех битов на порте, кроме одного? Изменить его значение с 0 на 1 или наоборот? Ответ на этот вопрос дадим чуть позже.

Вначале рассмотрим побитовые операции в C.

Побитовые операции можно применять только к целочисленным типам.

Виды побитовых операций:

  • & ( или and ),
  • | ( или OR ),
  • ^ ( или XOR ),
  • ~ ( или NOT ),
  • сдвиг влево,
  • сдвиг вправо.
Первые четыре операции дают результат как в математической логике: Сравниваем значение каждой пары битов. В результате получаем тоже целочисленный тип. Например,
1 & 1 == 1; 
1 | 0 == 1; 
1 & 0 == 0;
0b01 | 0b11 == 0b11 и т.д.
Операции << - сдвиг влево и >> - сдвиг вправо просто сдвигают разряд числа в соответствующем направлении. Например:
0b010 << 1 == 0b100; 
0b010 >> 1 == 0b001;
0b00001 << 3 == 0b01000; 

0b00100 << 3 == 0b00001 и т.д.

Для чего нужны побитовые операции в C для микроконтроллеров?

Например, мы хотим сделать значение 3 бита равным 1, при этом остальных битов не трогать. Это выглядит так:

PORTA |= 1 << 3;
Проанализуруем. Например, значение на PORTA = 0b1010.Теперь, при выполнении операции 0b1010 | 0b100 получим 0b1110. Таким образом, ставим 1 на 3 позицию вне зависимости от значений остальных битов и текущего значения 3 бита. Чтобы поставить 0, надо поступить немного иначе:
PORTA &= ~(1 << 3);
Передвигаем 1 на 3 позицию, делаем логическое отрицание (получаем 0b011), теперь, при любом значении PORTA получим 0 на 3 позиции.