Society of Robots - Robot Forum

Software => Software => Topic started by: spizzak on October 01, 2011, 04:59:25 PM

Title: Bitwise Operations
Post by: spizzak on October 01, 2011, 04:59:25 PM
I was reading through the $50 robot code and there's a line I don't understand.

TCCR1B = (1 << WGM13) | (1<<WGM12) | (1 << CS11);

WGM13, WGM12, and CS11 are all single bit registers as far as I can tell. Therefore either 1 or 0. If they are 1 then all those shifts are just shifts of one and then this line looks like the equivalent of (0b10 | 0b10 | 0b10) = 0b10.

Can someone please explain where I'm going wrong?

Thanks
Title: Re: Bitwise Operations
Post by: rbtying on October 01, 2011, 06:36:57 PM
I'm not exactly sure what you mean by a single bit register (usually registers are 8 bits, and bits are 1 bit...)

If you read the datasheet you'll realize that WGM13, for example, is an offset which, when shifted, gives the corresponding bit in the TCCR1B register.

I think you should rephrase to "WGM13, WGM12, and CS11 are all single bits in registers".
Title: Re: Bitwise Operations
Post by: joe61 on October 01, 2011, 09:07:02 PM
TCCR1B = (1 << WGM13) | (1<<WGM12) | (1 << CS11);

WGM13, WGM12, and CS11 are all single bit registers as far as I can tell. Therefore either 1 or 0. If they are 1 then all those shifts are just shifts of one and then this line looks like the equivalent of (0b10 | 0b10 | 0b10) = 0b10.

These identifiers are preprocessor macros. The preprocessor is a program that runs before the compiler and does text substitution on things that are in the code like

#define FOO bar

In this case, every time FOO shows up in the source code, it will be replaced by bar, and then the compiler will see bar (not FOO). The macros above are defined in a header file (which one depends on the model of avr being used). the processor expands TCCR1B to the address of that register. It expands the WGM* macros to the number of each bit. So given the following

TCCR1B = (1 << WGM13) |= (1 << WGM12);

The preprocessor first converts TCCR1B to a register address. Then it converts WGM13 & WGM12 to their bit numbers within TCCR1B.

The compiler then sees something like

0x2f = 8 | 4;

So bits 4 and 3 get set in the byte located at 0x2f.

Joe
Title: Re: Bitwise Operations
Post by: spizzak on October 02, 2011, 02:02:57 PM
I think you should rephrase to "WGM13, WGM12, and CS11 are all single bits in registers".

You're right that is what I meant to say, and I realize that they are offset in the register but that doesn't really change the fact that it's a single bit of data.

What Joe is saying, makes sense though. I didn't realize that they were macros. Anyway, I'll stick to giving the registers a binary number, but that does clear things up.

Thanks guys