Oder du wartest nicht beim Empfang:
Code:
// Zeichen empfangen
int uart_getc_nowait (void)
{
    if (!(UCSRA & (1<<RXC)))  // warten bis Zeichen verfuegbar
        return  -1
    return (int) UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
}
Du reagierst dann nur auf die Funktion, wenn sie nicht -1 liefert (ist was anderes als 0xff, daher gibt sie int zurück).

Mit der Interrupt-Lösung musst du dir auch merken, ob das Zeichen schon ausgewertet wurde, und da reicht 1 Byte auch nicht mehr.