Hi,
macht es euch doch nicht so schwer. Den PWM kannst du ganz einfach mit den Timern lösen.
Ich habe mal einige Ausschnitte aus den Programmen für Meine RC-Fernsteuerung auf Basis der XBee-Pro Funkmodule zusammengepuzzelt und angehängt, mit dem an einem Mega8 Prozessor 5 Servos angesteuert werden können sollten.
Ich hoffe es ist verständlich auskommentiert.
Es gibt ein Array mit 9 Servokanälen - 1bis 5 sind die Servos am Portb.0 bis Portb.4, Servos 6-9 gehen an eine Dummy-Variable um die Pause zwischen den Impulsen auf min ca 10ms zu halten - auch wenn alle Servos gerade nur mit 1,0ms angesteuert werden. (Die Pausenzeit ist hier Variabel - bei RC-Servos sollte sie nicht unter 10ms und nicht über 20ms liegen, alles dazwischen ist unkritisch)
Das Array beginnt mit S(1) soll aber Portb.0 ansteuern, darum das Handling mit aktservo und _aktservo.
Das ganze läuft mit 7Bit Daten (S(1)=0 erzeugt am Portb.0 einen Impuls mit 2ms Dauer, S(2)=127 erzeugt am Portb.1 einen Impuls mit 1ms Dauer)
ADC-Messungen erfolgen am Portc.1 ... Portc.5
Edit: Ich habe es aber nicht nochmal in dieser Form getestet - ich hoffe, daß es Funzt, kann es aber nicht garantieren...
Code:$regfile = "m8def.dat" $crystal = 8000000 Config Portb = Output Config Adc = Single , Prescaler = Auto , Reference = Avcc Start Adc Config Timer0 = Timer , Prescale = 64 'Timer für Servos Start Timer0 On Timer0 _timer0 Enable Timer0 Enable Interrupts Dim Durchlauf As Byte 'Zähler Servoimpulsdurchläufe Dim Aktservo As Byte 'Aktuelles Servo (ISR) Dim _aktservo As Byte 'Portpin des akt. Servos Dim S(9) As Byte 'Servowertearray Dim Servo As Word 'Dummy für verarbeitung der 4 Dummyservokanäle für die Pausenzeit Dim A as Byte 'Zähler For Next Dim B as Byte 'Zähler For Next Dim C as Word 'Annahme vom ADC Dim Temp as Word 'Mittelwertbildung ADC 'Initialisieren der Startwerte (damit Servos nicht total rumzicken oder sich im Kreis drehen...) For A = 6 To 9 'Dummykanäle der Pausenzeit S(a) = 64 Next Do For A = 1 To 5 'Die 5 Servokanäle Sollwerte erfassen Temp = 0 For B = 1 To 16 'Mittelwertbildung aus 16 Messungen C = Getadc(a) Temp = Temp + C Next Shift Temp , Right , 7 '16 Messungen a 10Bit ergeben 14Bit, diese werden auf 7Bit runterdividiert - das geht am einfachsten und schnellsten mit Shiften S(a) = Temp Next Loop '**ISR des Servotimers** _timer0: If Aktservo < 6 Then 'servos 1-5 sind echte Portpins, Portb._aktservo = 0 'Servos 6-9 gehen an Bits der Dummyvariable Servo, Else ' um die Pausenzeiten auf ca. 13...19ms zu bringen Servo._aktservo = 0 'Hier wird der Impuls abgeschaltet, nachdem die Zeit abgelaufen ist End If Incr Aktservo 'Zähler, welches Servo gerade seinen Impuls bekommt _aktservo = Aktservo - 1 'da die Ports mit Pin 0 beginnen, wird -1 gerechnet If Aktservo = 10 Then 'Rücksetzen nach den 9 Durchläufen Aktservo = 1 _aktservo = 0 End If If Aktservo < 6 Then 'Nachdem die Aktservo erhöht wurde, wird der nächste Impuls eingeschaltet Portb._aktservo = 1 Else Servo._aktservo = 1 End If Timer0 = S(aktservo) + 4 'und der Timer wird passend vorgeladen - S=0 =2ms, S=127 =1ms, S=64 =1,5ms Return







Zitieren

Lesezeichen