Arduino and AVR Serial Communication over USB I have a Arduino Uno Rev3 and I would like to use a AVR development toolchain to write a program that performs serial communication over USB.

Doing this using the Arduino IDE is fairly simple:

void setup() {
   Serial.begin(9600);
}

void loop() {
   int i;
   while(1) {
      Serial.write("hello\n");
      delay(5000);
   }
}


Then from Linux, I can simply read from /dev/ttyACM0 and every 5 seconds I get "hello\n".

I found a blog post titled Simple Serial Communications With AVR libc that explains how to perform serial communication using an AVR development toolchain. The simplified version of the above Arduino sketch is below.

#ifndef F_CPU
#define F_CPU 8000000UL
#endif

#ifndef BAUD
#define BAUD 9600
#endif

#include &lt;stdio.h&gt;
#include &lt;avr/io.h&gt;
#include &lt;util/delay.h&gt;
#include &lt;util/setbaud.h&gt;

void uart_init() {
    // Upper and lower bytes of the calculated prescaler value for baud.
    UBRR0H = UBRRH_VALUE;
    UBRR0L = UBRRL_VALUE;

    // Configure data frame size to 8-bits.
    UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);

    // Configure to enable transmitter.
    UCSR0B = _BV(TXEN0);
}

void uart_putchar(char c) {
    // Wait until the register to write to is free.
    loop_until_bit_is_set(UCSR0A, UDRE0);

    // Write the byte to the register.
    UDR0 = c;
}

void uart_putstr(char *data) {
    // Loop until end of string writing char by char.
    while(*data){
      uart_putchar(*data++);
    }
}

int main() {
    uart_init();

    while(1) {
        uart_putstr("hello\n");
        _delay_ms(5000);
    }

    return 0;
}


The problem is, this doesn't actually work. I can build and flash the ATmega328p but reads to /dev/ttyACM0 block forever. I suspect what is happening is that the serial communication is occurring on some pins and not over USB, but I am not sure.

Anyone have any idea on how I can emulate Serial.write using an AVR development toolchain and have the output be written over USB?
Turns out the problem was with my Makefile. avr-gcc was missing the -mmcu=atmega328p flag. Once I added that and changed F_CPU to 16000000UL everything works.