#define STARTPULS_MIN ...			//Timingdefinitionen --> bei 10 kHz Interrupt: 0,1ms-Schritte
#define STARTPULS_MAX ...			
#define STARTPAUSE_MIN ...
#define STARTPAUSE_MAX ...
#define PULS_MIN ...
#define PULS_MAX ...
#define PAUSE_NULL_MIN ...
#define PAUSE_NULL_MAX ...
#define PAUSE_EINS_MIN ...
#define PAUSE_EINS_MAX ...
#define T_RUHE ...						//Ruhezeit vor "Scharfschaltung" der Statemachine
#define BITANZAHL ...					//Anzahl der Nutzdatenbits im Frame (ohne Startbit)
#define SHIFTER_INITMASKE (1 << 7)		//Anpassen, wenn die Daten "rechtsbündig" geschrieben werden sollen (Bei einer Nutzdatenbitanzahl, die nicht durch 8 teilbar ist)

//Flags für die "Kommunikation" mit der Main
#define FEHLER_STARTPULS			(1<<7)	//Timing Startpuls falsch
#define FEHLER_STARTPAUSE 		(1<<6)	//Timing Startpause falsch
#define FEHLER_PULS					(1<<5)	//Timing Nutzdatenpuls falsch
#define FEHLER_PAUSE				(1<<4)	//Timing Nutzdatenpause
#define FEHLER_BITANZAHL			(1<<3)	//Fehler Bitanzahl im Frame (zu viele)
#define TIMEOUT						(1<<2)	//Timeout Pausenerkennung (Frame zuende)

//Globale Variablen
unsigned char status = 0;							//akt. Zustand der Statemachine
unsigned char pulsdauer = 0;					//Zählervariable für Pulsdauern
unsigned char pausendauer = 0;				//Zählervariable für Pausendauern
unsigned char ruhezaehler = T_RUHE;			//Zählervariable für Erkennung "Funkstille"
volatile unsigned char bitzaehler = 0;			//Zählvariable für Empfangene Bits
volatile unsigned char empfangspuffer[16];	//hier werden die empfangenen Nutzdaten BITWEISE reingeschrieben, ggf. vergrößern
unsigned char *empfangspuffer_akt;			//Zeiger auf aktuelles Emfangsbyte
unsigned char empfangsshifter = SHIFTER_INITMASKE;	//Bitmaske für aktuelles Bit im akt. Empfangsbyte --> 1. Nutzdatenbit wird an diese Stelle im "nullten" Empfangspufferbyte geschrieben
volatile unsigned char update = 0;				//Flag-Byte für Kommunikation mit der Main
volatile unsigned char pulsdauern[128];		//Array mit Pulsdauern (zum debuggen)
volatile unsigned char pausendauern[128];	//...das gleiche nochmal für die Pausendauern

//Interruptroutine, mit 10 kHz aufwärts aufrufen
void interrupt() {
switch(status)
{
	case 0:	//Ruhezeit abwarten ("Funkstille" zwischen Frames)
		if (PAUSE_ERKANNT)	//Pause am IR-Pin --> Zähler dekrementieren
		{
			 ruhezaehler--;
		}
		else			//Puls erkannt --> Ruhezähler auf Initialwert zurücksetzen
		{
			ruhezaehler = T_RUHE;
		}
		if (ruhezaehler == 0)	//Ruhezeit abgelaufen? --> Weiter zu "Warte auf Startpuls"
		{
			status = 1;		//Übergang zu "Warte auf Startpuls"
			bitzaehler = 0;	//Bitzähler nullen
			ruhezaehler = T_RUHE;		//Ruhezähler für nächsten Durchlauf belegen
			empfangspuffer_akt = &empfangspuffer[0];	//Zeiger auf "nulltes" Empf.-Byte 
			empfangsshifter = SHIFTER_INITMASKE;	//Shifter initialisieren
			empfangspuffer[0] = 0; 					//nulltes Empf.-byte "nullen"
		}
		break; 	//Ende case "0"
	case 1:	//Warten auf Startpuls
		if (PULS_ERKANNT)	//Wenn Puls erkannt wurde, weiter zu Zustand "Pulsdauer zählen"
		{
			status = 2;
			pulszaehler = 1;		//Pulszähler auf Startwert eins setzen
		}
		break;	//Ende case "1"
	case 2:	//Status "Startpulsdauer zählen"
		if (PULS_ERKANNT)	//Puls liegt noch an?...
		{
			pulszaehler++;		//Pulsdauer mitzählen
			if (pulszaehler > PULS_START_MAX)	//Puls "zu lang"?
			{ 
				status = 0;		//Statemachine rücksetzen
				update |= FEHLER_STARTPULS;	//Fehlerflag Startpuls setzen
			}
		}
		else	//Startpuls zuende --> Timing überprüfen
		{
			if (pulszaehler <= PULS_START_MAX && pulszaehler >= PULS_START_MIN)
				//Startpulstiming OK?
			{ 		
				status = 3;		//Übergang zu Startpausenerkennung
				pausenzaehler = 1;	//Pausenzaehler auf Startwert eins setzen
				pulsdauern[0] = pulszaehler;	//DEBUG: Länge Startpuls sichern
			}
			else	//Startpuls zu lang oder zu kurz?
			{
				status = 0;		//Statemachine rücksetzen
				update |= FEHLER_STARTPULS;	//Fehlerflag Startpuls setzen
			}
		}
		break;	//Ende case "2"
	case 3:	//Zustand "Startpausendauer zählen"
		if (PAUSE_ERKANNT)	//Pause liegt noch an?...
		{
			pausenzaehler++;		//Pausendauer mitzählen
			if (pausenzaehler > PAUSE_START_MAX)	//Startpause "zu lang"?
			{ 
				status = 0;		//Statemachine rücksetzen
				update |= FEHLER_STARTPAUSE;	//Fehlerflag Startpause setzen
			}
		}
		else	//Startpause zuende --> Timing überprüfen
		{
			if (pausenzaehler <= PAUSE_START_MAX && pausenzaehler >= PAUSE_START_MIN)
				//Startpausentiming OK?
			{ 		
				status = 4;			//Übergang zu Nutzdatenpulserkennung
				pulszaehler = 1;		//Pulszähler auf Startwert eins setzen
				pausendauern[0] = pausenzaehler;		//DEBUG: Länge Startpause sichern
			}
			else	//Startpause zu lang oder zu kurz?
			{
				status = 0;		//Statemachine rücksetzen
				update |= FEHLER_STARTPAUSE;	//Fehlerflag Startpause setzen
			}
		}
		break;	//Ende case "3"
	case 4:	//Status "Nutzdatenpulsdauer zählen"
		if (PULS_ERKANNT)	//Puls liegt noch an?...
		{
			pulszaehler++;		//Pulsdauer mitzählen
			if (pulszaehler > PULS_MAX)	//Puls "zu lang"?
			{ 
				status = 0;		//Statemachine rücksetzen
				update |= FEHLER_PULS;	//Fehlerflag Startpause setzen
			}
		}
		else	//Nutzdatenpuls zuende --> Timing überprüfen
		{
			if (pulszaehler <= PULS_MAX && pulszaehler >= PULS_MIN)
				//Nutzdatenpulstiming OK?
			{ 		
				status = 5;				//Übergang zu Nutzdatenpausenerkennung
				pausenzaehler = 1;		//Pausenzaehler auf Startwert eins setzen
				pulsdauern[bitanzahl+1] = pulszaehler;	//DEBUG: Länge Puls sichern
			}
			else	//Nutzdatenpuls zu lang oder zu kurz?
			{
				status = 0;		//Statemachine rücksetzen
				update |= FEHLER_PULS;	//Fehlerflag Startpause setzen
			}
		}
		break;	//Ende case "4"
	case 5:	//Zustand "Nutzdatenpausendauer zählen"
		if (PAUSE_ERKANNT)	//Pause liegt noch an?...
		{
			pausenzaehler++;		//Pausendauer mitzählen
			if (pausenzaehler > PAUSE_NULL_MAX && pausenzaehler > PAUSE_EINS_MAX)			//Nutzdatenpause "zu lang"? (eigentlich reicht der Vergleich mit der größeren Konstante, das sollte der Compiler aber rausoptimieren)
			{ 
				status = 0;		//Statemachine rücksetzen
				update |= TIMEOUT;	//Flag "Timeout" Pausenerkennung setzen -> Frame zuende!
			}
		}
		else	//Nutzdatenpause zuende --> Timing überprüfen (Unterscheidung 0/1)
		{
			unsigned char h;		//Hilfsbyte für Speicherung 0/1
			unsigned char pausentiming_ok = 0;	//Status, ob Timing der Pause OK war
			if (pausenzaehler <= PAUSE_NULL_MAX && pausenzaehler >= PAUSE_NULL_MIN)
				//Nutzdatenpausentiming NULL OK?
			{ 	//Null speichern (Puffer wird vorher geleert, also eigentlich "nichts schreiben"...
				h = 0;			//merken, dass eine Null gespeichert werden soll
				pausentiming_ok = 1;		//Flag für korrekte Pausendauer setzen
			}
			if (pausenzaehler <= PAUSE_EINS_MAX && pausenzaehler >= PAUSE_EINS_MIN)
				//Nutzdatenpausentiming EINS OK?
			{ 	//Eins speichern
				h = 0xFF;			//merken, dass eine Eins gespeichert werden soll
				pausentiming_ok = 1;		//Flag, für korrekte Pausendauer setzen
			}
			if (pausentiming_ok)		//Pausentiming für 1 / 0 OK?
			{
				*empfangspuffer_akt |= empfangsshifter & h; //aktuell maskiertes Bit schreiben (Bitweises UND zwischen h und empfangsshifter --> bei einer null passiert "nichts"
				empfangsshifter = empfangsshifter >> 1;	//nächstes Bit maskieren
				if (empfangsshifter == 0)		//Eins "rausgeschoben"? --> "Umschalten" auf nächstes Byte im Empfangspuffer!
				{
					empfangsshifter = (1 << 7);	//Wieder Bit 7 maskieren...
					empfangspuffer_akt++;		//..und Zeiger auf nächstes Byte setzen
					*empfangspuffer_akt = 0;	//nächstes Empf.-Byte nullen
				} 
				bitzaehler++;						//Zähler empfangener Bits erhöhen
				if (bitzaehler <= BITANZAHL)	//Überlauf Bitanzahl abfangen
				{
					status = 4;			//Übergang zu Nutzdatenpulserkennung
					pulszaehler = 1;		//Pulszähler auf Startwert eins setzen
					pausendauern[bitanzahl] = pausenzaehler;	//DEBUG: Länge Pause sichern
				}
				else	//Zu viele Bits?
				{
					status = 0;
					update |= FEHLER_BITANZAHL;	//Fehlerflag "zu viele Bits" setzen
				}
			}
			else	//Pausentiming nicht OK
			{
				status = 0;
				update |= FEHLER_PAUSE;	//Fehlerflag Nutzdatenpause setzen
		}
		break;

}	//Ende switch
} 	//Ende interrupt()