Reputation: 2315
What does the following do?
PORTB = (PORTB & ~0xFC) | (b & 0xFC);
PORTD = (PORTD & ~0x30) | ((b << 4) & 0x30);
AFAIK, the 0xFC is a hex value. Is that basically saying 11111100, hence PORTD0-PORTD1 are outputs but the rest are inputs.
What would a full explanation of that code be?
Upvotes: 1
Views: 1355
Reputation:
The first line actually sets the state of port's PB7-PB2 lines. The current state of PORTB is first masked using ~0xFC
= 0x03
, so all bits, but 0 and 1, are reset.
The second step is masking b
using 0xFC, so bits 0 and 1 are always 0. Then the values are OR'ed together. Effectively, it sets PB7-PB2 from b[7]..b[2], while keeping the current state of PB1 and PB0 untouched.
Note, that the PORTB register bits serve different purposes depending on the pin direction configured via the DDRB register. For output pins, it simply controls the pin state. For input pins, PORTB controls the pin's pull-up resistor. You have to enable this pull-up resistor if, for example, you have a push button connected between the pin and ground - this way the input pin is not floating when the switch is open.
Upvotes: 0
Reputation: 1194
PORTB = (PORTB & ~0xfc) | (b & 0xfc);
Breaking it down:
PORTB = PORTB & ~0xFC
0xFC = 1111 1100
~0xFC = 0000 0011
PORTB = PORTB & 0000 0011
Selects the lower two bits of PORTB
.
b & 0xFC
0xFC = 1111 1100
Selects the upper 6 bits of b.
ORing them together, PORTB
will contain the upper six bits of b and the lower two bits of PORTB
.
PORTD = (PORTD & ~0x30) | ((b << 4) & 0x30);
Breaking it down:
PORTD = PORTD & ~0x30
0x30 = 0011 0000
~0x30 = 1100 1111
PORTD = PORTD & 11001111
Selects all but the 4th and 5th (counting from 0) bits of PORTD
(b << 4) & 0x30
Consider b as a field of bits:
b = b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0
b << 4 = b3 b2 b1 b0 0 0 0 0
0x30 = 0011 0000
(b << 4) & 0x30 = 0 0 b0 b1 0 0 0 0
ORing the two pieces together, PORTD
will contain the 0th and 1st bits of b
in its 4th and 5th bits and the original values of PORTD in the rest.
Upvotes: 4