Der erste und eigentlich schwierigere Schritt ist, die einzelnen Impulslängen der ankommenden Kanäle zu messen.
Das mach ich üblicherweise mit flankengetriggerten Interrupts, bei denen Ich dann das sensing umschalte -> Einmal steigende Flanke, Dann wieder fallende Flanke.
Da Du anscheinend gleich 8 von diesen Impulslängen messen willst, brauchst Du einen Controller der 8 geeignete Interuptquellen hat.
Da dürften sich Controller eignen, die Pin Change Interrupts unterstützen.
Die Signalausgabe ist am einfachsten über Comparematch Interrups an einem 16Bit Timer zu lösen.
Du lässt einen Zähler mitlaufen, der die aktuelle Kanalposition darstellt.
Bei einem Comparematch Interrupt wird zum aktuellen Zählerstand die Counts bis zum nächsten gewünschten Ereignis addiert.
Dieser Wert wird dann im Comparematch Register des Timers abgespeichert.
Das machst Du so lange, bis alle Impulse + Pause Übertragen wurden, dann stellst Du diesen Framecounter wieder auf 0 und es beginnt alles wieder von Vorne.
Beispiel !!!
Startbedingung, Kanal 1 wird übertragen:
Comparematch Interupt tritt auf.
Der Impulsausgang wird auf 1 geschaltet.
Der TCNT wird ausgelesen, es werden die Counts bis zum nächsten Comparematch Interrupt ( sagen wir mal 1,8ms ) zu diesem Wert dazu gezählt.
Dieser Wert wird ins Comparemach Register eingespeichert.
Die Comparematch Interrupt routine wird verlassen.
Der nächste Comparematch Interupt tritt nach 1,8ms auf.
Der Impulsausgang wird auf 0 gesteuert.
Das TCNT Register wird ausgelesen.
Dazu werden die Counts bis zum nächsten gewünschten Interrupt dazu addiert - In Deinem Fall wären das 0,2ms.
Dieser Wert wird im Comparematch Register des Counters abgespeichert.
Der Impulszähler wird Inkrementiert.
Die Comparematch Interrupt routine wird verlassen.
Beim nächsten Comparematch Interrupt also nach 1,8+0,2ms gehts dann so weiter bis alle Impulse + Startpause übertragen wurden.
Dann wird einfach der Framecounter auf 0 gesetzt und das Spielchen beginnt von vorne.
Das funktioniert sehr gut und läuft praktisch im Hintergrund, weil die komplette Impulsausgabe im Comparematch Interrupt stattfindet.
Der gleiche 16 Bit Timer kann dann auch gleich für die Impulslängenmessung der eingehenden Impulse verwendet werden, weil das TCNT Register ja nicht verändert, sondern nur gelesen wird.
Die Impulsausgabe Funktion läuft auch problemlos über die 0 Stellung des Counters drüber. Also ein Null Stellen des TCNT Registers ist absolut nicht nötig und sogar kontraproduktiv, auch wenn es für das Verständnis einfacher wäre am anfang jedes Frames das Register zu Nullen!
Nachtrag!
Wenn Du den Controller mit 8MHz laufen lässt, einen 16Bit Timer mit Prescaler 8 nimmst, dann entsprechen 1000 Counts genau einer ms.
Also ein Count ist dann 1µs lang.
Die Servoauflösung entspricht dabei ca. 1000 Schritten, was die meisten Servos ohnehin nicht mehr auflösen können.
Lesezeichen