Go Down

Topic: Please explain "TCCR1B |= (1 << CS12);" (Read 2205 times) previous topic - next topic

Robin2

I realize that this code sets the bit called CS12 in the TCCR1B register.

But I can't find any explanation of why it is coded like that. I would expect the << operator to shift all of the bits in the register to the left but clearly that doesn't happen here.

Perhaps someone can explain it.

...R

KeithRB

The (1<<CS12) creates a temporary operand that contains a 1 in the CS12 position. That temporary is then ORed with the TCCR1B variable(register) setting the CS12 bit and leaving the rest of TCCR1B alone.

Hillridge

KeithRB is correct, but here's a step by step breakdown in case you wanted more detail:

CS12 has a value of 2 since it represents bit 2 of the TCCR1B register. 
(1 << CS12) takes the value 1 (0b00000001) and shifts it left 2 times to get (0b00000100).
The order of operations dictates that things in () happen first, so this is done before the "|=" is evaluated.
So now we get TCCR1B |= 0b00000100, which is the same as TCCR1B = TCCR1B | 0b00000100.
Since "|" is "OR", all the bits other than CS12 in TCCR1B are unaffected.

You can do this exact same thing with any of these:
Code: [Select]

bitSet(TCCR1B, CS12);
TCCR1B |= _BV(CS12);
TCCR1B |= bit(CS12);


I think TCCR1B |= CS12; would work as well, but it's not good practice and may throw a warning.

Robin2

Thank you for the comprehensive explanation and you also answered my follow-up question

...R


KeithRB is correct, but here's a step by step breakdown in case you wanted more detail:

CS12 has a value of 2 since it represents bit 2 of the TCCR1B register. 
(1 << CS12) takes the value 1 (0b00000001) and shifts it left 2 times to get (0b00000100).
The order of operations dictates that things in () happen first, so this is done before the "|=" is evaluated.
So now we get TCCR1B |= 0b00000100, which is the same as TCCR1B = TCCR1B | 0b00000100.
Since "|" is "OR", all the bits other than CS12 in TCCR1B are unaffected.

You can do this exact same thing with any of these:
Code: [Select]

bitSet(TCCR1B, CS12);
TCCR1B |= _BV(CS12);
TCCR1B |= bit(CS12);


I think TCCR1B |= CS12; would work as well, but it's not good practice and may throw a warning.

KeithRB

CS12 is a bit position - a number - not a mask. If it for example, '3', it has the binary value of 0b11, and if you or *that* with TCCR1B, you will not get the same as the original expression, i.e., CS12 != (1<<CS12) .

Go Up