Refering to a bit by bit number
If we have a value X we can identify each bit within X as XjWe could either identify each bit within a byte as:
Or as:
right to left X7 X6 X5 X4 X3 X2 X1 X0 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).
left to right X0 X1 X2 X3 X4 X5 X6 X7 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
So
X7 X6 X5 X4 X3 X2 X1 X0 0 0 1 0 0 1 0 1 bit 7 of X (shown as X7) has the value 0To 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.
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 1e.g. calculating a mask with only bit X3 set
Using a traditional BASIC we could achive the above using
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 let X = 1 for J=1 to 3 X = X * 2 next JIn XCSB however we would use the left shift operator << and the expression:(1 << 3)to calculate the above mask of X3In 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 expressionX = X | (1 << 3)is converted into the PIC instructionbsf X, 3and the XCSB expressionX = X & ~(1 << 3)is converted into the PIC instructionbcf X, 3using a bit mask
Having calculated a bit mask we can use it to set, clear or test a bit withing a variableset 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 seeFor definition of X7, X6, X5 etc., see Refering to a bit by bit number
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 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 seeFor definition of X7, X6, X5 etc., see Refering to a bit by bit number
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 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)) != 0Looking 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)) != 0Looking step by step at the computation we seeFor definition of X7, X6, X5 etc., see Refering to a bit by bit number
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