سؤال

I have a question about ATMEGA328P programing 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!!

Lets say:

DDRC = 0b11001100;

I have to check initial bit condition before making bitwise operation before shitfing any a bit to location? for example

DDRC |= (1<<DDRC0);

and we get:

11001100
10011001

=

11011101

Is it right? if we know anyway a bit combination to simply write and maybe its faster and simpler?:

0b11001101
هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

No, it is slower.

The reason for the usual syntax like DDRC |= (1<<DDRC0); is that the right side contains compile time constants. The compiler will convert it to a number before the processor sees it, so the processor doesn't perform the shift.

As for using the |= assignment operator, there may be an extra read operation. But the cost for efficiency for a one time assignment is vastly less than the cost to maintain the source code.

I'm not sure what you are doing with the arithmetic in your question. The statement takes the original contents of DDRC and ors it with something like 0b00000001 (where the 1 is in the DDRC0 position), and assigns it back to DDRC.

There are more efficient ways of setting a bit and clearing a bit on many microcontrollers that does not involve the other bits, ie you don't have to use OR and AND to maintain the other bits.

There are AVR machine instructions to set a bit and clear a bit of a register, namely "SBR" and "CBR". Also see "CBI" and "SBI" if you need to set an IO register. I'm not sure if the AVR compiler is smart enough to convert C-style operations which operate on bytes into individual bit statements. But usually there are intrinsics to do this. I'm not an AVR user.

Perhaps you can use gcc asm() to insert SBR and CBR. But I wouldn't bother with this unless you need to save a cycle in an ISR. It's not worth the headache.

See page 127 here http://www.atmel.com/images/doc0856.pdf and page 272 here http://www.ic.unicamp.br/~celio/mc404-2008/docs/avr-libc-user-manual-1.4.6.pdf

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top