Frage zum TIMER2 des ATMEGA

OP #1233267
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?
Gast #1233290
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

...
#1233297
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 !!!
Gast #1233410
>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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.