Arduino:Основы/Битовые маски: различия между версиями
Myagkij (обсуждение | вклад) Нет описания правки |
Нет описания правки |
||
Строка 13: | Строка 13: | ||
Если хотя бы у одного их входных значений в бите будет '''«0»''', в итоге этот '''«0»''' появится и в итоговом значении: | Если хотя бы у одного их входных значений в бите будет '''«0»''', в итоге этот '''«0»''' появится и в итоговом значении: | ||
<syntaxhighlight lang="c | <syntaxhighlight lang="c"> | ||
x: 10001101 | x: 10001101 | ||
y: 01010111 | y: 01010111 | ||
Строка 23: | Строка 23: | ||
Иногда его называют [[Arduino:Справочник языка Arduino/Побитовые операторы/AND(&),OR и XOR (^)|включающим ИЛИ]]. Если хотя бы у одного их двух входных значений в бите будет '''«1»''', в итоге этот '''«1»''' появится и в итоговом значении: | Иногда его называют [[Arduino:Справочник языка Arduino/Побитовые операторы/AND(&),OR и XOR (^)|включающим ИЛИ]]. Если хотя бы у одного их двух входных значений в бите будет '''«1»''', в итоге этот '''«1»''' появится и в итоговом значении: | ||
<syntaxhighlight lang="c | <syntaxhighlight lang="c"> | ||
x: 10001101 | x: 10001101 | ||
y: 01010111 | y: 01010111 | ||
Строка 33: | Строка 33: | ||
Сдвигает значение влево на указанное количество позиций. Например: | Сдвигает значение влево на указанное количество позиций. Например: | ||
<syntaxhighlight lang="c | <syntaxhighlight lang="c"> | ||
y = 1010 | y = 1010 | ||
x = y << 1 | x = y << 1 | ||
Строка 45: | Строка 45: | ||
Работает идентично оператору для сдвига влево, но двигает биты в противоположную сторону, т.е. вправо. | Работает идентично оператору для сдвига влево, но двигает биты в противоположную сторону, т.е. вправо. | ||
<syntaxhighlight lang="c | <syntaxhighlight lang="c"> | ||
y = 1010 | y = 1010 | ||
x = y >> 1 | x = y >> 1 | ||
Строка 55: | Строка 55: | ||
В качестве практического примера давайте возьмем значение '''«170»''', которое в двоичном виде представляет собой '''«10101010»'''. Чтобы передать это значение через '''контакт 7''', код должен выглядеть следующим образом: | В качестве практического примера давайте возьмем значение '''«170»''', которое в двоичном виде представляет собой '''«10101010»'''. Чтобы передать это значение через '''контакт 7''', код должен выглядеть следующим образом: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
byte transmit = 7; // задаем контакт для передачи данных | byte transmit = 7; // задаем контакт для передачи данных | ||
byte data = 170; // значение для передачи; «10101010» | byte data = 170; // значение для передачи; «10101010» | ||
Строка 82: | Строка 82: | ||
Здесь мы использует цикл [[Arduino:Справочник языка Arduino/Управляющие операторы/for|for()]], чтобы сделать несколько проходов по битовой маске. С каждым проходом через цикл мы сдвигаем значение в маске на одну позицию влево. В данном случае мы используем оператор '''<<=''', который равнозначен, по сути, оператору [[Arduino:Справочник языка Arduino/Побитовые операторы/Операторы побитового сдвига влево и вправо|<<]], но за тем исключением, что делает оператор более компактным. | Здесь мы использует цикл [[Arduino:Справочник языка Arduino/Управляющие операторы/for|for()]], чтобы сделать несколько проходов по битовой маске. С каждым проходом через цикл мы сдвигаем значение в маске на одну позицию влево. В данном случае мы используем оператор '''<<=''', который равнозначен, по сути, оператору [[Arduino:Справочник языка Arduino/Побитовые операторы/Операторы побитового сдвига влево и вправо|<<]], но за тем исключением, что делает оператор более компактным. | ||
<syntaxhighlight lang="c | <syntaxhighlight lang="c"> | ||
00000001 | 00000001 | ||
& 10101010 | & 10101010 | ||
Строка 91: | Строка 91: | ||
В итоге контакт получает значение '''«0»'''. При втором проходе через цикл битовой маской станет значение '''«00000010»''', и операция будет выглядеть следующим образом: | В итоге контакт получает значение '''«0»'''. При втором проходе через цикл битовой маской станет значение '''«00000010»''', и операция будет выглядеть следующим образом: | ||
<syntaxhighlight lang="c | <syntaxhighlight lang="c"> | ||
00000010 | 00000010 | ||
& 10101010 | & 10101010 |
Версия от 18:17, 14 мая 2023
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Битовые маски[1]
Битовые маски используются, чтобы получить доступ к конкретным битам в байте. В частности, их используют для итерации, к примеру, при последовательной передаче байта данных через один контакт. В этом примере контакту нужно поменять свое состояние с HIGH на LOW для каждого передаваемого бита в байте. Это выполняется при помощи так называемых побитовых операторов и битовой маски.
Побитовые операторы – это такие операторы, которые выполняют логические функции на уровне битов. Среди стандартных побитовых операторов: И (&), ИЛИ (I), сдвиг влево (<<) и сдвиг вправо (>>).
Оператор И (&)
Если хотя бы у одного их входных значений в бите будет «0», в итоге этот «0» появится и в итоговом значении:
x: 10001101
y: 01010111
x & y: 00000101
Оператор ИЛИ (I)
Иногда его называют включающим ИЛИ. Если хотя бы у одного их двух входных значений в бите будет «1», в итоге этот «1» появится и в итоговом значении:
x: 10001101
y: 01010111
x | y: 11011111
Оператор для сдвига влево (<<)
Сдвигает значение влево на указанное количество позиций. Например:
y = 1010
x = y << 1
x = 0100
Как видите, здесь все байты сдвинулись на одну позицию влево, а бит, находящийся на крайней левой позиции, был удален.
Оператор для сдвига вправо (>>)
Работает идентично оператору для сдвига влево, но двигает биты в противоположную сторону, т.е. вправо.
y = 1010
x = y >> 1
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){ // если побитовое И дает «true»
digitalWrite(transmit,HIGH); // отправляем «1»
}
else{ // если побитовое И дает «false»
digitalWrite(transmit,LOW); // отправляем «0»
}
delayMicroseconds(bitDelay); // задержка
}
}
Здесь мы использует цикл for(), чтобы сделать несколько проходов по битовой маске. С каждым проходом через цикл мы сдвигаем значение в маске на одну позицию влево. В данном случае мы используем оператор <<=, который равнозначен, по сути, оператору <<, но за тем исключением, что делает оператор более компактным.
00000001
& 10101010
________
00000000
В итоге контакт получает значение «0». При втором проходе через цикл битовой маской станет значение «00000010», и операция будет выглядеть следующим образом:
00000010
& 10101010
________
00000010
И в итоге наш выходной контакт получит значение «1». Цикл продолжить делать проход за проходом для каждого бита в маске, пока «1» не сместится за левый край, а маска не превратится в «00000000». Тогда все 8 бит будут переданы и цикл завершится.