CompileNative

Your First Real C Program

Write a bare-metal C program without any Arduino libraries. Understand main(), includes, and the build process.

Your First Real C Program

The Arduino Way vs. The Real Way

If you've only ever written Arduino code, you're used to this:

void setup() {
  pinMode(13, OUTPUT);
}

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

This hides everything that's actually happening. Where's main()? Who calls setup()? What is pinMode() actually doing to the hardware?

What Really Happens

Every C program starts at main(). The Arduino framework hides this from you, but it's there:

#include <avr/io.h>
#include <util/delay.h>

int main(void) {
    // Set pin 13 (PB5 on ATmega328P) as output
    DDRB |= (1 << PB5);

    while (1) {
        // Toggle pin 13
        PORTB ^= (1 << PB5);
        _delay_ms(1000);
    }

    return 0;  // Never reached
}

What Changed?

ArduinoReal C
pinMode(13, OUTPUT)DDRB |= (1 << PB5)
digitalWrite(13, HIGH)PORTB |= (1 << PB5)
delay(1000)_delay_ms(1000)
Hidden main()Explicit int main(void)

Key Takeaways

  1. main() is the entry point — always. The Arduino IDE generates one for you behind the scenes.
  2. Registers control hardwareDDRB, PORTB, PINB are actual memory addresses mapped to physical pins.
  3. No magic — every function you call eventually touches a register. There are no exceptions.