Hallo,
ich versuche mich an einer Servoansteuerung mittels Timer 1 in einem
Atmega8. Untenstehender Programmcode soll vorerst einfach nur den Servo
in eine bestimmte Position bringen, sonst nichts. Dazu lade ich in das
Timer Compare Register A (OCR1AL und OCR1AH) den Wert dec 20.000. Das
entspricht der Gesamtdauer Impuls + Pause von 20 ms. (Der Prozessor
läuft mit 1 MHz und der Timer im CTC Modus.)
Zum Test soll bei Auslösung des Interrupts (also bei dec 20.000) ein
Impuls ausgegeben werden, was ich mit einer einfachen Warteschleife von
256 Impulsen Länge erledige. (Zu kurz für einen Servo. Egal - ist nur
ein Test)
Ich würde also als Ergebnis ein Signal erwarten, das 256 Takte auf 5
Volt ist und den Rest auf 0 Volt. Tatsächlich ist es so, daß die 5 Volt
Phase paßt, die 0 Volt Phase jedoch viel zu kurz ist. (Ich teste das
natürlich nicht mit dem Servo, sondern schaue mir das Ergebnis mit einem
Alt-aber-gut-Oszi an) Die Gesamtdauer, in der sich das Signal
wiederholt, ist offensichtlich 256 Takte plus "ein bißchen was".
Meine Bitte wäre, ob jemand in den untenstehenden Code reinschauen
könnte. Ich bin sicher, daß ich nur irgend eine Kleinigkeit übersehe.
Was mache ich falsch bzw. wo liegt mein Denkfehler?
Vielen Dank und beste Grüße,
Nino.
1
.include "m8def.inc"
2
3
.def PulsH_L = r2 ; Servo horizontal Pulslänge in Takten
Hi
> Ich bin sicher, daß ich nur irgend eine Kleinigkeit übersehe.>Was mache ich falsch bzw. wo liegt mein Denkfehler?
Für mich liegt der Fehler schon im Konzept. Das ganze lässt sich mit dem
Timer1 ohne Warteschleife und Interrupt machen. PWM-Mode 14. Mit ICR die
Periodenzeit und mir OCR1A oder B Pulsdauer einstellen. Fertig.
mfG Spess
Nino K.L. schrieb:> ldi temp1, PulsDauer_L> out OCR1AL, temp1 ; Schreibe die Werte auch in das Timer> ldi temp1, PulsDauer_H ; Output Compare Register> out OCR1AH, temp1
Lies im Datenblatt den Abschnitt Timer1, Accessing 16-bit Registers und
korrigiere Deinen Code entsprechend.
Nino K.L. schrieb:> TIM1_COMPA:> cli ; interrupts ausschalten
Lies im Datenblatt den Abschnitt Reset and Interrupt Handling, was beim
Eintritt in den Interrupt erfolgt und korrigiere Deinen Code
entsprechend.
Hallo nochmal,
wußte ich doch, daß Profis sofort erkennen, woran es hapert. Vielen Dank
für die Hilfe!
@Peter:
Tut mir leid, daß ich die betreffenden Stellen im Datenblatt nicht
selbst gefunden hab. (Sind ja doch 230 Seiten) Danke für die Verweise,
die in weiterer Folge das Programm sofort zum Laufen gebracht haben.
@Speß:
Mit deiner Hilfe mache ich jetzt den Programmcode noch kürzer. Da ich im
uC-Bereich noch Lernender bin, hatte ich bisher den PWM Mode 14 noch
nicht benützt. Es wurde also offensichtlich Zeit. Danke für die
Information!
Beste Grüße,
Nino.