Битовые маски в Arduino
Битовые маски используются для доступа к отдельным битам в байте данных.
Авторы: Arduino
Последняя редакция: 16.01.2024
Битовые маски используются для доступа к отдельным битам в байте данных. Это часто бывает полезно как метод итерации, например, при последовательной отправке байта данных через один пин. В этом примере пин должен менять своё состояние с высокого на низкое для каждого бита передаваемого байта. Это достигается с помощью так называемых побитовых операций и битовой маски.
Побитовые операции выполняют логические функции, действующие на уровне отдельных битов. К стандартным побитовым операциям относятся AND (&), OR (|), сдвиг влево (<<) и сдвиг вправо (>>).
Оператор AND (&) даёт в результате 1 в каждой битовой позиции, где оба входных значения равны 1. Например:
x: 10001101
y: 01010111
x & y: 00000101
Оператор OR (|), также известный как «включающее ИЛИ», даёт в результате 1 в каждой битовой позиции, где хотя бы одно из входных значений равно 1. Например:
x: 10001101
y: 01010111
x | y: 11011111
Оператор сдвига влево (<<) сдвигает значение влево на указанное число позиций.
Например:
y = 1010
x = y << 1
yields: x = 10100
Все биты в байте сдвигаются на одну позицию влево, а самый левый бит отбрасывается.
Оператор сдвига вправо (>>) работает аналогично сдвигу влево, за исключением того, что он сдвигает значение вправо на указанное число позиций.
Например:
y = 1010
x = y >> 1
yields: x = 0101
Все биты в байте сдвигаются на одну позицию вправо, а самый правый бит отбрасывается.
В качестве практического примера возьмём значение 170, в двоичном виде 10101010. Чтобы вывести это значение импульсами на пин 7, код может выглядеть следующим образом:
byte transmit = 7; //определяем наш пин для передачи
byte data = 170; //значение для передачи, двоичное 10101010
byte mask = 1; //наша битовая маска
byte bitDelay = 100;
void setup()
{
pinMode(transmit,OUTPUT);
}
void loop()
{
for (mask = 00000001; mask>0; mask <<= 1) { //перебираем биты маски
if (data & mask){ // если побитовое AND даёт истину
digitalWrite(transmit,HIGH); // отправляем 1
}
else{ //если побитовое AND даёт ложь
digitalWrite(transmit,LOW); // отправляем 0
}
delayMicroseconds(bitDelay); //задержка
}
}
Здесь мы используем цикл FOR для перебора значения битовой маски, сдвигая значение на одну позицию влево при каждом проходе цикла. В этом примере мы используем оператор <<=, который работает точно так же, как оператор <<, но сокращает запись.
00000001
& 10101010
________
00000000
И наш выходной пин устанавливается в 0. Во второй раз через цикл маска = 00000010, поэтому наша операция выглядит так:
00000010
& 10101010
________
00000010
И наш выходной пин устанавливается в 1. Цикл будет продолжать перебирать каждый бит маски до тех пор, пока 1 не сдвинется влево за пределы 8 бит и наша маска не станет равной 0. После этого все 8 бит будут отправлены, и наш цикл завершится.
Примечание
Лицензия: документация Arduino распространяется под лицензией Creative Commons Attribution-Share Alike 4.0.