Dazu wäre der Timer 1 der ATMEGA's meiner Meinung nach optimal geeignet.Mein Ziel wäre es eben schlussendlich ein Servo ansteuern zu können
Du lässt der Controller mit 8MHz Taktfrequenz laufen und stellst den Prescaler des Timers 1 auf 8.
Somit entspricht ein inkrement des Timers 1 genau 1µs.
Du gibst nun die beiden Comparematch Interrupts des Timers frei.
Der Comparematch Interrupt A löst einen Interrupt aus.
Die Routine in diesem Interrupt zählt zum augenblicklichen Zählerstand des Timers 1 die gewünschte Impulslänge, also z.B. 1500 für 1,5ms dazu und speichert diesen Wert im Comparematch B Register ab.
Gleichzeitig wird ein Port auf High geschaltet.
Der Controller läuft nun weiter bis der Comparematch B erreicht ist.
Die Interruptroutine hier drin zählt zum aktuellen Zählerstand des Timers 1 die gewünschte Pausenzeit hinzu z.B. 19000 für 19ms.
Dieser Wert wird dann im Comparematch A Register abgespeichert.
Gleichzeitig wird der in der Comparematch A gesetzte Ausgang wieder auf 0 gesetzt.
Somit läuft die komplette Impulserzeugung im Interrupt des Controllers ab.
Die gewünschten Servoimpulslängen können direkt im Comparematch A aus Hilfsregistern übernommen werden.
Eine Erweiterung der möglichen Servokanäle auf ca 8...9 sollte problemlos möglich sein. Man braucht ja nur in der Comparematch A Routine eine Hilfsvariable einsetzen, die bei jedem Durchlauf hochgezählt wird und jeweils einen anderen Servoausgang aktiviert.
Im Comparematch B muss bei mehreren Kanälen die Pausenzeit verkürzt werden, damit man wieder auf eine Refreshrate von ca. 20ms pro Servoausgang kommt. Praktischerweise würde ich im Comparematch B immer alle benutzten Servoausgänge auf 0 setzen.
Nimmt man dafür einen komplatten Port, geht das mit einem Kommando.
Da der Zählerstand von TCNT1 bei dieser Methode nicht beinflusst wird, kann man den Timer 1 auch noch zusätzlich für Zeitmessungen o.Ä. verwenden.
Lesezeichen