AVR bitwise C operations
avr, bit-manipulation, c, gcc
Solution
for the sake of the demonstration:
here are two code compiled with avr-gcc-4.7.2:
void main() {
DDRC |= (1<<5);
}
and another:
void main() {
DDRC |= 0b100000;
}
% diff -s t2.s t.s
Files t2.s and t.s are identical
that's because `1<<N` is detected at compile time, and transform to its constant equivalent, making both expressions identical when sent to the microcontroller.
About operations, please have a look at truth tables:
| a b -> a&b | | a b -> a|b |
| 0 0 0 | | 0 0 0 |
| 0 1 0 | | 0 1 1 |
| 1 0 0 | | 1 0 1 |
| 1 1 1 | | 1 1 1 |
the hint to remember both truth tables is the following:
- if one of the operands is a `0` and you're doing a `&`, then the result will be `0` (force to 0)
- if one of the operands is a `1` and you're doing a `|`, then the result will be `1` (force to 1)
So if you take an example a bit more complicated:
101010 | 010101 = 111111
101010 & 010101 = 000000
and finaly, when you want to set a bit:
REGISTER = 00000001
REGISTER |= 1<<5 <=> REGISTER = 00000001 | 00100000
REGISTER == 00100001
if you want to reset that bit:
REGISTER &= ~(1<<5) <=> REGISTER = 00100001 & ~(00100000) <=> REGISTER = 00100001 & 11011111
REGISTER == 00000001
I hope it's making more sense… Though you'd better lookup for a course on combinatory logics, which is the basic to perfectly handle when doing embedded programming.
Now to answer your question:
if we know anyway a bit combination to simply write and maybe its faster and simpler?:
it's not necessarily faster, and not really simpler.
Consider the following made up register FOO:
7 6 5 4 3 2 1 0
[ A | B | C | D | W | X | Y | Z ]
now consider that we have build a header that has preprocessor variables with the right values:
FOOZ = 0
FOOY = 1
FOOX = 2
FOOW = 3
FOOD = 4
FOOC = 5
FOOB = 6
FOOA = 7
and now we need to set up `A`, `C` and 'X' bits, which can be done as follows:
FOO |= 1<<FOOA | 1<<FOOC | 1<<FOOX
instead of:
FOO |= 0b10100100
which could more easily lead to errors.
Problem
I have a question about ATMEGA328P programming in Atmel Studio 6.1. Isn't it faster to assign a binary to register than making shift operation? If I understand correctly, but please correct this!! Let's say: ``` DDRC = 0b11001100; ``` I have to check initial bit condition before making bitwise operation before shifting any a bit to location? For example ``` DDRC |= (1<<DDRC0); ``` and we get: ``` 11001100 10011001 = 11011101 ``` Is this right? If we know anyway a bit combination to simply write and maybe it's faster and simpler?: ``` 0b11001101 ```