Hallo! Ich möchte mit dem Timer2 des ATMEGA16 ein Servo Signal erzeugen, d.h. ich benötige eine High Phase von 0,8 ... 2,2ms aber nur alle 20ms. Ich grübel gerade wie man das am besten realisieren kann. Mein Timer2 benötigt 4,6ms um einmal hoch und wieder runter zu laufen, wenn er das einmal gemacht hat würd eich ihn gerne dazu benutzen die Pause von 15,34ms zu timen. Das Problem ist wie erkenne ich dass er genau einmal hoch und wieder runter gelaufen ist? Overflow und Compare Match Interrupt helfen mir hier nicht. Mir fällt dazu keine Lösung ein... Hat jemand einen Tipp? Geh ich die Sache vielleicht komplett falsch / zu kompliziert an?
Warum hoch und runter? Es genügt die Fast-PWM und die läuft nur hoch. Das Problem ist der geringe Zählumfang des Timer2, da dies nur ein 8-Bit-Timer ist. Du wirst damit also nicht gleichzeitig die Impulsdauer von 1..2 ms und die Periodendauer von 20 ms abbilden können, zumindest nicht halbwegs feinstufig aufgelöst. Servoimpulse sind aber aus Sicht des AVRs dermaßen schnarchlangsam, dass man sie ohne Weiteres per Software im OCR-Interrupt generieren kann. Siehe z.B. hier: http://www.hanneslux.de/avr/mobau/7ksend/7ksend02.html ...
5*HW-Servo-PWM auf mega1281 (3xtimer1 & 2xtimer3) void PWM_Init (void) { DDRB |= (1<<PB5) | (1<<PB6) | (1<<PB7); DDRE |= (1<<PE3) | (1<<PE4); // Reset TCCR1A = 0; TCCR1B = 0; ICR1 = 0; // Mode (Fast-PWM TOP=ICRn) TCCR1A |= (1<<WGM11); TCCR1B |= (1<<WGM13) | (1<<WGM12); // Output-Pins TCCR1A |= (1<<COM1A1) | (1<<COM1B1) | (1<<COM1C1); // Prescaler TCCR1B |= (1<<CS11); // Top (Overflow) ICR1 = 10000; OCR1A = 500 + 255; OCR1B = 500 + 255; OCR1C = 500 + 255; // Reset TCCR3A = 0; TCCR3B = 0; ICR3 = 0; // Mode (Fast-PWM TOP=ICRn) TCCR3A |= (1<<WGM31); TCCR3B |= (1<<WGM33) | (1<<WGM32); // Output-Pins TCCR3A |= (1<<COM3A1) | (1<<COM3B1); // Prescaler TCCR3B |= (1<<CS31); // Top (Overflow) ICR3 = 10000; OCR3A = 500 + 255; OCR3B = 500 + 255; sei(); } Mit Software-PWM währe ich Vorsichtig, je nach dem wie viel die MCU noch zu tun hat (IRQ's) kann es ekelhafte Zuckungen in den Servos kommen !!!
> 5*HW-Servo-PWM auf mega1281 (3xtimer1 & 2xtimer3)
Und wie soll das jetzt dem OP mit seinem 8-Bit-Timer helfen?
garnett, 8bit ist mist, wollte nur zeigen wie ich das mache ! Wobei der Prescaler nochmal geändert werden könnte. DBD Olli PS: kannst ja auch mal was nützliches Beitragen ;-)
Hm ja das hilft mir noch nicht weiter, mir steht nunmal nur der TIMER 2 mit seinen 8Bit zur Verfügung... Gibt es denn keine Möglichkeit zu erkennen ob er einmal hoch und wieder runter gelaufen ist? Das wäre eine Lösung.
>Gibt es denn keine Möglichkeit zu >erkennen ob er einmal hoch und wieder runter gelaufen ist? Jein, es kommt auf den PWM-Mode an. Das, was du schreibst, klingt nach dem Phase-Correct-PWM-Mode. Ungünstige Wahl, wobei man da den oberen "Umschaltpunkt" erkennen kann. Man sollte aber (wie Hannes es schon ansprach), den Timer nur in einer Richtung laufen lassen z.B. FastPWM-Mode Da kann man dann für den Impuls eine obere Grenze setzen, bei der der zugehörige Pin ausgeschaltet wird. Eingeschaltet wird der Pin bei 0. Beim Erreichen der oberen Impulsgrenze wird ein Interrupt ausgelöst, in dessen ServiceRoutine dann der Pinschaltautomatismus wieder abgeschaltet wird. Jetzt zählt man noch die Anzahl der Timerüberlaufe und kann so die 20ms abschätzen. Die müssen nämlich nicht hoch genau eingehalten werden.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.