Skip to main content

Microcontrollers

Section 14.5 Bitwise Operations

Bitwise operators come in multiple forms. Binary bitwise operations (the term “binary operation” refers to the fact that there are two operands, not the datatype of any of the operands) include AND, OR, and XOR. In these operations, each bit of one operand is compared to each bit in the other operand and the logical operation is performed between those two values. Unary bitwise operations (operations that have only one operand) include NOT (where each individual bit is inverted) and bitshift operations.
Bitwise operations are used to manipulate binary values especially when only some values in a data byte need to be changed while leaving others alone. For this reason, they are used frequently when changing particular bits in PORTxn registers or when accessing the values stored in PINxn registers.

Subsection 14.5.1 Bitwise AND: &

The bitwise AND operator, & calculates the logical AND between each individual bit in the two operands. The operation c = a & b is depicted in Figure 14.5.1 for two 8-bit operands a and b. Because taking a logical AND with the number 0 results in a 0, the bitwise AND operation is used to selectively clear bits while leaving others alone.
An 8-bit value a is depicted as a series of 8 squares labeled a7 through a0. An 8-bit value b is depicted as a series of 8 squares labeled b7 through b0. There are 8 AND gates, each of which takes in inputs from the squares. For example, one of the AND gates has inputs of a7 and b7. And so on. The output of each AND gate is depicted of a series of 8 squares labeled c7 through c0.
Figure 14.5.1. A bitwise AND operation takes the logical AND of each corresponding bit of the two operands.

Subsection 14.5.2 Bitwise OR: |

The bitwise OR operator, | calculates the logical OR between each individual bit in the two operands. The operation c = a | b is depicted in Figure 14.5.2 for two 8-bit operands a and b. Because taking a logical OR with the number 1 results in a 1, the bitwise OR operation is used to selectively set bits while leaving others alone.
An 8-bit value a is depicted as a series of 8 squares labeled a7 through a0. An 8-bit value b is depicted as a series of 8 squares labeled b7 through b0. There are 8 OR gates, each of which takes in inputs from the squares. For example, one of the OR gates has inputs of a7 and b7. And so on. The output of each OR gate is depicted of a series of 8 squares labeled c7 through c0.
Figure 14.5.2. A bitwise OR operation takes the logical OR of each corresponding bit of the two operands.

Subsection 14.5.3 Bitwise XOR: ^

The bitwise XOR operator, ^ calculates the logical XOR between each individual bit in the two operands. The operation c = a ^ b is depicted in Figure 14.5.3 for two 8-bit operands a and b. Because taking a logical XOR with the number 1 results in a toggle, the bitwise XOR operation is used to selectively toggle bits while leaving others alone.
An 8-bit value a is depicted as a series of 8 squares labeled a7 through a0. An 8-bit value b is depicted as a series of 8 squares labeled b7 through b0. There are 8 XOR gates, each of which takes in inputs from the squares. For example, one of the XOR gates has inputs of a7 and b7. And so on. The output of each XOR gate is depicted of a series of 8 squares labeled c7 through c0.
Figure 14.5.3. A bitwise XOR operation takes the logical XOR of each corresponding bit of the two operands.

Subsection 14.5.4 Bitwise NOT: ~

The bitwise NOT operator, ~, acts to invert each individual bit of a single operand, as depicted in Figure 14.5.4 for an 8-bit operand a. The bitwise NOT operation is used to toggle all bits in a variable simultaneously.
An 8-bit value a is depicted as a series of 8 squares labeled a7 through a0. Each of these squares connects to the input of one of 8 NOT gates. The output of each NOT gate is depicted of a series of 8 squares labeled ~a7 through ~a0.
Figure 14.5.4. A bitwise NOT operation takes the logical NOT of each bit in a single operand.

Subsection 14.5.5 Bitshift Right: >>

The bitshift right operator, >>, shifts the operand to the right a specific number of places. When being bitshifted to the right, the number 0 will be shifted in to the most significant bit.

Example 14.5.5. Bitshifting right.

An 8-bit variable a is bitshifted right 3 times using the following code. (Note that the code utilizes a compound bitshift operation. Compound operators are described in Section 14.7.)
a >>= 3;
Figure 14.5.6 (top) depicts the initial values stored in the variable a. Figure 14.5.6 (bottom) depicts the values stored in the variable a after the bitshift operation has finished executing.
Top: An 8-bit value a is depicted as a series of 8 squares labeled a7 through a0. Bottom: An 8-bit value a is depicted as a series of 8 squares. The left 3 squares are labeled 0. The next squares are labeled a7, a6, a5, a4, and a3, in that order.
Figure 14.5.6. Initial (top) and final (bottom) values stored in an 8-bit variable a after a bitshift right operation.

Subsection 14.5.6 Bitshift Left: <<

The bitshift left operator, <<, shifts the operand to the left a specific number of places. When being bitshifted to the left, the number 0 will be shifted in to the least significant bit.

Example 14.5.7. Bitshifting left.

An 8-bit variable a is bitshifted left 5 times using the following code. (Note that the code utilizes a compound bitshift operation. Compound operators are described in Section 14.7.)
a <<= 5;
Figure 14.5.8 (top) depicts the initial values stored in the variable a. Figure 14.5.8 (bottom) depicts the values stored in the variable a after the bitshift operation has finished executing.
Top: An 8-bit value a is depicted as a series of 8 squares labeled a7 through a0. Bottom: An 8-bit value a is depicted as a series of 8 squares. The left 3 squares are labeled a2, a1, and a0, in order. The next squares are labeled 0.
Figure 14.5.8. Initial (top) and final (bottom) values stored in an 8-bit variable a after a bitshift left operation.