Bitwise operations are always a little tricky to make sense of at first.
To SET some bits, you can either:
• clear them using bitwise AND
• set them using bitwise OR
To GET some bits, you need to SHIFT and clear.
Specifically, your object is combining two integers.
1 2
|
unsigned counter; // 4 bits of data CCCC
unsigned light_id; // 4 bits of data LLLL
|
Put them together to get an 8-bit integer.
|
unsigned counter_and_light_id; // 4 MSB = counter, 4 LSB = light id: CCCC LLLL
|
CLEAR operations:
• Clear the counter:
counter_and_light_id &= 0x0F;
• Clear the light id:
counter_and_light_id &= 0xF0;
So, 0010 1000 (counter = 3, light id = green light) AND 0000 1111 becomes 0000 1000 (counter = 0, light id = green light).
Likewise, 0010 1000 AND 1111 0000 becomes 0010 0000 (counter = 3, light id = red start off).
Once you have cleared something, you can SET it:
• Set the counter:
counter_and_light_id |= 5 << 4;
• Set the light id:
counter_and_light_id |= GREEN_LIGHT;
GET operations:
• Get the counter:
counter_and_light_id >> 4
(0010 1000 >> 4 → 0000 0010)
• Get the light id:
counter_and_light_id & 0x0F
(0010 1000 AND 0000 1111 → 0000 1000)
Hopefully that makes sense.
To make life easy, you should make yourself some functions to split and combine the two values:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
unsigned get_counter( unsigned counter_and_light_id )
{
return counter_and_light_id >> 4;
}
unsigned get_light_id( unsigned counter_and_light_id )
{
return counter_and_light_id & 0x0F;
}
unsigned combine_counter_and_light_id( unsigned counter, unsigned light_id )
{
return (counter << 4) | (light_id);
}
|
This becomes easy to use:
1 2 3 4
|
counter_and_light_id = combine_counter_and_light_id(
get_counter ( counter_and_light_id ) + 1,
get_light_id( counter_and_light_id )
);
|
(As an added bonus, to simply increment the counter, just add n << 4 to it:
1 2 3 4 5
|
unsigned increment_counter( unsigned counter_and_light_id, unsigned n = 1 )
{
counter_and_light_id += n << 4; // increment the counter
return counter_and_light_id & 0xF0; // make sure the counter value never exceeds 4 bits
}
|
|
counter_and_light_id = increment_counter( counter_and_light_id );
|
Hope this helps.