Pull to refresh

Битовые операции. Для чего они нужны на примере программировании МК

Введение


В своё время я не мог понять смысл таких вещей, как битовые операции. Статьи в интернете не давали мне практического понимания этого вопроса. Со временем, когда я столкнулся с программированием микроконтроллеров (МК), я понял удобство подобных операций, поэтому я решил написать данную статью, чтобы пролить свет на этот вопрос людям, которые только услышали про битовые операции и хотят узнать конкретное практическое применение данных операций. Все примеры будут приведены для tms320f28027.


Операции битового сдвига:


Битовые операции, как можно понять из названия, заключаются в сдвиге битов вправо (>>) или влево (<<).


Давайте предположим, что нам необходимо выставить первый и второй бит в состояние 1, остальные назначить нулями. Для этого мы можем записать


GpioCtrlRegs.GPADIR.all = 0x006;

Где 0x00616= 01102, эта запись эквивалентна (1 <<1) + (1 << 2). Таким образом запись выше может быть более наглядно записана:


GpioCtrlRegs.GPADIR.all = (1 <<1) + (1 << 2);

Кроме этого бывают случаи, когда нам необходимо получить значения только последних битов, для этого может понадобится операция битового сдвига вправо. Например, нам может быть необходимо передать 16 бит данных, при том, что мы можем за раз передать только 8 бит данных. В такой ситуации может пригодится битовый сдвиг вправо, чтобы получить старшие 8 бит. Старшие биты можно не обнулять в случае, если при передаче они не вместятся и обрежутся при передаче 16 битной величине в 8 битный буфер. На стороне приёмника достаточно сдвинуть старшие биты влево и сложить с младшими.


Битовая операция ИЛИ:


Допустим нам необходимо выставить конкретный бит в 1, при этом не меняя весь регистр. Для этого нам может подойти битовая операция ИЛИ. Ниже приведена таблица истинности.


А B A ИЛИ B
0 0 0
0 1 1
1 0 1
1 1 1

GpioCtrlRegs.GPADIR.all |= (1 << 3);

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


Битовые операции И и НЕ


Бывают случаи, когда нам наоборот требуется выставить конкретный бит в состояние 0. Для этого нам необходимо воспользоваться операцией битового И. Для наглядности ниже приведена таблица истинности.


А B A&B
0 0 0
0 1 0
1 0 0
1 1 1

Как видно из таблицы истинности, если произвести операцию битового И с числом, в котором везде единицы, кроме одного бита, то мы сможем выставить 0 в нужном нам бите регистра.


GpioCtrlRegs.GPADIR.all &= 0xFFFFFFF7; // Выставили на 3 бите 0

В примере выше 0xFFFFFFF716 = ‭11111111111111111111111111110111‬2
Кроме этого битовая операция И может понадобится для определения наличия бита в конкретном регистре.
Допустим нам надо сразу определить, выставлен 2 или же 3 бит, для этого мы можем произвести операцию


if(GpioDataRegs.GPADAT.all & FFFFFFF3){
....
}

Это выражение истинно, если выставлен любой из 2 и 3 бита или оба бита выставлены одновременно.


Пример выше можно осуществить проще, с помощью комбинирования операции И и НЕ


GpioCtrlRegs.GPADIR.all |=(~0x008);

Или в виде


GpioCtrlRegs.GPADIR.all &= ~(1 << 3);

Заключение


Спасибо всем кто прочитал. Надеюсь такая простая тема найдёт своего читателя.

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.