Go Down

Topic: Please explain "TCCR1B |= (1 << CS12);" (Read 2413 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy