Skip to content

GPIO

The Arduino Uno provides input/output (I/O) ports that enable the microcontroller to interact with external devices such as sensors, motors, and LEDs. These ports are divided into digital pins and analog pins, grouped into internal ports for efficient control.

  • PORTB: Controls digital pins D8 to D13.

    Pin NumberPort Bit
    D8PB0
    D9PB1
    D10PB2
    D11PB3
    D12PB4
    D13PB5
  • PORTC: Controls analog pins A0 to A5.

    Pin NumberPort Bit
    A0PC0
    A1PC1
    A2PC2
    A3PC3
    A4PC4
    A5PC5
  • PORTD: Controls digital pins D0 to D7.

    Pin NumberPort Bit
    D0PD0
    D1PD1
    D2PD2
    D3PD3
    D4PD4
    D5PD5
    D6PD6
    D7PD7

Each port has three registers associated with it:

  • DDR (Data Direction Register): DDR controls the data direction (input or output). Set the corresponding bit to 1 for output and 0 for input.
  • PORT Register: PORT controls the output state. Set the corresponding bit to 1 to set the pin HIGH and 0 to set it LOW. When configured as input, the PORT register can be used to enable pull-up resistors. To enable pull-up resistors, set the corresponding bit to 1.
  • PIN Register: PIN reads the current state of the input pins.

For example, if you would like to configure pin D8 (PB0) as an output and set it HIGH, you can use the following code:

DDRB |= (1 << PB0); // Set D8 (PB0) as output
PORTB |= (1 << PB0); // Set D8 (PB0) HIGH

A more elaborated example is to blink an LED connected to pin D5. Before diving into the code, let’s first understand the registers involved:

  • DDRB: Data Direction Register for PORTB. Setting bit 5 (PB5) to 1 configures pin D5 as an output.
  • PORTB: Port Register for PORTB. Setting bit 5 (PB5) to 1 turns the LED on, while clearing it (setting to 0) turns the LED off.

Connect an LED to pin D5 with a current-limiting resistor. Assuming that the diode forward voltage is 2V and the current is 20mA, you can use a 220Ω resistor or higher.

220 ΩARDUINOUNO r3IOREFRESET3.3V5VGNDGNDVinA0A1A2A3A4A5AREFGNDD13D12PWM D11PWM D10PWM D9D8D7PWM D6PWM D5D4PWM D3D2TX D1RX D0

This code snippet configures pin D5 as an output and toggles the pin state to blink the LED. The _delay_ms function imported from utils/delay.h is used to introduce a delay between turning the LED on and off. avr/io.h is included to access the I/O registers and macros.

#include <avr/io.h>
#include <util/delay.h>
#define BLINK_DELAY_MS 1000
int main(void) {
/* set pin 5 of PORTB for output */
DDRB |= (1 << DDB5);
while (1) {
/* toggle pin 5 to turn LED on/off */
PORTB ^= (1 << PORTB5);
_delay_ms(BLINK_DELAY_MS);
}
}