cgccbit-manipulationavr

AVR bitwise C operations


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

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:

    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.