Понимание побитовых операций — сдвиг и AND

uint8_t payload[] = { 0, 0 };
pin5 = analogRead(A0);
payload[0] = pin5 >> 8 & 0xff;
payload[1] = pin5 & 0xff;

Это код из библиотеки XBee, опубликованной andrewrapp на GitHub. Мне было интересно, как работает побитовая операция.
поэтому предположим, что вывод 5 получает аналоговое значение 256, которое, поскольку я использую фотонную плату частиц, приходит в 12-битном текстовом формате как 000100000000. Так что полезная нагрузка [0] получает последние восемь битов, т.е. 00000000, или получает значение после сдвига, т.е. 00000001? Кроме того, что становится значением в полезной нагрузке [1]?

Я хочу добавить 4-битный код моего использования битовой маски к первым четырем битам в массиве, за которыми следуют биты данных. Могу я & полезная нагрузка [1] с полезной нагрузкой 0X1 [1] для этого?

-2

Решение

Код в вашем примере возвращает содержимое pin5два байта в payload массив: самый старший байт помещается в payload[0] и наименее значимый байт помещается в payload[1],

Если, например, pin5 является 0x0A63, затем payload будет содержать 0x63, 0x0A,

Если pin5 имеет 12-битное значение, вы можете использовать его четыре старших разряда, чтобы сохранить собственное четырехбитное значение. Чтобы убедиться, что верхние биты обнулены, используйте 0x0F маска вместо 0xFF:

payload[0] = pin5 >> 8 & 0x0f;
//                         ^

Теперь вы можете переместить ваши данные в верхние четыре бита с помощью | оператор:

payload[0] |= myFourBits << 4;
0

Другие решения

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

pin5              000100000000
MMMMLLLLLLLL

M = 4 старших разряда, L = 8 наименее значимых бит

payload[0] принимает результат некоторых операций на pin5:

pin5              000100000000
>> 8              000000000001  Shifts all bits 8 positions to the right
00000000MMMM  and fills the left part with zeroes

так что теперь у вас есть первые 4 бита, выровненные по правому краю, для которых выполняется дополнительная операция:

                  000000000001
& 0xFF            000011111111  Anding with FF
000000000001

Сдвиг вправо 12-битной переменной на 8 позиций оставляет 4 значимых позиции; старшие 8 бит всегда будут 0. 0xFF является двоичным 11111111то есть представляет 8 установленных битов. Так что здесь сделано And4 младших значащих бита с 8 младшими значащими битами, чтобы убедиться, что 4 старших значащих бита удалены.

                  00000000xxxx  Potentially set bits (you have 0001)
000011111111  & 0xFF
00000000xxxx  Result
0000xxxx  Storing in 8-bits variable
payload[0] =          00000001  in your case

В этом случае AndЭта операция бесполезна и является пустой тратой времени, потому что Andс помощью любой переменной 0xFF никогда не изменяет свои 8 младших значащих битов, и поскольку 4 старших бита никогда не устанавливаются, в этой операции просто нет смысла.

(Технически, поскольку источником является 12-битная переменная (предположительно, это 16-битная переменная, имеющая только 12 значимых (соответствующих) двоичных цифр), 0x0F было бы достаточно для Andмаска Вы понимаете почему? Но даже это будет просто потраченный впустую цикл процессора.)

payload[1] также принимает результат операции на pin5:

pin5              MMMMLLLLLLLL  potentially set bits
& 0xFF            000011111111  mask to keep LLLLLLLL only
0000LLLLLLLL  result (you have 00000000)
xxxxxxxx  Storing in 8-bits variable
payload[1] =          00000000  in your case

В этом случае Anding с 11111111 имеет смысл, потому что это отбрасывает MMMM, который в вашем случае 0001,

Итак, в целом, ваша ценность

pin5              000100000000
MMMMLLLLLLLL

расколота так, что payload[0] содержит MMMM (0001 = десятичный 1) и payload[1] содержит LLLLLLLL (00000000 = десятичный 0).

Если вход был

pin5              101110010001
MMMMLLLLLLLL

вместо этого вы найдете в payload[0]: 1011 (десятичное 8 + 2 + 1 = 11) и в payload[1]: 10010001 (десятичное 128 + 16 + 1 = 145).

Этот результат можно интерпретировать как десятичное 11 * 256 + 145 = 2961, то же самое, что вы получите при преобразовании исходного 101110010001 из двоичного в десятичное, например, используя calc.exe в режиме программиста (Alt+3), если вы используете Windows.

Аналогично, ваши исходные данные интерпретируются как 1 * 256 + 0 = 256, как и ожидалось.

0

По вопросам рекламы [email protected]