Hallo

Jetzt bin ich endlich über eine einfache Servoansteuerung gestolpert die auch noch libverträglich zu sein scheint:
Code:
// Servoansteuerung mit Timer1                                         31.1.2010 mic

// Einfach und elegant, warum finde ich das erst jetzt? Timer1 (RP6-Motoransteuerung)
// läuft ja sowieso im Hintergrund. Deshalb kann man die "klassische" Servoansteuerung
// in die Overflow-ISR einbauen und mit ca. 19kHz aufrufen lassen. Timersetup der Lib:
// Mode 10, Phase Correct mit ICR1 als Top ergibt bei ICR1=210 ca. 8MHz/420=19047,6Hz ;)

// Drehbereich meiner RS-2-Servos ist von ca. 14 bis ca. 38

#include "RP6RobotBaseLib.h"

volatile uint8_t servo1, servo2, servo3, p; 	// Servopositionen und Impulszähler
uint8_t c; 												// ein Char zur freien Verfügung

int main(void)
{
   initRobotBase();
   servo1=servo2=servo3=26;	// Servomitte?
   TIMSK |= (1 << TOIE1); 		// Die Timer1 Overflow-ISR zur Servoansteuerung
	DDRA |= (E_INT1);          // Servopins auf Ausgang setzen
   DDRC |= (SCL | SDA);
   setLEDs(1);                // und los!
   startStopwatch1();
   startStopwatch2();
   startStopwatch3();
	while(1)
   {
   	for(c=0;c<6;c++)            // 6 mal ein einfaches Demo....
		{
		   setLEDs(1<<c);
			servo1=servo2=servo3=26; // mitte
   		p=50; while(p);          // warten bis 50 Impulse gesendet (ca. 1 Sek.)
   		servo1=servo2=servo3=14; // links
   		p=50; while(p);
   		servo1=servo2=servo3=38; // rechts
   		p=50; while(p);
		}
		setStopwatch1(0);
		setStopwatch2(0);
		setStopwatch3(0);
		while(c)                    // und 6 mal ein etwas anspruchsvolleres Demo
		{
		   setLEDs(1<<c);
		   if(getStopwatch1()>1000)
		   {
		      setStopwatch1(0);
				switch(servo1)
		      {
		         case 38: servo1=30; break;
		         case 30: servo1=20; break;
		         case 20: servo1=14; break;
		         case 14: servo1=21; break;
		         case 21: servo1=31; break;
		         case 31: servo1=38; break;
				}
			}
		   if(getStopwatch2()>100)
		   {
		      setStopwatch2(0);
		      servo2++;
		      if (servo2 > 38) { servo2=14; c--; }
			}
		   if(getStopwatch3()>300)
		   {
		      setStopwatch3(0);
		      if (servo3 == 10) servo3=50; else servo3=10;
			}
			task_RP6System(); // Verträglichkeitstest ;)
		}
   }
   return 0;
}
ISR (TIMER1_OVF_vect)
{
	static uint16_t servocount=1;
	if(servocount > servo1) PORTA &= ~E_INT1; else PORTA |= E_INT1; 		// PA4 XBUS 8
	if(servocount > servo2) PORTC &= ~SCL; else PORTC |= SCL; 				// PC0 XBUS 10
	if(servocount > servo3) PORTC &= ~SDA; else PORTC |= SDA; 				// PC1 XBUS 12
	if(servocount < 400) servocount++; else {servocount=1; if(p) p--;} 	// p = 1/50 Sek
}
Blöderweise finde ich grad nicht genug Servos zum Testen:

Bild hier  
http://www.youtube.com/watch?v=fGHDkUlJuh0

Gruß

mic