Code:
 //---------------------------------------------------------------------------
// Title      	: DC Motor Steuerung V7.0
// Schaltung  	: Steuert zwei DC Motoren PAN&TILT über Tasten NORD, SÜD, OST, WEST 
//                Motoren werden über PWM Ausgänge betrieben, Hall Geber über ext Interrut,
//				  Anzahl der Schritte über SW vorgebene 
//----------------------------------------------------------------------
// Prozessor 	: ATmega8
// Takt      	: 3.6864 MHz
// Sprache   	: C
// Datum     	: 27.05.2010
// Version   	: 9.0
// Autor     	: Sven Thomson
// Programmer	: ...
// Port		 	: ...
//---------------------------------------------------------------------------
#define 	F_CPU 3686400	// Taktfrequenz des myAVR-Boards
#include	<avr\io.h>		// AVR Register und Konstantendefinitionen
#include 	<util\delay.h>	// Bibliothek mit Warteroutinen

#include 	<math.h>
#include 	<inttypes.h>
#include 	<avr\interrupt.h>

//----------------------------------------------------------------------
//------------------------Globale VARIABLEN-----------------------------

// Varaiablen für PAN-Motor
int PRichtung=0;	// PAN Drehrichtung Osten:-1, Stillstand:0, Westen=1
int PZaehler_A=0;	// PAN Zählerstand am Anfang
int PKorrektur=0;	// PAN Korrekturwert
int PWeg_Kor=0;		// PAN korrigierter Weg

// Varaiablen für TILT-Motor
int TRichtung=0;	// TILT Drehrichtung Norden:-1, Stillstand:0, Süden=1
int TZaehler_A=0;	// TILT Zählerstand am Anfang
int TKorrektur=0;	// TILT Korrekturwert
int TWeg_Kor=0;		// TILT korrigierter Weg

//durch interrupt veränderbare Varaiablen

volatile int PZaehler=0;	// PAN Zähler der HALL Impulse
volatile int TZaehler=0;	// TILT Zähler der HALL Impulse


// Der Modifizierer "volatile" teilt dem Compiler mit, 
// daß eine Variable möglicherweise von einer 
// Hintergrundroutine, einer Interruptroutine 
// oder einem I/O-Port verändert wird.


//---------------------------------------------------------------------
//----------------INTERRUPT ROUTINE EXTERN ÜBER INT0-------------------
ISR (INT0_vect)						// Interruptroutine für den INT0 - PortD2 
{									// hier Hall Sensor Auswertung PAN (weisse Leitung)
	PZaehler++;						// sobald Flanke am PAN Motor, Zähler erhöhen
}

//----------------INTERRUPT ROUTINE EXTERN ÜBER INT1-------------------
ISR (INT1_vect)						// Interruptroutine für den INT1 - PortD3
{									// hier Hall Sensor Auswertung TILT (blaue Leitung)
	TZaehler++;						// sobald Flanke am TILT Motor, Zähler erhöhen
}

//----------------ALLEGEMIEN DELAY FUNKTION ------------------------------------------------------
void delay_us(unsigned int count)
{
	_delay_loop_2(count);
}



//----------------PWM AUSGÄNGE B1, B2 INITIALISIEREN------------------------------------------------------
void initPWM()
{
	DDRB=0b00000110;			// PWM Ausgänge B1, B2
	TCCR1A=0b10100011;			// Timer/Counter 1 Control Register A 
	TCCR1B=0b00000010;			// Timer/Counter 1 Control Register B
}

//----------------PORTS INITILAISIEREN ------------------------------------------------------
void initPORTS()
{
	DDRB = 0b11111111;           // PORT-B = als Ausgang festlegen

	DDRC = 0b00000000;           // PORT-C = als Eingang festlegen
	PORTC = 0b00111111;          // PORT-C = PULL-UP

	DDRD  = 0b00000000;          // PORT-D = als Eingang festlegen
	PORTD = 0b11111111;          // PORT-D = PULL-UP
}

//----------------EXTERE INTERRUPT EINGÄNGE INITIALISIEREN------------------------------------------------------
void initEXISR()
{
	GICR  = 0b01000000;            // für mega8 - Bit 7,6 - Exteren Interrupt einschalten für INT1, INT0 also PORTD3,2
	//EIMSK = 0b00000011;          // für mega 168 - Bit 1,0 - Exteren Interrupt einschalten für int1, int0 also PORTD3,2

	MCUCR = 0b00001010;            // Interrupt bei fallende Flanke, int0:PORTD2 - für PAN, int1:PORTD3 - für TILT
}

//----------------UART INITIALISIERUNG------------------------------------------------------
void initUART()
{
	UBRRL = 23;       		//für mega 8 - 9600Baud siehe Baudratentabelle
	UCSRB = 8 + 16;         //Sender enable, (Empfänger enable)
}

//----------------UART SENDEFUNKTION FÜR 1 ZEICHEN (8 BIT)-------------------
void putChar (char data) // sendet nur ein 8Bit Zeichen
{
	//warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
	while (!(UCSRA&32));
	//sende
	UDR=data;
}

//----------------UART SENDEFUNKTION FÜR ZEICHENKETTE------------------------
void putChar(char *buffer)
{
	for (int i=0; buffer[i] !=0;i++)
		putChar (buffer[i]);
}

//----------------UART SENDEFUNKTION FÜR ZAHL 16BIT------------------------
void uart_uint(uint16_t zahl)
{
	unsigned char text[20];
	int ziffer;
	int i = 0;

	do
	{
		ziffer = zahl % 10;  				// ziffer ist die erste Ziffer 128->8
		zahl   = ( zahl - ziffer ) / 10;  	// zahl ist nun Restziffer(n) 128->12

		text[i++] = ziffer + 0x30;
	}
	while ( zahl != 0 ); 					// solange Restziffern da sind

	while (i > 0)
	{
		putChar( text[--i] );
	}
}



//----------------TASTENAUSWERTUNG für PAN & TILT MIT RICHTUNG------------------------
void TastenSTG()
{
	if (!(PINC&0b00000100)) PRichtung=1;   			// PAN, Bit 2 = 0 -> Drehrichtung WESTEN
	if (!(PINC&0b00001000)) PRichtung=-1;   		// PAN, Bit 3 = 0 -> Drehrichtung OSTEN

	if (!(PINC&0b00010000)) TRichtung=1;   			// TILT, Bit 4 = 0 -> Drehrichtung SÜDEN
	if (!(PINC&0b00100000)) TRichtung=-1;   		// TILT, Bit 5 = 0 -> Drehrichtung NORDEN 
}


//-------------------------------  MOTORSTEUERUNG---------------------------------
//--------------------------------------------------------------------------------

// ---------------------------- PAN MOTOR --------------------------------

void PanMotorGo(int PDir, int PWeg)
{

	while (PDir==1)									// PAN Drehrichtung -> WESTEN
	{
		PDir=0;										// setzte Drehrichtung wieder auf null -> damit nur ein Durchlauf

		putChar(" PZ_:");							// Kontrollausgabe 
		uart_uint(PZaehler);						// PAN Zählerstand über UART
		putChar("B");								// Kontrollausgabe, Zeilenumbruch	

		PKorrektur=PZaehler-PZaehler_A-PWeg_Kor;	// Berechne Korrekturwert für nächsten lauf
		PZaehler_A=PZaehler;						// merke Zählerstand vor dem Lauf
		PWeg_Kor=PWeg-PKorrektur;					// Berechne korrigierten Weg

		while (PZaehler<PZaehler_A+PWeg_Kor-5)		// Laufe solange bis gewünschter Zählerstand-Rampe erreicht
		{
			OCR1A=1000;								// schneller Lauf, mit hohem PWM Wert
			PORTB|=0b00000001;						// Laufe Drehrichtung WESTEN
		}
		while (PZaehler<PZaehler_A+PWeg_Kor)		// Laufe Rest solange bis Rampe zuende
		{
			OCR1A=500;								// lansamer Lauf, mit reduziertem PWM Wert
			PORTB|=0b00000001;						// Laufe Drehrichtung WESTEN
		}

	}

	while (PDir==-1)								// PAN Drehrichtung -> OSTEN
	{
		PDir=0;										// setzte Drehrichtung wieder auf null -> damit nur ein Durchlauf

		putChar(" PZ_:");							// Kontrollausgabe
		uart_uint(PZaehler);						// PAN Zählerstand über UART
		putChar("B");								// Kontrollausgabe, Zeilenumbruch	

		PKorrektur=PZaehler-PZaehler_A-PWeg_Kor;	// Berechne Korrekturwert für nächsten lauf
		PZaehler_A=PZaehler;						// merke Zählerstand vor dem Lauf
		PWeg_Kor=PWeg-PKorrektur;					// Berechne korrigierten Weg

		while (PZaehler<PZaehler_A+PWeg_Kor-5)		// Laufe solange bis gewünschter Zählerstand- Rampe erreicht
		{
			OCR1A=1000;								// schneller Lauf, mit hohem PWM Wert
			PORTB|=0b00001000;						// Laufe Drehrichtung OSTEN
		}
		while (PZaehler<PZaehler_A+PWeg_Kor)		// Laufe Rest solange bis Rampe zuende
		{
			OCR1A=500;								// lansamer Lauf, mit reduziertem PWM Wert
			PORTB|=0b00001000;						// Laufe Drehrichtung OSTEN
		}

	}
	PORTB&=0b11110110;								// Keine Taste gedrückt -> also STOP, Bit 0&3->0
}

// ---------------------------- TILT MOTOR --------------------------------

void TiltMotorGo(int TDir, int TWeg)
{

	while (TDir==1)									// TILT Drehrichtung -> SÜDEN
	{
		TDir=0;										// setzte Drehrichtung wieder auf null -> damit nur ein 
		
		putChar(" TZ_:");							// Kontrollausgabe
		uart_uint(TZaehler);						// TILT Zählerstand über UART
		putChar("B");								// Kontrollausgabe, Zeilenumbruch	

		TKorrektur=TZaehler-TZaehler_A-TWeg_Kor;	// Berechne Korrekturwert für nächsten lauf
		TZaehler_A=TZaehler;						// merke Zählerstand vor dem Lauf
		TWeg_Kor=TWeg-TKorrektur;					// Berechne korrigierten Weg

		while (TZaehler<TZaehler_A+TWeg_Kor-5)		// Laufe solange bis gewünschter Zählerstand-Rampe erreicht
		{
			OCR1B=1000;								// schneller Lauf, mit hohem PWM Wert
			PORTB|=0b000010000;						// Laufe Drehrichtung SÜDEN
		}
		while (TZaehler<TZaehler_A+TWeg_Kor)		// Laufe Rest solange bis Rampe zuende
		{
			OCR1B=500;								// lansamer Lauf, mit reduziertem PWM Wert
			PORTB|=0b000010000;						// Laufe Drehrichtung SÜDEN
		}

	}

	while (TDir==-1)								// TILT Drehrichtung -> NORDEN
	{
		TDir=0;										// setzte Drehrichtung wieder auf null -> damit nur ein 

		putChar(" TZ_:");							// Kontrollausgabe
		uart_uint(TZaehler);						// TILT Zählerstand über UART
		putChar("B");								// Kontrollausgabe, Zeilenumbruch	

		TKorrektur=TZaehler-TZaehler_A-TWeg_Kor;	// Berechne Korrekturwert für nächsten lauf
		TZaehler_A=TZaehler;						// merke Zählerstand vor dem Lauf
		TWeg_Kor=TWeg-TKorrektur;					// Berechne korrigierten Weg

		while (TZaehler<TZaehler_A+TWeg_Kor-5)		// Laufe solange bis gewünschter Zählerstand- Rampe erreicht
		{
			OCR1B=1000;								// schneller Lauf, mit hohem PWM Wert
			PORTB|=0b000100000;						// Laufe Drehrichtung NORDEN
		}
		while (TZaehler<TZaehler_A+TWeg_Kor)		// Laufe Rest solange bis Rampe zuende
		{
			OCR1B=500;								// lansamer Lauf, mit reduziertem PWM WertM
			PORTB|=0b000100000;						// Laufe Drehrichtung NORDEN
		}

	}
	PORTB&=0b11001111;								//  Keine Taste gedrückt -> also STOP, Bit 4&5->0
}



// ********************* HAUPTBPROGRAMMTEIL ******************************
// **********************************************************************
// **********************************************************************

main (void)
{
	// ************************ Variablen *******************************	

	// ********************* Initialisierungen  **************************	

	initPWM();								//Initialisiere PWM Ausgänge
	initPORTS();							//Initialisiere die Ports
	initEXISR();							//Initialisiere den Exteren Interrupt
	initUART();								//Initialisiere UART für Kontrollausgabe
	sei();									//Ermögliche Interrupts

	// ************************* HAUPTSCHLEIFE  *****************************		
	// **********************************************************************

	while (true) 							// Mainloop
	{
		TastenSTG();						// Tastenabfrage für Motorstart mit jew. Richtung
		PanMotorGo(PRichtung,100);			// Fahre PAN Achse in jew. Richtung mit 100 Schritten
		TiltMotorGo(TRichtung,100);			// Fahre TILT Achse in jew. Richtung mit 100 Schritten

		_delay_ms(100);						// warte 100 ms bis Motor endgülig steht


// AUSGABE der Variablen über UART zu Kontrollzwecken


		if (PRichtung!=0)					// Einmalige Kontrollausgabe über UART nach PAN Lauf
		{
			putChar(" PK:");					// Kontrollausgabe PAN Korrekturwert
			uart_uint(PKorrektur);
			putChar(" PZ_A:");					// Kontrollausgabe PAN Zählerstand am Anfang
			uart_uint(PZaehler_A);
			putChar(" PW_K:");					// Kontrollausgabe PAN korrigierter Weg
			uart_uint(PWeg_Kor);
			putChar(" PZ:");					// Kontrollausgabe PAN Zähler der HALL Impulse
			uart_uint(PZaehler);

			putChar("B");						// Zeilenumbruch
			putChar("B");						// Zeilenumbruch
		}

		if (TRichtung!=0)						// Einmalige Kontrollausgabe über UART nach TILT Lauf 
		{
			putChar(" TK:");					// Kontrollausgabe TILT Korrekturwert
			uart_uint(TKorrektur);
			putChar(" TZ_A:");					// Kontrollausgabe TILT Zählerstand am Anfang
			uart_uint(TZaehler_A);
			putChar(" TW_K:");					// Kontrollausgabe TILT korrigierter Weg
			uart_uint(TWeg_Kor);
			putChar(" TZ:");					// Kontrollausgabe TILT Zähler der HALL Impulse
			uart_uint(TZaehler);

			putChar("B");						// Zeilenumbruch
			putChar("B");						// Zeilenumbruch
		}

		PRichtung=0;						// PAN Drehrichtung wieder auf Null -> Motor Stop
		TRichtung=0;						// TILT Drehrichtung wieder auf Null -> Motor Stop

	}
}

// ************************* ENDE HAUPTSCHLEIFE ************************		
// **********************************************************************