Bit Manipulation in 'C'
'C' bit operators
OP symbol
&
|
^
>> n
<< n
~
Description
AND
OR
XOR
shift bits right n places
shift bits left n places
complements (invert all bits)
Example
y = y & 0xF7;
y = y | 0x08;
y = y >> 4;
y = y << 2;
y = ~y;
Only use bit operators with integer data types - Not real data types.
Note: In 'C' binary operators(such as y = y OP z;) can be written as in a
shortened form: y OP= z;
E.g.'s
y = y + 7;
y+=7;
y = y & 0x80;
y &= 0x80;
y = y >> 4;
y >>= 4;
3-1
Masking for bit manipulation
A mask is a pattern of 0's and 1's
Use OR ('|')and a mask value to set selected bits to '1'
Use AND ('&') and a mask value to set selected bits to '0'
Use XOR(^) to toggle bits (0 -> 1 and 1-> 0)
OR
B Output
AND
B Output
XOR
B Output
0
0
1
0
1
0
0
1
1
0
0
1
0
1
0
0
0
0
0
0
1
0
1
0
0
1
1
0
3-2
Shift Operations
<< shift left
used
to move bits to the left - lose MSB(most
significant bit) and gain new LSB(least significant bit)
New LSB = 0 for all data types.
can be used for multiply by 2 for each shift.
>> shift right
used
to move bits to the right - lose LSB and gain
new MSB (Note: new MSB = 0 for unsigned integer
data types, or previous MSB for signed types).
can be used for divide by 2 for each shift.
3-3
Bit Masking - Setting bits to 1
Setting bits to 1 using the OR (|) bit-wise operator
General format: value = value | mask;
Shorthand : value |= mask;
Mask : '1' to set a bit, '0' to leave bit unchanged.
Example: Controlling a single bit (Note var is an integer data type.)
To set bit 5 to '1'
the mask is 0000.0000100000
var= var | 0x20; //mask expressed as hexadecimal value
or shortended form
var |= 0x20;
Is often written using the shift left operator :var |= (1UL << 5); // note the brackets to force shift before ORing
1UL - UL represents unsigned long i.e. 32 bit representation of 1
<< 5 - shift bit pattern 5 places to the left.
- result is 000.00100000 or 0x00000020
3-4
Bit Masking - Setting bits to 0
Setting bits to 0 using the AND (&) bit-wise operator
General format: value = value & mask;
Shorthand : value &= mask;
Mask : '0' to clear a bit, '1' to leave bit unchanged
Example: Controlling a single bit (Note var is an integer data type.)
To set bit 5 to '0'
For a 32bit integer the mask is 11111111111111111111111111011111
var = var & 0xFFFFFFDF;
or
var &= 0xFFFFFFDF;
or
var &= ~0x20;
or
var &= ~(1UL << 5);
3-5
To set and clear multiple bits
Set bits 1 and 4 of var
var |= ((1UL << 1) | (1 UL << 4));
Clear bits 1 and 17 of var
var &= ~( (1UL << 1) | (1UL << 17) );
what do these do?
1.
2.
3.
4.
5.
6.
7.
var
var
var
var
var
var
var
|=
&=
|=
&=
|=
&=
|=
((1UL << 0) | (1UL << 5) | (1UL << 12) );
~((1UL << 0) | (1UL << 5) | (1UL << 12) );
(3UL << 6);
~ (3UL << 2 * 3);
(1UL << 6) | (1UL << 7) | (1UL << 8);
~(3UL << 2*10);
(1UL << 2*10);
var &= ~((3UL << 2*2) | (3UL << 2*3) | (3UL << 2*6) | (3UL << 2*7));
var |= ((1UL << 2*2) | (1UL << 2*3) | (1UL << 2*6) | (1UL << 2*7));
3-6
Some for you to try
Write expressions to perform the following
operations on a variable x.
1.
2.
3.
4.
5.
6.
set bit 11
clear bit 13
set bits 6 and 10
clear bits 13 and 14
set bits 4,5,6, and 7
set bit 2 and clear bit 3
3-7
Input Masking
Used to test the value of a single bit.
Use AND (&) and a mask to isolate the selected bit
value & mask
Used in input Polling to test bit status
set bit(s) to be tested to '1', all other bits to '0'
Example: Testing bit 3
mask is 00001000 (0x08) or (1UL << 3)
Two possible results 00000000 or 00001000 when ANDED
I.e. zero or non-zero
Loop while bit is '0', exit when bit becomes 1
while ( (reg & (1UL << 3)) == 0) { ; }
Loop while bit is '1', exit when bit becomes 0
while ( (reg & (1UL << 3)) != 0) { ; }
3-8
Testing multiple bits
use a mask with each bit to be tested set to 1
test for bits 3 and 7 both at logic 0
if
test for bits 4 and 6 both at logic 1
if
( (reg & (1<<3))==0) && (reg & (1<<7) == 0) ) {
( (reg & (1<<4))!=0) && (reg & (1<<6) == 0) ) {
test if either bit 3 or bit 7 at logic 0
if
( (reg & (1<<3))==0) || (reg & (1<<7) == 0) ) {
3-9
An Exercise
A32 bit register(REG) is interfaced to the following peripherals:A motor connected to bit 7 (0 is off, 1 is on)
An led connected to bit 0 (0 is off, 1 is on)
Two switches S1 and S2 connected to bits 1 and 2 respectively that
generate either logic 0 or 1 inputs.
Assume inputs start at logic 0 and all output are initialised to 0.
Write C code to perform the following steps:
1.
2.
3.
4.
5.
6.
7.
8.
loop waiting while switch S1 is at logic 0, end loop when S1 becomes 1.
Now turn on the led
loop waiting until both switches are at logic 1
Now turn on the motor
Loop waiting until either of the switches change to logic 0
Turn of the motor and the led
loop until both switches are at logic 0
start back at step 1
3-10