Hi,
danke für eure zahlreichen Beiträge & Vorschläge! Da werde ich mich gleich mal durcharbeiten. Bei meiner Regelung ist das Hauptziel nicht die Synchronität, sondern der minimale Zeitversatz zwischen Sensoren auslesen / Rechnen / PWM ausgeben. Wobei das natürlich auch zusammenhängt. Ich versuche mich mal einfach heranzutasten das Ganze überhaupt richtig zu verstehen... Denn im Moment verstehe ich noch alles maximal halb. Ist folgendes richtig?
Mein PWM Timer ist so konfiguriert:
Code:
Config Tcd0 = Pwm , Prescale = 1 , Comparea = Enabled , Compareb = Enabled , Comparec = Enabled , Compared = Enabled , Event_source = Off , Event_action = Off , Event_delay = Disabled , Resolution = 16
Der µC läuft mit dem internen 32 MHz Takt.
TcD0_cnt ist der aktuelle Wert vom PWM Timer. Dieser läuft immer wieder von 0 auf 65535. Wenn TcD0_cnt den Wert null erreicht gehen alle PWM Pins auf High. Sobald TcD0_cnt einen bestimmten Wert erreicht (eingestellt per Tcd0_cca, Tcd0_ccb, Tcd0_ccc und Tcd0_ccd) geht der entsprechende Pin auf Low.
Ich muss die Berechnungen der Regelung starten kurz bevor TcD0_cnt sein Maximum erreicht. Angenommen die Berechnungen dauern 1 ms, dann muss ich die Berechnungen bei TcD0_cnt = 33535 starten. Wenn TcD0_cnt den Wert 65535 erreicht hat sind meine Berechnungen fertig (32000 Ticks bzw. 1 ms später). Bei TcD0_cnt = 65535 bzw. 0 gehen die PWM Pins hoch und bleiben dort bis die errechneten Werte (Tcd0_cca bis Tcd0_ccd sind immer zwischen 4000 und 8000 = 125 bis 250 µs) erreicht wurden.
Mir wurde immer gepredigt, dass man so wenig Code wie möglich im IRQ laufen lassen soll... Es gibt ja auch noch einen zweiten Interrupt vom RC Empfänger der sehr präzise sein muss. Für mich klingt es am einfachsten in der Main Loop den Wert von TcD0_cnt abzufragen und die Berechnungen zu starten sobald dieser größer als 33535 ist.
z.B. so:
Code:
if TcD0_cnt < 33535 then
RechnenDarfGestartetWerden = 1
end if
if TcD0_cnt > 33535 AND RechnenDarfGestartetWerden = 1 then
RechnenDarfGestartetWerden = 0
RechneAllesAus
end if
Lasst mich raten: So geht es nicht. Wäre ja auch zu schön. Ich probiere es jetzt trotzdem aus und berichte was passiert.
- - - Aktualisiert - - -
Lasst mich raten: So geht es nicht. Wäre ja auch zu schön. Ich probiere es jetzt trotzdem aus und berichte was passiert.
Hmmm... Also ich habe das so mal eingebaut, und Schwuuupps, mein Code läuft mit genau 500 Hz. Ich habe kein Oszi hier, deswegen kann ich nicht gucken ob der Code wirklich das tut was er soll (außerdem weiß ich auch nicht wie lange meine Berechnungen denn wirklich brauchen). Aber ich denke mal rein theoretisch sollte das doch gehen... Ist dieser Ansatz programmiertechnisch sehr schlimm, oder kann ich das so machen?
- - - Aktualisiert - - -
Noch ein kurzer (evtl. schwachsinniger) Gedanke: Angenommen, ich verwende den Code so wie vorgeschlagen. Dann wäre es cool, wenn der Zeitpunkt zu dem die Berechnungen gestartet werden sich automatisch optimal einstellt. Ich kann mit einer groben Schätzung starten, und dann verschiebt sich der Start (z.B. um 0.1 ms) nach vorne falls eine Berechnung mal nicht fertig wurde. Ansonsten wird der Start Zeitpunkt immer ganz langsam nach hinten verschoben (z.B. jeden Durchgang um 0.001 ms). So pendelt der Startzeitpunkt um den optimalen Wert herum, egal was ich noch alles so an Berechnungen einbaue.
Lesezeichen