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] для этого?
Код в вашем примере возвращает содержимое pin5
два байта в payload
массив: самый старший байт помещается в payload[0]
и наименее значимый байт помещается в payload[1]
,
Если, например, pin5
является 0x0A63
, затем payload
будет содержать 0x63
, 0x0A
,
Если pin5
имеет 12-битное значение, вы можете использовать его четыре старших разряда, чтобы сохранить собственное четырехбитное значение. Чтобы убедиться, что верхние биты обнулены, используйте 0x0F
маска вместо 0xFF
:
payload[0] = pin5 >> 8 & 0x0f;
// ^
Теперь вы можете переместить ваши данные в верхние четыре бита с помощью |
оператор:
payload[0] |= myFourBits << 4;
Итак, вы хотите понять, что делают указанные операции. Давайте посмотрим, сможем ли мы уточнить это, изучив 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 установленных битов. Так что здесь сделано And
4 младших значащих бита с 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, как и ожидалось.