Lesson 1: Digital output

Pin 13 on the UNO R3 is bit 5 of the PORTB register1. This lesson blinks it twice: once with Arduino calls, then again by writing the register yourself.

What you need

  • Arduino UNO R3
  • USB cable
  • Nothing else: the board has an LED on pin 13

Wire it, then check it

The UNO R3 has a built-⁠in LED on pin 135, so this lesson needs no wiring.

Before you run it on a real board, check each connection

Not working on a real board? Start with the wiring checklist.

Arduino version

l1-blink-arduino.ino
// Lesson 1, Arduino version.
// Blinks the UNO R3's LED on pin 13: 1 s on, 1 s off.
void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
  delay(1000);
}

Once pinMode(13, OUTPUT) makes pin 13 an output, digitalWrite(13, HIGH) sets it to 5 V and LOW sets it to 0 V3. delay(1000) waits one second and blocks the rest of the sketch while it waits4.

Register version

l1-blink-registers.ino
// Lesson 1, register version: the same blink, written
// directly to the port registers.
// Pin 13 is PORTB bit 5 (PB5) on the UNO R3.
void setup() {
  DDRB |= (1 << DDB5);       // pin 13 is an output
}

void loop() {
  PORTB |= (1 << PORTB5);    // pin 13 HIGH
  delay(1000);
  PORTB &= ~(1 << PORTB5);   // pin 13 LOW
  delay(1000);
}

A 1 in a DDRB bit makes that pin an output2. PORTB sets the output level, and PINB reads the pins6. |= with (1 << PORTB5) sets bit 5 and leaves the others alone; &= ~ with the same mask clears bit 5 only.

PORTB bits 7 to 0, with the port pin, Arduino pin and chip pin each one drives
PORTB bit76543210
Port pinPB7PB6PB5PB4PB3PB2PB1PB0
Arduino pinnonenone1312111098
Chip pin109191817161514
PORTB bits 7 to 0, with the port pin, Arduino pin and chip pin each one drives
PORTB bitPort pinArduino pinChip pin
7PB7none10
6PB6none9
5PB51319
4PB41218
3PB31117
2PB21016
1PB1915
0PB0814
PORTB bit 5 is port pin PB5, which the UNO’s pin map calls pin 131. On the 28-⁠pin chip it is pin 192. Bits 6 and 7 go to chip pins 9 and 10, XTAL1 and XTAL22, and have no Arduino pin number1.

Registers in this lesson (ATmega328P data-⁠space addresses)2

RegisterAddressBit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
DDRB0x24DDB7DDB6DDB5DDB4DDB3DDB2DDB1DDB0
PORTB0x25PORTB7PORTB6PORTB5PORTB4PORTB3PORTB2PORTB1PORTB0
PINB0x23PINB7PINB6PINB5PINB4PINB3PINB2PINB1PINB0

Run it in the lab

Switch between the two programs. The register panel shows the same PORTB5 bit turning on and off in both.

Drill

  1. Which register bit is pin 13 on an UNO R3?

    Show the answer

    PORTB bit 5 (PB5). The UNO’s pin map puts digital pin 13 on PB5. 1

  2. What does DDRB |= (1 << DDB5); do?

    Show the answer

    It makes pin 13 an output, like pinMode(13, OUTPUT). A 1 in a pin’s DDxn bit makes that pin an output. 2

  3. Why does PORTB &= ~(1 << PORTB5); leave pins 8 to 12 alone?

    Show the answer

    The AND with an inverted mask clears bit 5 only. Every other bit of the mask is 1, so ANDing keeps those bits as they were.

Sources

  1. ArduinoCore-⁠avr, variants/standard/pins_arduino.h: LED_BUILTIN is 13; pin 13 is PB5
  2. Microchip ATmega328P datasheet DS40002061A: Pin configurations (p12); I/O ports; PORTB and DDRB at p100
  3. Arduino reference: digitalWrite
  4. Arduino reference: delay
  5. Arduino UNO R3 technical specifications: Built-⁠in LED Pin: 13
  6. Arduino: Port Manipulation (retired page, written for the ATmega8/168): DDRx, PORTx and PINx

Next: Lesson 2