Hi!
Ich möchte gerne 4 Servos schnell ansteuern (mit vielleicht 100 bis 200 Hz). Im Anhang findet Ihr ein Bild mit dem angedachten Aufbau. Die Framezeit scheint total unkritisch zu sein. Mein Programm funktioniert anscheinend wunderbar, allerdings frage ich mich wie effizient mein Code wohl ist...
Hier mal mein Bascom Code:
Code:$regfile = "m32def.dat" $framesize = 32 $swstack = 32 $hwstack = 64 $crystal = 16000000 $baud = 9600 Config Timer0 = Timer , Prescale = 64 'je höher prescale desto resourcenschonender? On Timer0 Timer_irq Dim Servo1time As Byte 'servo1 high-time Dim Servo2time As Byte 'servo2 high-time Dim Servo3time As Byte 'servo3 high-time Dim Servo4time As Byte 'servo4 high-time Dim Kanal As Byte 'Kanal 1-4 Dim I As Byte Dim Timeraufnull As Bit 'Timer Zurücksetzer Enable Timer0 Enable Interrupts Config Portb = Output Portb.0 = 0 'hier hängt servo1 Portb.1 = 0 'hier hängt servo2 Portb.2 = 0 'hier hängt servo3 Portb.3 = 0 'hier hängt servo4 Kanal = 1 Timeraufnull = 0 Servo1time = 131 'Preload 131 = 2000Hz = 0.5ms pulse Servo2time = 131 Servo3time = 131 Servo4time = 131 Do '----- Das ist nur Code um Servos zu bewegen --> unwichtig For I = 0 To 255 'Servo1 Servo1time = I Waitms 50 'bisschen warten damit servo auch position erreichen kann 'Servo2 If I < 163 Then Servo2time = I + 20 Else Servo2time = 131 End If 'Servo3 If I < 170 Then Servo3time = 301 - I Else Servo3time = 150 End If 'Servo4 If I < 140 Then Servo4time = I Else Servo4time = 170 End If Next I Loop End Timer_irq: If Kanal = 1 Then If Portb.0 = 0 Then 'wenn port low... Timer0 = Servo1time 'dann timer auf gewünschte länge... Portb.0 = 1 'und port auf high Else 'portb.0 = 1 If Timeraufnull = 1 Then 'port erst wieder auf low wenn der timer Portb.0 = 0 'servo1time gelaufen ist UND einmal zurückgesetzt wurde. Incr Kanal 'das ergibt dann: 0 bis 1ms + 1ms = 1 bis 2ms high Timeraufnull = 0 Else 'TimerAufNull=0 Timeraufnull = 1 Timer0 = 6 'ergibt 1ms bis zum erneuten überlauf End If End If End If 'und hier das gleiche für die anderen kanäle... If Kanal = 2 Then If Portb.1 = 0 Then Timer0 = Servo2time Portb.1 = 1 Else If Timeraufnull = 1 Then Portb.1 = 0 Incr Kanal Timeraufnull = 0 Else Timeraufnull = 1 Timer0 = 6 End If End If End If If Kanal = 3 Then If Portb.2 = 0 Then Timer0 = Servo3time Portb.2 = 1 Else If Timeraufnull = 1 Then Portb.2 = 0 Incr Kanal Timeraufnull = 0 Else Timeraufnull = 1 Timer0 = 6 End If End If End If If Kanal = 4 Then If Portb.3 = 0 Then Timer0 = Servo4time Portb.3 = 1 Else If Timeraufnull = 1 Then Portb.3 = 0 Incr Kanal Timeraufnull = 0 Else Timeraufnull = 1 Timer0 = 6 End If End If End If If Kanal > 4 Then Kanal = 1 End If Return
Ablauf:
Kanal = 1 und Portb.0 ist aus. Der Preload des Timers wird auf die gewünschte Länge gesetzt , z.b. 152 = 2400Hz = 0,416ms. Der Port wird angeschaltet, der Rest des Timer_irq wird nicht ausgeführt.
Nach 0,416ms wird erneut in Timer_irq gesprungen. Nun wird die Variable "Timeraufnull" auf "1" gesetzt, und der Preload des Timers auf 6 = 1000Hz = 1ms gesetzt. Timer_irq wird wieder verlassen.
Nach 1,416ms wird nochmal ins Timer_irq gesprungen. Jetzt wird Portb.0 ausgeschaltet, die Kanalnummer um eins erhöht und "Timeraufnull" wieder auf 0 gesetzt. Noch während dieses Interrupts wird das ganze für Servo2 eingeleitet usw....
Meine Fragen:
Es gibt 8 Interrupts von Timer0 um alle Servos zu stellen. Ist das gut so, oder nimmt man besser Timer1 mit Prescale=1?? Das ergäbe auch ne gute Auflösung, außerdem nur 4 Interrupts um 4 Servos zu stellen. Aber der Prescale wäre nur 1, und das ist doch ungünstig?
Wie stelle ich Performance des Programms fest? Im Simulator steht was von Cycles und "mS", kann man das benutzen um zu errechnen wie schnell ein Programm läuft?
In Zukunft soll das Programm auf einem ATmega644 mit 20 MHz laufen. Dann ist die maximale Pulslänge den ich mit Prescale=64 erreichen kann 0,8159ms und nicht mehr 1,019 ms. D.h. ich komme nicht mehr auf 2 ms wenn ich zwei Interrupts zusammenzähle, sondern nur noch auf ca. 1,632 ms. Das reicht nicht für den Vollausschlag eines Servos... Was tun? Evtl drei Interrupts zusammenhängen? Das wird aber ungleich komplizierter....
Wenn mir jemand ein bisschen weiterhelfen könnte wäre das fantastisch....!







Zitieren

Lesezeichen