I am getting started learning more about AVR ATMEGA programming.
Reading an article about the inner workings of Arduinos, I am learning how the shiftOut
method is structured. I am kind of familiar with bitwise operations so far, but I have an expression I do not understand yet:
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
uint8_t i;
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST) {
PORTD |= !!(val & (HIGH << i));
} else {
PORTD |= !!(val & (HIGH << (7 - i)));
}
PORTB |= (HIGH << clockPin);
PORTB ^= (HIGH << clockPin);
}
}
The line PORTD |= !!(val & (HIGH << i));
is not 100% clear to me. I understand that i set the i-th bit High on PORTD but what das the !!
mean and val&(HIGH <<i))
I know this might sound basic, but can you please help me out?
1 Answer 1
In C, !
is the logical negation operator: !x
has the value 1 if x
is falsy (i.e. zero), and the value 0 if x
is truthy (i.e. non-zero). !!x
has just two negations back-to-back, which gives the same logical truth value as x
itself, but it collapses all true values to 1
. (It's worth remembering that e.g. 2
, 0x1000
, and -123
are all true in C.)
(val & (HIGH << i))
This is just HIGH
shifted left by i
bits, and that value anded with val
. i.e. if HIGH
is 1
, it picks the i
th bit of val
(counting from zero).
So, e.g. if i
is 3, (val & (1 << i))
might be 0x08
, and the following !!
would collapse that to 1
.