01 | На заметку: |
Эта статья написана по мотивам оригинальной статьи — Bit Math, об операциях над битами.
|
|
02 |
Вместо введения. Многие программисты Arduino сталкиваются с тем, что в качестве параметров некоторых функций приходится отправлять переменные типа byte (байт). Байт состоит из 8 битов. Бит — это наименьшая единица информации в компьютерном мире — может принимать всего два значения — 1 или 0. |
Возможно, будет также полезно почитать о двоичной системе счисления.
|
03 |
В среде Arduino значение байта начинается с буквы B и далее записываются значения байта побитово: |
|
04 | Arduino (C++) |
1 2 3 // | - старший бит
byte mybyte = B11001100;
// ^ - младший бит |
|
05 |
Также при разборе байта используются понятия старшего (high) и младшего (low) бита. В нашем примере старший бит 1 (первый слева), младший — 0 (первый справа, последний). |
|
06 |
Так, например, при выполнении команды для регистра микроконтроллера DDRD = DDRD | B11111100; — два нуля в конце байта — младшие биты — отвечают как раз за 0 (RX) и 1 (TX) пины платы Arduino. |
Доступно о регистрах микроконтроллера, для чего нужны и как использовать можно почитать здесь.
|
07 |
Операции над битами — побитовое И (AND) Оператор побитового И (AND) в C++ — амперсанд &. Правила: результат равен 1, только если обе части выражения равны 1, в остальных случаях результат — 0: |
|
08 |
Пример: 1 2 3 byte b1 = B10110010; //B10110010
byte b2 = B11100111; //B11100111
byte result = b1 & b2; //B10100010 |
|
09 |
Побитовое ИЛИ (OR) Оператор побитового ИЛИ (OR) в C++ — вертикальная черта |. Правила: результат равен 0, только если обе части выражения равны 0, в остальных случаях результат — 1: |
|
10 |
Пример: 1 2 3 byte b1 = B10110010; //B10110010
byte b2 = B11100111; //B11100111
byte result = b1 | b2; //B11110111 |
|
11 |
Побитовое Исключающее ИЛИ (XOR) Оператор побитового Исключающего ИЛИ (XOR) в C++ — символ каретки ^. Правила: результат равен 0, только если обе части выражения равны, в остальных случаях результат — 1: |
|
12 |
Пример: 1 2 3 byte b1 = B10110010; //B10110010
byte b2 = B11100111; //B11100111
byte result = b1 ^ b2; //B01010101 |
|
13 |
Побитовое НЕ (NOT) Оператор побитового НЕ (NOT) в C++ — символ тильда ~. В отличие от & и |, используется только с одним операндом. Он просто инвертирует биты. |
|
14 |
Пример: 1 2 byte b1 = B10110010; //B10110010
byte result = ~ b1; //B01001101 |
|
15 |
Операции над битами — сдвиги битов (Bit Shift Operations) Существуют только 2 сдвиговые операции над битами — смещение бита влево <<, и смещение бита вправо >>. Следом за знаком смещения следует число, показывающее на сколько позиций сместить биты. |
|
17 |
При смещении бита влево старшие биты теряются, а младшие заполняются нулями: 1 2 byte b1 = B10000011; //B10000011
byte result = b1 << 3; //B00011000 |
|
18 |
При смещении бита вправо младшие биты теряются, а старшие заполняются нулями: 1 2 3 4 5 byte b1 = B10000011; //B10000011
byte result = b1 >> 3; //B00010000
byte b2 = B01100001; //B01100001
result = b2 >> 3; //B00001100 |
|
19 |
Операции с присваиванием Все упомянутые выше операции (за исключением побитового НЕ (NOT)) можно записывать в краткой форме. Этот прием применяется в случаях, когда в расчете результата используется та же переменная, которой будет присвоен результат: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 byte b1 = B10000011;
//--------------------
b1 = b1 >> 3;
// то же самое, что и
b1 >>= 3;
//--------------------
b1 = b1 << 2;
// то же самое, что и
b1 <<= 2;
//--------------------
b1 = b1 | B10011101;
// то же самое, что и
b1 |= B10011101;
//--------------------
b1 = b1 ^ B10011101;
// то же самое, что и
b1 ^= B10011101;
//--------------------
// и т.д. |
|
20 |
Раздел добавлен 20.12.2017
|
Манипуляции с единичными битами Иногда возникает необходимость точечного воздействия на конкретный бит одного байта. Далее представлены примеры основных операций над единичными битами с использованием операций сдвига единичного байта (1=B00000001). |
|
21 |
Для записи единицы в бит под номером n (где n=[0, 1, .., 7]): |
|
22 | Arduino (C++) |
1 2 3 4 b |= (1 << n);
// Пример
byte b = B00000000;
b |= (1 << 4); //B00010000 |
|
23 |
Для записи нуля в бит под номером n (где n=[0, 1, .., 7]): |
|
24 | Arduino (C++) |
1 2 3 4 b &= ~(1 << n);
// Пример
byte b = B11111111;
b &= ~(1 << 4); //B11101111 |
|
25 |
Инвертировать бит под номером n (где n=[0, 1, .., 7]) можно следующим образом: |
|
26 | Arduino (C++) |
1 2 3 4 5 b ^= (1 << n);
// Пример
byte b = B11110000;
b ^= (1 << 4); //B11100000
b ^= (1 << 1); //B11100010 |
|
27 |
Функции по манипуляции с битами Если чем-то не устраивают стандартные функции Arduino по работе с битами — bit(), bitWrite(), bitSet(), bitClear(), bitRead(), либо нужно запрограммировать индивидуальные манипуляции с битами, то при помощи стандартных операций, можно реализовать любую битовую логику. Например, операция инвертирования порядка следования битов в байте будет выглядеть так: |
|
28 | Arduino (C++) |
1 2 3 4 5 6 7 8 9 10 byte b = B10010011;
byte result = (((((((0 | (((b >> 7) & 1) << 0)) |
(((b >> 6) & 1) << 1)) |
(((b >> 5) & 1) << 2)) |
(((b >> 4) & 1) << 3)) |
(((b >> 3) & 1) << 4)) |
(((b >> 2) & 1) << 5)) |
(((b >> 1) & 1) << 6)) |
(((b >> 0) & 1) << 7); //B11001001 |
|
29 |
Или, если упростить и обернуть в функцию: |
|
30 | Arduino (C++) |
1 2 3 4 5 6 7 8 9 10 11 byte invertBitOrder(byte b) {
byte result = 0;
for (int i = 0; i <= 7; i++) {
result = result | (((b >> (7 - i)) & 1) << i);
}
return result;
}
// Использование
byte b = B10010011;
Serial.println(invertBitOrder(b), BIN); //B11001001 |
|
32 |
Похожие запросы:
|
|