Code:
/* Variablen für die Servoansteuerung */
volatile unsigned char
servo_zaehler;
volatile unsigned int
servo_werte[3];
/*
* Timer1 52736 -> 0.8 ms
* 41535 -> 1.5 ms
* 30336 -> 2.2 ms
*
* Auflösung : 52736 - 30336 = 22400 Schritte
*/
void servo_init(void)
{
/* Timer1 */
TCCR1A = 0x00; // normaler Timermodus ( kein PWM )
TCCR1B = 0x00; // Timer1 deaktivieren
TIMSK = (1<<TOIE1) | (1<<TOIE0); // Timerüberlaufinterrupts aktivieren
/* Timer0 */
TCCR0 = (1<<CS02) | (1<<CS00);
TCNT0 = 0x98;
}
/****************************[ Interruptroutinen ]******************************/
/* Interrupt wird bei einem Überlauf von Timer0 ausgelöst ( alle 6,656... ms )
Es werden nacheinander die drei Servos des Beins ausgewählt und angesteuert */
INTERRUPT(SIG_OVERFLOW0)
{
unsigned int temp;
servo_zaehler++;
if (servo_zaehler > 2)
servo_zaehler = 0;
switch(servo_zaehler) // Signal für die Servos auswählen
{
case 0:
PORTD |= (1<<PD5);
break;
case 1:
PORTD |= (1<<PD6);
break;
case 2:
PORTD |= (1<<PD7);
break;
default:
servo_zaehler = 0;
}
temp = servo_werte[servo_zaehler];
TCNT1 = temp;
TCCR1B = (1<<CS10); // Timer1 aktivieren, Prescaler = 1
TCNT0 = 0x98; // Timer0 neu laden
}
/* Interrupt wird bei einem Überlauf von Timer1 ausgelöst
Setzt das Signal für die Servoansteuerung wieder zurück */
INTERRUPT(SIG_OVERFLOW1)
{
PORTD &= ~((1<<PD5)|(1<<PD6)|(1<<PD7)); // Servosignal wieder löschen
TCCR1B = 0x00; // Timer1 deaktivieren
}
Du müsstest dann nur noch die entsprechenden Werte in das Array laden. Das Beispiel hier ist jetzt für 3 Servos, sollte sich aber auf mindestens 10 erweitern lassen ( Man müsste nur die ganzen anderen Servos in die "case" Anweisung einfügen und den Wert für TCNT0 anpassen, sag wieviele du brauchts, dann kann ich dir den entsprechenden Wert geben ). Es ist jetzt einfach aus meinem Quelltext zusammenkopiert ... ich hoffe man kann trotzdem erkennen worum es geht
MfG Kjion
Lesezeichen