@@ -186,31 +186,24 @@ case). This is done in two steps. First, we must clear the current value of
186
186
bits 6-7, because it may hold some value already. Then we must set bits 6-7
187
187
to the value we want.
188
188
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:
211
204
212
205
``` c
213
- PERIPHERAL->REGISTER &= ~(NUMBER_WITH_N_BITS << X);
206
+ PERIPHERAL->REGISTER &= ~(( 2 ^N - 1 ) << X);
214
207
```
215
208
216
209
And, finally, we want to set a given bit range to the value we want. We
0 commit comments