Code:
	#define F_CPU 14745600 
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define FOSC 14745600 //Clock Speed
#define BAUD 9600
#define UBRR ((FOSC / (BAUD * 16L)) - 1)
#define STATE_IDLE    			10
#define STATE_SERVO1  			20
#define STATE_SERVO2  			30
#define STATE_PWM     			40
// Initialisierung Timer0
void timer0_init();
//// Initialisierung Timer1
void timer1_init();
// Initialisierung Timer2
void timer2_init();
//Initialisierung UART
void uart_init();
//Werte für das erste Signal
volatile unsigned char Array_Servo1[] = { 20, 45, 245, 54, 255, 54, 255, 54, 255, 54, 255, 54, 255, 54, 255, 54, 255, 35};
//Werte für das zweite Signal
volatile unsigned char Array_Servo2[] = { 20, 45, 245, 54, 255, 54, 255, 54, 255, 54, 255, 54, 255, 54, 255, 54, 255, 35};
//Zähler für ausgelösten Compare-Interrupt beim ersten Signal
volatile unsigned char NrCompare_Servo1 = 0;
//Zähler für ausgelösten Compare-Interrupt beim zweiten Signal
volatile unsigned char NrCompare_Servo2 = 0;
//Zähler für das erste Signal
volatile unsigned int Count_Servo1 = 0;
//Zähler für das zweite Signal
volatile unsigned int Count_Servo2 = 0;
unsigned char i, d;
//Hilfsaray zur Byteauswertung beim UART-Empfang für Servo1
unsigned char array1[8];
//Hilfsaray zur Byteauswertung beim UART-Empfang für Servo2
unsigned char array2[8];
//Zeiger für die Byteauswertung beim UART-Empfang für Servo1
unsigned char *tmp;
//Zeiger für die Byteauswertung beim UART-Empfang für Servo2
unsigned char *tmp2;
unsigned char c;
/*Funktion des Interrupts: Die Schleife wird 18 mal durchlaufen. Darin wird geschaut ob NrCompare_Servo1 in diesem Durchlauf 
  gerade oder ungerade ist und dementsprechend der Port ein oder ausgeschaltet. Hat NrCompare_Servo1 das ganze Array
  abgearbeitet, fängt es wieder von vorne an.
  Danach wird der neue Wert in das Register OCR2A geschrieben. Der Timer zählt dann bis zu diesem Wert, führt ein 
  Interrupt aus, schaltet den Port um und setzt den Timer wieder auf 0 (da CTC-Modus). Das ergibt hinterher ein 
  Signal mit einem dauernden Highpegel und neun "verschiedenen" Lowpegeln. Also erster Wert Array_Servo1[0] = Highpegel,
  zweiter Wert Array_Servo1[1] = Lowpegel usw.  
  Count_Servo1 wird dann noch bis 8216 hochgezählt, um zwischen den Signalen eine Pause von ca. 90ms zu erzeugen.*/
ISR(TIMER2_COMPA_vect)
{
//erstes Signal
  {
  if(Count_Servo1 <= 17 ){				//Schleife wird 18 mal durchlaufen, also für jeden Wert des Array_Servo1 ein mal
  if(NrCompare_Servo1 % 2 == 0)			//Wenn gerade, dann ausschalten
  	PORTC &= ~(1 << PC0);
  else
  	{PORTC |= (1 << PC0);}				//Wenn ungerade, dann einschalten
	                  
  NrCompare_Servo1++; 					//Wird bei jedem Interrupt um eins hochgezählt
  if( NrCompare_Servo1 == sizeof(Array_Servo1) / sizeof(unsigned char) ) 
	  NrCompare_Servo1 = 0;
	
	OCR2A = Array_Servo1[ NrCompare_Servo1];	// Den Timer damit laden
   }
  else
  {PORTC |= (1 << PC0);}  				//Highpegel während der 90ms Pause
  }
//Zweits Signal
  {
  
  if((Count_Servo2 >= 19) && (Count_Servo2 <= 36)){
  if(NrCompare_Servo2 % 2 == 0)
  	PORTC &= ~(1 << PC2);
  else
  	{PORTC |= (1 << PC2);}
	                  
  NrCompare_Servo2++; 
  if( NrCompare_Servo2 == sizeof(Array_Servo2) / sizeof(unsigned char) )
	  NrCompare_Servo2 = 0;
	
	OCR2A = Array_Servo2[NrCompare_Servo2];	// Den Timer damit laden
   }
  else
  {PORTC |= (1 << PC2);}
  }
  Count_Servo1++;
  	
  if(Count_Servo1 == 8216)  //erzeugt eine pause von ca.90ms
     Count_Servo1 = 0;
  Count_Servo2++;
  	
  if(Count_Servo2 == 8216) ////erzeugt eine pause von ca.90ms
     Count_Servo2 = 0;
}
void timer2_init()
{
  DDRC  =  0xFF; // PORTC als Ausgang schalten
  
  PORTC =  0x00; // Alle Ausgaenge auf 0 schalten
  OCR2A = 0;
  TCCR2B |= (1 << CS21);     // Teiler 8
  
  TCCR2A |= (1 << WGM21);	 // CTC Modus
   				
  TIMSK2 |= (1 << OCIE2A);   // Timer 2 Compare Interrupt enable
}
/* Timer0 initialisieren */
void timer1_init()
{
	OCR1A = 100;	//Wert 100 im Compare Register setzen
	DDRB   = 0xff;	// Als Ausgänge 
	PORTB =  0x00;
	TCCR1A = (1<<COM1A1)|(1<<COM1A0)|(1<<WGM10); //PWM Phase Correct
	TCCR1B = (1<<CS11) | (1 << WGM12); // No prescaling
}
void uart_init()
{
DDRB |= (1 << PB2) | (1 << PB4);
/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
/* baud rate*/
UBRR0H = (unsigned char) (UBRR>>8);
UBRR0L = (unsigned char) UBRR;
/* Frame Format: 8Data-Bit, 2Stop-Bit*/
UCSR0C = (1 << USBS0) | (3 << UCSZ00);
}
// Das Hauptprogramm (Einsprungpunkt)
int main()
{
	
	//UART initialisieren
	uart_init();
	//Timer1 initialisieren
	timer1_init();
	//Timer2 initialisieren
	timer2_init();
    // Interrupts aktivieren
    sei();
    // Eine Endlosschleife.  
    while (1)
    {}
}
ISR(USART_RX_vect)
{
static unsigned char state = STATE_IDLE;
	c = UDR0;
	switch (state)
   {
    case STATE_IDLE:
             if(c == 'b')
             {
                 state=STATE_SERVO1;
             }
             if(c == 'c')
             {
                 state=STATE_SERVO2;
             }
			 if(c == 'a')
			 {
			 	state=STATE_PWM;
			 }
			 break;
    case STATE_SERVO1:
             tmp = array1;
  				for( i = 1; i; i *= 2 )
    			*(tmp++) = (c&i) ? 54 : 35;
				Array_Servo1[3]  = array1[0];
				Array_Servo1[5]  = array1[1];
				Array_Servo1[7]  = array1[2];
				Array_Servo1[9]  = array1[3];
				Array_Servo1[11] = array1[4];
				Array_Servo1[13] = array1[5];
				Array_Servo1[15] = array1[6];
				Array_Servo1[17] = array1[7];
			
			 state = STATE_IDLE;
             break;
	case STATE_SERVO2:
			tmp2 = array2;
  				for( i = 1; i; i *= 2 )
    			*(tmp2++) = (c&i) ? 54 : 35;
				Array_Servo2[3]  = array2[0];
				Array_Servo2[5]  = array2[1];
				Array_Servo2[7]  = array2[2];
				Array_Servo2[9]  = array2[3];
				Array_Servo2[11] = array2[4];
				Array_Servo2[13] = array2[5];
				Array_Servo2[15] = array2[6];
				Array_Servo2[17] = array2[7];
			
			 state = STATE_IDLE;
             break;
    case STATE_PWM:
			 OCR1A = c;
			 state = STATE_IDLE;
			 break;
    default:
             break;
    }
}
 
						
Lesezeichen