Побитовые операции и их применение в WinAVR

Просмотров: 28733Комментарии: 3
Электроника. СхемотехникаAVR.Начинающим

Битовые операции применяются повсеместно при программировании микроконтроллеров. Мы ими пользуемся при работе с регистрами МК, при работе с переменными программы и др. Вот и решил описать их и объяснить применение на каких-нибудь простых примерах. Буду по порядку описывать побитовые операции и сразу приводить примеры.

Операция НЕ (Побитовое отрицание)
Эта операция изменяет значение бита на противоположное. 
Если применить эту операцию к байту, то результатом будет байт с измененными на противоположные битами. В WinAVR операция НЕ обозначается "~" и ставится перед числом к которому она применяется. Например:
unsigned char res=~(0b00110011);
После этого значение переменной res=0b11001100

Операция И (Побитовое И)
Эта операция соответствует применению операции логического И к битам стоящим на одинаковых позициях байта.
В WinAVR операция И обозначается "&" и ставится между байтами к которым она применяется. Например, есть два байта 0b11001100 и 0b01010100 . 
unsigned char res=0b11001100  0b01010100
Результатом применения операции И будет 0b01000100. 
res=0b01000100;
Если мы хотим применить операцию И к res и записать результат в res, то для этого существует два вида записи
  1. Полная запись res=res & 0b00001111;
  2. Короткая запись res &= 0b00001111;
Результатом обоих операций будет 0b00000100.
Часто операция И применяется для того, чтобы сбросить в "0" какой-нибудь бит в байте (переменной) или несколько бит. Мы просто применяем операцию И к тому байту в котором хотим сбросить бит и байту у которого на месте сбрасываемого бита стоит "0", а в тех местах, в которых мы не хотим изменять бит стоит "1". Например
0b11111111 & 0b11110000 = 0b11110000
Как видно у искомого байта младшие 4 бита сброшены в "0".

Операция ИЛИ (Побитовое ИЛИ)
Действие этой операции эквивалентно применению операции логического ИЛИ к битам стоящим на одинаковых позициях байта.
Эта операция обозначается "|" и ставится между числами к которым применяется. Простой пример применения операции ИЛИ к двум байтам
0b11001100 | 0b01010101 = 0b11011101
Также для применения операции ИЛИ к переменной и записи результата в ту же переменную существует две формы записи
  1. Полная - res = res | 0b00001111;
  2. Короткая - res |= 0b00001111;
Часто операция ИЛИ применяется для установки нужного бита в "1". Например
0b00000000 | 0b00001111 = 0b00001111
Т.е. в результате 4 младших бита установлены в "1".

Операция Исключающее ИЛИ (Побитовое исключающее ИЛИ)
Эта операция соответствует применению операции логического исключающего ИЛИ к битам, стоящим на одинаковых позициях байта.
Эта операция обозначается "^" и ставится между переменными к которым применяется. Посмотрим на простой пример
0b11001100 ^ 0b01010101 = 0b10011001
Т.е. если на одинаковых позициях стоят одинаковые биты, то в результирующий бит запишется "0", а если стоят противоположные биты, тогда запишется "1".

Операции сдвига (Битовые сдвиги)
Еще две очень важные операции. При сдвиге биты копируются в соседние по направлению сдвига. В WinAVR различают сдвиг влево "<<" и сдвиг вправо ">>". Это так называемый логический сдвиг, при котором последний бит по направлению сдвига теряется, а первый становится равным нулю. 
Знак операции сдвига ставится между числом в котором мы хотим сдвинуть биты и числом указывающим насколько мы хотим сдвинуть биты. 
0b01111000 << 2 = 0b11100000
Вместе с операциями И и ИЛИ используется для установки  в "1" или сброса в "0" соответствующих бит в байте. Например, хотим установить 5й бит в байте, тогда поступаем так
res |= (1<<5);
Если хотим сбросить все биты кроме 5го
res &= (1<<5);
Также совместно с операцией И применяется для проверки установлен бит в "1" или сброшен в "0". Например, проверим установлен ли 5й бит байта
if((PINB & (1<<5)) == (1<<5)) {}
В WinAVR для сдвига влево существует функция _BV(n), которая соответствует 1<<n.
Также сдвиги часто применяется для быстрого умножения или деления числа на 2. Например, 0b00000010 << 1 равносильно умножению 2 на 2, результатом будет 4. При делении на 2 аналогично применяется операция сдвига вправо.
Еще применяю операции сдвига с побитовыми операциями, если хочу собрать из простых типов переменных более сложный тип. Например у нас есть два байта - старший и младший (будем так называть), обозначим CharH и CharL соответственно. Соберем из них тип int - 2х байтный тип, обозначим IntRes. При этом старший должен стоять старшим байтом в int, а младший - младшим байтом. Поступаю следующим образом:
  1. IntRes = CharH;//приравниваю старший байт
  2. IntRes = IntRes << 8;//устанавливаю старшим байтом в int
  3. IntRes |= CharL;//устанавливаю старший байт в int
Вот собственно и все что хотел написать о битовых операциях. Думаю, не все применения описал, но основные, надеюсь, донес, а дальше каждый сам сможет найти им примененияsmile

Комментариев: 3 RSS

1 UnderColoneL 06-11-2011 19:47

Извиняюсь, за певый пост, вот рабобрался с тегами:

Dmitry? прочитал Вашу статью - 1-wire. Здорово, спасибо, а здесь не всё понятно:

1)

unsigned char res=0b11001100 & 0b11001100;
Результатом применения операции И будет 0b01000100.
res=0b01000100;
Результатом применения операции И будет 0b01000100. 
res=0b01000100;

ответ правильный??

2)

>Если хотим сбросить

>

res &= (1

2 Dmitry 07-11-2011 15:52

в первом варианте исправил

во втором уточнил в тексте, что имелось ввиду))

3 Dmitry 07-11-2011 15:54

провокации нет никакой))) просто когда пишешь, думаешь что все правильно и не всегда проверяешь. спасибо за исправления))

Оставьте комментарий!

grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question

Используйте нормальные имена. Ваш комментарий будет опубликован после проверки.

Вы можете войти под своим логином или зарегистрироваться на сайте.

(обязательно)