Files
embedded-programming/LED Blink Input Output/How-to-write-GPIO-notes.md
2026-04-03 17:14:04 +11:00

2.3 KiB
Raw Permalink Blame History

INPUT OUTPUT (DDRx Register)

To configure a pin as INPUT or OUTPUT, we use DDRx register.

  • DDRx bit = 1 → OUTPUT
  • DDRx bit = 0 → INPUT

Problem

Using direct assignment:

DDRB = 0b00000001;

→ PB0 = OUTPUT
→ PB1PB7 = INPUT

This is not good because:

  • it overwrites all bits
  • existing configuration is lost

Correct approach (safe and professional)

Set PB0 as OUTPUT

DDRB |= (1 << PB0);

Explanation:

Assume DDRB = 11111110

(1 << PB0) = 00000001

11111110
00000001 (OR)

11111111

→ Only PB0 becomes OUTPUT
→ other pins unchanged


Set PB0 as INPUT

DDRB &= ~(1 << PB0);

Explanation:

Assume DDRB = 11111111

(1 << PB0) = 00000001
~(1 << PB0) = 11111110

11111111
11111110 (AND)

11111110

→ PB0 becomes INPUT
→ other pins unchanged


Final

  • OUTPUT → DDRx |= (1 << Px)
  • INPUT → DDRx &= ~(1 << Px)

This method:

  • does not disturb other pins
  • is scalable
  • is standard embedded practice

PORTx and PINx (Output and Input Control)

0xFF can be used in hex for 8-bit and 0b11111111 in binary.
Both represent all bits = 1.


OUTPUT (Using PORTx)

After setting direction using DDRx, we use PORTx to control output.

Set pin HIGH:

PORTB |= (1<<PB0);

→ PB0 = HIGH (5V)

Set pin LOW:

PORTB &= ~(1<<PB0);

→ PB0 = LOW (0V)

This follows same bit logic (OR to set, AND with NOT to clear).


INPUT (Important concept)

To use pin as INPUT:

DDRB &= ~(1<<PB0);

Now PB0 is INPUT.


Pull-up requirement

If input is left floating:

  • Noise (EMF, static) can cause false HIGH/LOW

So we enable internal pull-up:

PORTB |= (1<<PB0);

Now:

  • Default = HIGH
  • Pressed (connected to GND) = LOW

Reading input (PINx)

PINx register reads actual pin state.

Example:

if (!(PINB & (1<<PB0))) {

}


Logic explanation

Case 1: Button NOT pressed

PINB bit = 1

PINB & (1<<PB0) = 1

!1 = 0 → FALSE

→ goes to else


Case 2: Button pressed

PINB bit = 0

PINB & (1<<PB0) = 0

!0 = 1 → TRUE

→ enters if


Final understanding

  • DDRx → direction
  • PORTx → output / pull-up
  • PINx → input reading

Key point

Pull-up makes:

  • Not pressed → HIGH
  • Pressed → LOW

So logic is inverted:

  • LOW = pressed
  • HIGH = not pressed