Bit Numbers

Refering to a bit by bit number

If we have a value X we can identify each bit within X as Xj

We could either identify each bit within a byte as:

right to left

X7 X6 X5 X4 X3 X2 X1 X0
Or as:
left to right

X0 X1 X2 X3 X4 X5 X6 X7
The right to left representation is prefered however because by selecting the bit numbers of each bit within X to start at 0 and increasing from right to left, each bit Xj has the value 2n (where n is equal to j) (see a more detailed description of binary).
i.e.

X0 has the value 1 which is the same as 20

X1 has the value 2 which is the same as 21

X2 has the value 4 which is the same as 22

X3 has the value 8 which is the same as 23

The XCSB expression (1 << j) has the same effect as raising 2 to the (integer) power of j

Usefully, the PIC microcontroller has native instructions that use the right to left representation for selecting bits within bytes.

If we assign the value 00100101 to X we can pick out specific bits as

X7 X6 X5 X4 X3 X2 X1 X0
0 0 1 0 0 1 0 1
So
bit 7 of X (shown as X7) has the value 0
bit 5 of X (shown as X5) has the value 1
bit 1 of X (shown as X1) has the value 0
bit 0 of X (shown as X0) has the value 1
To generate a value with a specific bit set to 1, we would find the bit number of the bit we are interested in (call this j) and calculate a mask pushing the bit left until it is in the required bit position.

e.g. calculating a mask with only bit X3 set

  X7 X6 X5 X4 X3 X2 X1 X0
start 0 0 0 0 0 0 0 1
shift left 0 0 0 0 0 0 0 0 1
shift left 1 0 0 0 0 0 0 1 0
shift left 2 0 0 0 0 0 1 0 0
shift left 3 0 0 0 0 1 0 0 0
finish 0 0 0 0 1 0 0 0
Using a traditional BASIC we could achive the above using
	let X = 1

	for J=1 to 3
		X = X * 2
	next J
In XCSB however we would use the left shift operator << and the expression:
	(1 << 3)
to calculate the above mask of X3

In general if we want to calculate a mask for bit Xj we would use the expression:

	(1 << j)
XCSB actualy trys very hard to convert bit manipulation expressions into single native PIC instructions.
e.g. the XCSB expression
	X = X | (1 << 3)
is converted into the PIC instruction
	bsf	X, 3
and the XCSB expression
	X = X & ~(1 << 3)
is converted into the PIC instruction
	bcf	X, 3

using a bit mask

Having calculated a bit mask we can use it to set, clear or test a bit withing a variable

set bit

To set a bit we would use the binary OR operator

e.g.
	X = 0x21
	J = 2
	X = X | (1 << J)
Looking step by step at the computation we see
      X7 X6 X5 X4 X3 X2 X1 X0     E7 E6 E5 E4 E3 E2 E1 E0
X = 0x21   0 0 1 0 0 0 0 1                  
E = (1 << J)                     0 0 0 0 0 1 0 0
X = X | E   0 0 1 0 0 1 0 1             x    
For definition of X7, X6, X5 etc., see Refering to a bit by bit number

clear bit

To clear a bit we would use the binary NOT and AND operators

e.g.
	X = 0x25
	J = 2
	X = X & ~(1 << J)
Looking step by step at the computation we see
      X7 X6 X5 X4 X3 X2 X1 X0     E7 E6 E5 E4 E3 E2 E1 E0
X = 0x25   0 0 1 0 0 1 0 1                  
E = (1 << J)                     0 0 0 0 0 1 0 0
E = ~E                     1 1 1 1 1 0 1 1
X = X & E   0 0 1 0 0 0 0 1             x    
For definition of X7, X6, X5 etc., see Refering to a bit by bit number

test bit

To test a bit we would use the binary AND and NOT EQUAL operators

e.g.
	X = 0x21
	J = 2
	T = (X & (1 << J)) != 0
Looking step by step at the computation we see
      X7 X6 X5 X4 X3 X2 X1 X0     E7 E6 E5 E4 E3 E2 E1 E0     T7 T6 T5 T4 T3 T2 T1 T0
X = 0x21   0 0 1 0 0 0 0 1                                    
E = (1 << J)                     0 0 0 0 0 1 0 0                  
E = X & E             x       0 0 0 0 0 0 0 0                  
T = (E != 0)                     x x x x x x x x   0 0 0 0 0 0 0 0
e.g.
	X = 0x25
	J = 2
	T = (X & (1 << J)) != 0
Looking step by step at the computation we see
      X7 X6 X5 X4 X3 X2 X1 X0     E7 E6 E5 E4 E3 E2 E1 E0     T7 T6 T5 T4 T3 T2 T1 T0
X = 0x25   0 0 1 0 0 1 0 1                                    
E = (1 << J)                     0 0 0 0 0 1 0 0                  
E = X & E             x       0 0 0 0 0 1 0 0                  
T = (E != 0)                     x x x x x x x x   0 0 0 0 0 0 0 1
For definition of X7, X6, X5 etc., see Refering to a bit by bit number