In AVR Tutorials I often see:
DDRA |= (1 << PA0); PORTA |= (1 << PA0);
used instead of:
DDRA |= PA0; PORTA |= PA0;
What is the purpose of this?
Equates to shifting 1 left by zero bits, leaving an OR with the value 1 to set the first bit. Whereas the following line:
Is doing an OR with zero so won't change the registers at all.
Why do they do this? Likely because everyone else they ask for help or learned from did it that way. And because the standard defines are weirdly done.
Shifting by a number, typically a decimal number, will move that value over by that many binary positions.
Now, we need to see what PA0 - PA7 are defined as. These are typically defined in the specific header for your specific microcontroller, included via io.h or portpins.h
They are defined as their numerical position, in decimal!
They cannot be directly assigned, as bits, because they are not single bits.
If you were to do
See the problem? You just turned on PA0, PA1, PA2, instead of PA7.
The Smarter way
The other, better microcontroller, the MSP430, has a standard define of bits as:
These are define as their binary position, in hex. BIT0 is 0b0001, not like PA0, which is 0. BIT7 is 0b10000000, not like PA7, which is 0b111.
So direct assignments like
Your question has already been answered, but I want to present an alternative that was a bit much for a comment. One of the first things I do when I start an embedded project is define my bit set and clear macros.
Using the macros, your code becomes:
The end result is a bit set instruction in assembly.
Have a look here: http://nongnu.org/avr-libc/user-manual/FAQ.html#faq_use_bv
Those macros are used when setting particular bits in a register. For example: if PORTA is 8-bits wide, then PA0 is the lowest bit, PA7 is the highest. To set PA0 to 1 you have to write ("or-write") 0x01 to the register. If you want to set PA2, then you need a value that in binary will have a one in the right place, for PA2 that will be 0x04.
People don't want to remember which bit has a particular position (as other registers may have different bit names eg. CS12, CS10, ADSC etc.) so they use more abstract names. Instead of typing: PORTA = 0x04 you type PORTA = _BV(PA2) and you instantly know that it will turn pin PA2 high.