1

I'm new to bit register manipulation and am trying to set input and output values of some pins. The code sample I have on hand does it this way::

DDRD |= (1 << 2);                   
DDRD |= (1 << 4);                   
DDRD &= ~(1 << 5);                   
PORTD |= (1 << 2);  
PORTD &= ~(1 << 4);         
PORTD &= ~(1 << 5);  

I have two questions:

  1. This is part of a code where I'm attempting to determine the time for a capacitor's discharge between pins 2 and 4. The arduino helpfiles mention that there may be a benefit to triggering both pins at once. Therefore: Is it is it possible to do DDRD |= B00010100; and PORTD |= B00000100; or combine the first three DDRD lines so it happens simultaneously, or does it have to be separately called?

  2. Why is it PORTD &= ~(1 << 4) and not PORTD |= ~(1 << 4);Can this conflict with the previous state of PORTD.

5
  • 1
    (1 << 4) is 00010000, they are interchangeable ... ~(1 << 4) is the inverse 11101111 ... think about what the OR function does and what the AND function does
    – jsotola
    May 28, 2023 at 22:11
  • 2
    so it happens instantaneously ... maybe you wanted to say simultaneously
    – jsotola
    May 28, 2023 at 22:14
  • OK, thanks. Writing this out in a simplified form helps. Since & only returns 1 if a = 1, and b = 1, therefore 0 & 0 = 0, and 1 & 0 = 0 which is exactly what we want no matter what happens. On the other hand 1 & 1 = 1, so anything on remains on, and 0 & 1 = 0 so what was off remains off.
    – Letshin
    May 28, 2023 at 23:03
  • Yes, sorry simultaneously. I was quoting from the Arduino help page but didn't add its context. If I'm timing a capacitor discharge between pins 2 and 4, is there a benefit to triggering both pins at once instead of doing it line by line? eg B00010100 vs each pin individually?
    – Letshin
    May 28, 2023 at 23:05
  • Its context for the question. The original is because I don't know how it affects timings. It appears my question wasn't properly phrased from your feedback. I've amended it accordingly. Thanks.
    – Letshin
    May 29, 2023 at 10:17

1 Answer 1

2
DDRD |= (1 << 2);                   
DDRD |= (1 << 4);

The equivalent to that is:

DDRD |= (1 << 2) | (1 << 4);

However I prefer bit because it does the shift for you:

DDRD |= bit(2) | bit(4);

Why is it PORTD &= ~(1 << 4) and not PORTD |= ~(1 << 4);

PORTD &= ~(1 << 4) is turning a bit off. First you invert the sense of the bit with the ones complement operator (~) and then by anding it, it means that all bits are retained except that one. So this is basically turning bit 4 off. If you used |= it would turn all of the other bits on.

Equivalent code:

PORTD &= ~bit(4);

Based on your example you meant bit 5 not bit 4.


PORTD |= (1 << 2);  
PORTD &= ~(1 << 4);         
PORTD &= ~(1 << 5);  

That is turning on bit 2, and turning off bits 4 and 5, and leaving the rest unchanged.


Thanks. In that case would DDRD &= B00000000; DDRD |= B00010100; have a similar result ...

If you do DDRD &= B00000000; then you are setting all bits to zero. So the simple equivalent to the above would be:

DDRD = B00010100;

This is a straight assignment, so you don't need to clear any bits.

Or, you could write:

DDRD = bit(2) | bit(4);

Do you know if bit() faster or is it cleaner compared to 1 << x; or is it better for me to hook up a scope to test this myself?

It is exactly the same. bit is just a #define in the Arduino.h file, as follows:

#define bit(b) (1UL << (b))

So all it does is save you writing the brackets and the shift left operator. It expands out to the same as what you were writing and thus will execute at the same speed, and take the same amount of memory.

4
  • Thanks. In that case would DDRD &= B00000000; DDRD |= B00010100; have a similar result to your DDRD |= bit(2) | bit(4); DDRD &= bit(3) | bit(6); In my mind this first sets everything to input, then sets bits 2 and 4 to output. The malus would be that it changes all other settings due to the first DDRD &= B00000000 section?
    – Letshin
    May 29, 2023 at 10:07
  • 1
    See expanded answer.
    – Nick Gammon
    May 29, 2023 at 12:05
  • Thanks. Do you know if bit() faster or is it cleaner compared to 1 << x; or is it better for me to hook up a scope to test this myself?
    – Letshin
    May 30, 2023 at 15:25
  • 1
    @Letshin See additional paragraph in answer.
    – Nick Gammon
    May 30, 2023 at 22:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.