Er resettet nicht mehr und alles funzt wunderbar!
Aber nicht immer. Der Code aus Punkt 5 führt unweigerlich zum Crash. Vielleicht erst nach Stunden oder Tagen (hängt auch davon ab, wie viel Kommandos du an den Controller sendest), aber er kommt garantiert.

Ok, hier also mein Vorschlag für main:

Ich habe deinen Code doch richtig dahingehend interpretiert, dass eine Eingabe immer aus einem Buchstaben, 4 Ziffern und einem Ausrufezeichen besteht?
Die Funktion Pwmstatus habe ich übrigens rausgeschmissen.

Code:
int main () {

	// hier die ganzen Initialisierungen einfügen
	
	unsigned int c;
	char Eingabe[6];
	char Ausgabe[10];
	unsigned char count = 0;

	for (;;) {

		// auf das nächste Zeichen warten
		do
			c = uart_getc();
		while (c & UART_NO_DATA);
		
		if (c != '!') {
			Eingabe[count] = c;
			count++;
			if (count > 5) //ups
				count = 0;
			continue;  // weiter mit Warten auf das nächste Zeichen
		}
		
		// '!' wurde empfangen, Eingabe müsste also vollständig sein

		Eingabe[count] = '\0';
		count = 0;
		if (strlen(Eingabe) != 5) //ups
			continue;
		
		switch (Eingabe[0]) {
		
			case 'l':
				PORTD |= (1<<PD6);
				PORTD &= ~(1<<PD7);
				OCR1A = atoi(Eingabe+1);
				break;
				
			case 'r':
				PORTD &= ~(1<<PD6);
				PORTD |= (1<<PD7);
				OCR1A = atoi(Eingabe+1);
				break;

			case 'g':
				cli();
				c = Ergebnis;  // c wird hier als Zwischenspeicher "missbraucht"
				sei();
				itoa(c,Ausgabe,10);
				strcat(Ausgabe,"!");
				uart_puts(Ausgabe);
				break;
		}

	}
	return 0;
}
Die mit "ups" markierten Stellen sind Vorsichtsmaßnahmen, damit der Controller auch dann nicht aus dem Tritt kommt, wenn über die serielle Schnittstelle mal Müll eintrifft.