@@ -186,31 +186,24 @@ case). This is done in two steps. First, we must clear the current value of
186186bits 6-7, because it may hold some value already. Then we must set bits 6-7
187187to the value we want.
188188
189- So, first, we must set bit range 6-7 to zero. How do we set
190- a number of bits to zero? In four steps:
191-
192- - Get a number that has N contiguous bits set:
193- - 1 for 1 bit: ` 0b1 ` ,
194- - 3 for 2 bits: ` 0b11 ` ,
195- - 7 for 3 bits: ` 0b111 ` ,
196- - 15 for 4 bits: ` 0b1111 ` ,
197- - and so on: generally, for N bits, the number is ` 2^N - 1 `
198- So, for 2 bits it is number ` 3 ` , or ` 0b00000000000000000000000000000011 `
199- - Shift that number left. If we need to set bits X-Y, then shift on X positions
200- left. In our case, shift on a 6 positions left: ` (3 << 6) ` , or
201- ` 0b00000000000000000000000011000000 `
202- - Invert the number: turn zeros to ones, and ones to zeroes:
203- ` ~(3 << 6) ` , or ` 0xb11111111111111111111111100111111 `
204- - Now, perform a "logical AND" operation of the register with our number. Bits
205- 6-7, AND-ed with 0, will give zero - that's what we want! All other bits,
206- AND-ed with 1, will retain their current value: ` REG &= ~(3 << 6) ` . Retaining
207- values of all other bits is important: we don't want to change other settings
208- in other bit ranges!
209-
210- So, in general, if we want to clear bits X-Y (set them to zero), do:
189+ So, first, we must set bit range 6-7 (two bits at position 6) to zero. How do
190+ we set a number of bits to zero? In four steps:
191+
192+ | Action | Expression | Bits (first 12 of 32) |
193+ | - | - | - |
194+ | Get a number with N contiguous bits set: ` 2^N-1 ` , N=2 | ` 3 ` | ` 000000000011 ` |
195+ | Shift that number X positions left | ` (3<<6) ` | ` 000011000000 ` |
196+ | Invert the number: turn zeros to ones, and ones to zeroes | ` ~(3<<6) ` | ` 111100111111 ` |
197+ | Logical AND with existing value | ` VAL &= ~(3<<6) ` | ` xxxx00xxxxxx ` |
198+
199+ Note that the last operation, logical AND, turns N bits at position X to zero
200+ (because they are ANDed with 0), but retains the value of all other bits
201+ (because they are ANDed with 1). Retaining existing value is important, cause
202+ we don't want to change settings in other bit ranges. So in general, if we want
203+ to clear N bits at position X:
211204
212205``` c
213- PERIPHERAL->REGISTER &= ~(NUMBER_WITH_N_BITS << X);
206+ PERIPHERAL->REGISTER &= ~(( 2 ^N - 1 ) << X);
214207```
215208
216209And, finally, we want to set a given bit range to the value we want. We
0 commit comments