HOME

ATmega328P Register Bit Manipulation in C:  Ports, Pins, and Direction (Input/Output)

Clearing a bit means changing it to 0.

Setting a bit means changing it to 1.

Names like PORTB, DDRB, etc. are taken from C:\users\<yourname>\.platformio\packages\toolchain-atmelavr\avr\include\avr\ io.h and iom328p.h

Objective

C Code Example

Comment

More Info

Turn on the first 6 LEDs of PORTB.

DDRB = 0b00111111; or

DDRB = 0x3F;

 

PORTB=0b00111111;

The lower six LEDs, PORTB0 to PORTB5 (Arduino D8 through D13, ATmega328P pins 14 through 19), are enabled with a logical 1 (HIGH).

We first set the data direction register for each pin in PORTB using "DDRB=", and then we set the pin states using "PORTB=".

Pins PORTB6 and PORTB7 (pins 9 and 10) can be used for LEDs, etc., unless you're running the ATmega328P at 16MHz, in which case a crystal oscillator must be attached to these pins (as they are on my breadboard).

"0b" means binary.

"0x" means hexadecimal or hex for short. "0x3F" is equivalent to "0b00111111".

Illuminate a single LED attached to a PORTBpin. LED_Port = (1 << J);

Code Example: If J = 2, then "bit-shift roll" is bit 2 of the Port.

Bit 2, whether 0 or 1, will become 1.

If using PORTB (ATmega328P pins 14 to 19, pin 9 & pin 10), bit 2 would match PB2 which is pin 16 (Arduino IDE assigned pin D10).

Port bits:       76543210. (Positions.)

Affected bit:  00000100. Affected bit is bit 2, third from the right. This bit is now set to a 1.

File "iom328p.h" contains the port bit assignments for the ATmega328P microcontroller.

 

_BV() macro is defined as "#define _BV(bit)  (1 << (bit))"

Code Example for bit 2: "LED_Port = _BV(2)"

Set, clear, toggle or invert one or more Port pins.  

Bitwise Logical Operators and their C language symbols:

OR is "|"

AND is "&"

XOR is "^"

NOT is "~"

XOR = Exclusive OR: Same as OR except if both inputs are ones then output is 0.

 

NOT inverts the bit: each 0 becomes 1 and vice versa.

Set a Port bit to 1 without disturbing the other bits.

PORTB = PORTB | (1<<2);

or

PORTB |= (1<<2);

OR symbol is "|".

OR a bit with 0: the bit (0 or 1) remains the same.

OR a bit with 1: the bit (0 or 1) becomes a 1. This is how we set a bit.

Code Example: only bit 2 in PORTB is OR'd with a 1 so it's changed to a 1 regardless of whether it was a 0 or 1; the other Port bits remain the same.

 

Multiple bits can be set. Bits 2 and 4 need to be set to a 1 in this example:

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

OR Truth Table with Inputs A, B and Output C:

A | B = C

0 | 0  = 0

0 | 1  = 1

1 | 0  = 1

1 | 1 =  1

 

Toggle a Port bit.

PORTB = PORTB ^ (1 <<2);

or

PORTB ^= (1<<2);

Exclusive OR, XOR, symbol is "^".

XOR a 0 or 1 bit with 0: the Port bit remains the same.

XOR a 1 bit with 1: the Port bit becomes a 0. XORing any bit with a 1 will toggle it (0 becomes 1, 1 becomes 0).

 

Multiple bits can be toggled. Bits 2 and 4 will be toggled in this example:

PORTB ^= ((1 << 2) | (1 << 4));

Exclusive OR (XOR) Truth Table with Inputs A, B and Output C:

A ^ B = C

0 ^ 0  = 0

0 ^ 1  = 1

1 ^ 0  = 1

1 ^ 1 =  0  This result is the difference between OR and XOR.

Clear a Port bit with AND (&)

and NOT (~).

PORTB = PORTB & ~(1<<2);

or

PORTB &= ~(1<<2);

AND symbol is "&".

AND any bit with 0: the bit becomes a 0. This is how we clear a bit.

AND any bit with 1: the bit remains the same.

Code Example: If we AND bit 2 with a 1, the bit remains the same. If we then invert it with a NOT, it becomes a 0. This is how AND and NOT can be used together to clear a bit (or more).

 

Multiple bits can be cleared. Bits 2 and 4 will be cleared in this example: PORTB &= ~((1<<2) | (1<<4));

AND Truth Table with Inputs A, B and Output C:

A & B = C

0 & 0  = 0

0 & 1  = 0

1 & 0  = 0

1 & 1 =  1 This result only occurs when both bits are ones.

 

With OR, we could turn bits on by ORing them with 1.

With AND, we can turn bits off by ANDing them with 0.

Invert the state of one or more pins. LED_Port = ~(1 << J);

NOT symbol is "~".

00000000 becomes 00000100 if J = 2.

 
Enable the built-in Pull-up Resistor function.

DDRD &= ~(1 << PD2);

PORTD |= (1 << PD2);

Set direction mode to INPUT (0 = input, 1 = output) for pin 2 of port D.

Enables pull-up resistor on pin 2 of port D (1 = enabled).

 

Tag: ATmega328P Register Bit Manipulation

HOME