Ok,

Eine ISR habe ich nicht.
es wird aber auch nicht vom
https://www.roboternetz.de/wissen/in...RT_mit_avr-gcc
explizit erwähnt, oder ich habe es überlesen....

Habe ja auch fast alles von dort kopiert...

Hier der Gesamte Kode:

Main.c

Code:
#include <avr/interrupt.h>  /* Wird nur gebraucht bei der Interrupt-Version */ 
#include "uart.h"
/*==================[macros]=================================================*/
/* Ein Zeilenumbruch, abhängig davon, was die Gegenstelle haben will */ 
/* Windows: "rn" */ 
/* Linux  : "n"  */ 
/* MacOS  : "r"  */ 
#define CR "\r\n"
/*==================[type definitions]=======================================*/

/*==================[internal function declarations]=========================*/

/*==================[external constants]=====================================*/

/*==================[internal constants]=====================================*/

/*==================[internal data]==========================================*/

/*==================[external function definitions]==========================*/

/*==================[internal function definitions]==========================*/




int main()
{
    uart_init();
    sei();   // Wird nur gebraucht bei der Interrupt-Version 

    uart_putc ('f');
    /*uart_puts ("Hallo Welt!" CR);*/

    while (1);


    return 0;
}
/** @} doxygen end group definition */
/*==================[end of file]============================================*/
uart.h:

Code:
#include <avr/io.h>

/*==================[macros]=================================================*/

/*==================[type definitions]=======================================*/

/*==================[external function declarations]=========================*/
extern void 		uart_init();
extern int 			uart_putc(const uint8_t);
extern uint8_t 	uart_getc_wait();
extern int     	uart_getc_nowait();

extern void uart_puts (char *string_data);

/* Wartet, bis die Übertragung fertig ist. */
static inline void uart_flush()
{
	while (UCSRB & (1 << UDRIE));
}
/*==================[external constants]=====================================*/

/*==================[external data]==========================================*/


/** @} doxygen end group definition */
#endif /* _UART_H_ */
/*==================[end of file]============================================*/


uart.c:

Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "uart.h"
#include "fifo.h"
/*==================[macros]=================================================*/
#ifndef F_CPU
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
   F_CPU im Makefile definiert werden, eine nochmalige Definition
   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
   #ifndef/#endif 
 
   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio 
   verwendet wird und dort eine andere, nicht zur Hardware passende 
   Taktrate eingestellt ist: Dann wird die folgende Definition 
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) 
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
   noch nicht definiert: */
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 8000000"
#define F_CPU 8000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! 
#endif
 
#define BAUD 9600L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   /* clever runden */
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     /* Reale Baudrate */
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) /* Fehler in Promille */
/*
#if (((BAUD_ERROR) > (10)) || ((BAUD_ERROR) < (-10)))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif
*/
#define BUF_SIZE_IN		0x40													/* FIFO-Buffergröße */
uint8_t in_buffer[BUF_SIZE_IN];
fifo_t in_fifo;

#define BUF_SIZE_OUT		0x40													/* FIFO-Buffergröße */
uint8_t out_buffer[BUF_SIZE_OUT];
fifo_t out_fifo;

/*********     FUNKTIONEN       ***********/

void uart_init()
{
	uint8_t sreg = SREG;
	UBRRH = UBRR_VAL >> 8;
	UBRRL = UBRR_VAL & 0xFF;
	
	cli();														 /* Interrupts kurz deaktivieren */
	UCSRB |= (1<<TXCIE) | (1<<TXEN);   /* TXCompleteInterrupt u. TX einschalten */
	UCSRC |= (1<<URSEL)| (1<<UCSZ1) | (1<<UCSZ0);    /* Asynchron 8N1 	*/
	
	/* Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) */ 
	do
	{
	 /* UDR auslesen (Wert wird nicht verwendet) */ 
		UDR;
	}while (UCSRA & (1 << RXC));
	
  /* Rücksetzen von Receive und Transmit Complete-Flags */ 
  UCSRA = (1 << RXC) | (1 << TXC);
  
	/* Global Interrupt-Flag wieder herstellen */
	SREG = sreg;											
	
  /* FIFOs für Ein- und Ausgabe initialisieren */ 
  fifo_init (&in_fifo,   in_buffer, BUF_SIZE_IN);
  fifo_init (&out_fifo, out_buffer, BUF_SIZE_OUT);
}

/* Senden eines Chars */
int uart_putc (const uint8_t data)
{
	int ret = fifo_put (&out_fifo, data);
	UCSRB |= (1 << UDRIE);
 
  return ret;
}

/**/
int uart_getc_nowait ()
{
	return fifo_get_nowait (&in_fifo);
}
/**/
uint8_t uart_getc_wait ()
{
	return fifo_get_wait (&in_fifo);
}

/* Senden eines Strings */
void uart_puts (char *string_data)
{
	while (*string_data)				/* Wiederhole bis im String '\0' erreicht wurde (*s != '\0') */
	{
		uart_putc (*string_data);	/* Gebe ein Zeichen aus*/
		string_data++;						/* Erhöhe den String um ein Character */
	}
}

/*********************** INTERRUPTS ****************************************/
// Empfangene Zeichen werden in die Eingabgs-FIFO gespeichert und warten dort 
SIGNAL (SIG_UART_RECV)
{
    _inline_fifo_put (&in_fifo, UDR);
}

// Ein Zeichen aus der Ausgabe-FIFO lesen und ausgeben 
// Ist das Zeichen fertig ausgegeben, wird ein neuer SIG_UART_DATA-IRQ getriggert 
// Ist die FIFO leer, deaktiviert die ISR ihren eigenen IRQ. 
SIGNAL (SIG_UART_DATA)
{
    if (out_fifo.count > 0)
       UDR = _inline_fifo_get (&out_fifo);
    else
        UCSRB &= ~(1 << UDRIE);
}
/*********************** ENDE INTERRUPTS ***********************************/
/** @} doxygen end group definition */
/*==================[end of file]============================================*/
fifo.h
Code:
#ifndef FIFO_H_
#define FIFO_H_

#include <avr/io.h>
#include <avr/interrupt.h>

typedef struct
{
	uint8_t volatile count;       // # Zeichen im Puffer
	uint8_t size;                 // Puffer-Größe
	uint8_t *pread;               // Lesezeiger
	uint8_t *pwrite;              // Schreibzeiger
	uint8_t read2end, write2end;  // # Zeichen bis zum Überlauf Lese-/Schreibzeiger
} fifo_t;

extern void fifo_init (fifo_t*, uint8_t* buf, const uint8_t size);
extern uint8_t fifo_put (fifo_t*, const uint8_t data);
extern uint8_t fifo_get_wait (fifo_t*);
extern int fifo_get_nowait (fifo_t*);


/* Schreibt das nächste Byte "data" in die FIFO.
 * Liefer 1 bei Erfolg und 0, falls die FIFO voll ist. */
static inline uint8_t _inline_fifo_put (fifo_t *f, const uint8_t data)
{
	if (f->count >= f->size)
		return 0;
		
	uint8_t * pwrite = f->pwrite;
	
	*(pwrite++) = data;
	
	uint8_t write2end = f->write2end;
	
	if (--write2end == 0)
	{
		write2end = f->size;
		pwrite -= write2end;
	}
	
	f->write2end = write2end;
	f->pwrite = pwrite;

	uint8_t sreg = SREG;
	cli();
	f->count++;
	SREG = sreg;
	
	return 1;
}


/* Liefert das nächste Zeichen aus der FIFO. Ob überhaubt ein Zeichen in der FIFO
 * ist, muss vorher extra abgeprüft werden */
static inline uint8_t _inline_fifo_get (fifo_t *f)
{
	uint8_t *pread = f->pread;
	uint8_t data = *(pread++);
	uint8_t read2end = f->read2end;
	
	if (--read2end == 0)
	{
		read2end = f->size;
		pread -= read2end;
	}
	
	f->pread = pread;
	f->read2end = read2end;
	
	uint8_t sreg = SREG;
	cli();
	f->count--;
	SREG = sreg;
	
	return data;
}


#endif /*FIFO_H_*/

fifo.c:
Code:
#include "fifo.h"

/* Initialisiert die FIFO, setzt Lese- und Schreibzeiger, etc. 
 * Die FIFO verwendet den Puffer "buffer", der "size" Bytes sein muss. */
void fifo_init (fifo_t *f, uint8_t *buffer, const uint8_t size)
{
	f->count = 0;
	f->pread = f->pwrite = buffer;
	f->read2end = f->write2end = f->size = size;
}

/* Schreibt das nächste Byte "data" in die FIFO.
 * Liefer 1 bei Erfolg und 0, falls die FIFO voll ist. */
uint8_t fifo_put (fifo_t *f, const uint8_t data)
{
	return _inline_fifo_put (f, data);
}

/* Liefert das nächste Byte aus der FIFO, bei leerer FIFO wird gewartet, 
 * bis das nächste Zeichen eintrift. */
uint8_t fifo_get_wait (fifo_t *f)
{
	while (!f->count);
	return _inline_fifo_get (f);	
}

/* Liefert das nächste Byte aus der FIFO als "int" bzw. -1, 
 * falls die FIFO leer ist. */
int fifo_get_nowait (fifo_t *f)
{
	if (!f->count)		return -1;
	return (int) _inline_fifo_get (f);	
}