mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PWM und Timer für Dumme


Autor: Peter F. (piet)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Zuerstmal, ich hab mir schon einen Rechteck Generator mit Grafik LCD, 
variabler Pulsweite und Frequenz gebaut.
Auch ne Stoppuhr im ms Sekunden bereich mit GLCD hab ich hin bekommen 
aber ich bekomm es gerade nicht auf die Reihe ne simple Soft-PWM für nen 
Servo zu ralisieren die so funktioniert wie man erwarten sollte.

ATMega16 bei 5V und 16Mhz
Fuse auf ext. Crystal / High Freq
Das ganze in C

Ziel ist, Frequenz 50Hz, das sind 20ms.
Pulsweite von 1,5ms bis 2,5ms

Takt nach Prescaler:
16000000 / 8 = 2000000

Sekunde je Takt:
1 / 2000000 = 0,0000005000

Ein überlauf bei einem OCR0 wert von 200:
0,0000005000 / 200 = 0.0001 Sekunden

Zählschleife im Interrupt macht daraus 20ms wenn "pwmcounter" einen Wert 
von 200 hat:
0.0001 * 200 = 0,02 Sekunden

Jetzt wird "servo_pos[0]" mit "pwmcounter" vergliechen.
Eine Pulsweite von 1,5ms würde also einem "servo_pos[0]"-Wert von 150 
entsprechen.
Eine Pulsweite von 2,5ms würde also einem "servo_pos[0]"-Wert von 250 
entsprechen.

Da ist aber irgendwo ein Fehler drinn... Es geht nähmlich nicht, zum 
nachmessen habe ich leider nichts da...
Ich hab aber rausgefunden das ein Wert von 5 bis 20 den Servo zum 
bewegen bringt.
Habe drei verschiedene Servos:
Nummer1 geht mit werten von 5 bis 20
Nummer2 macht genau das gegenteil von Nummer1 mit werten von 5 bis 20
Nummer3 macht nur komische Sachen.

Wo hab ich den Fehler?

Aus dem Code:
// soft-PWM loop counter
uint8_t pwmcounter = 0;

// servo positions
volatile uint8_t servo_pos[10] = {15,16,16,16,16,7,22,40};

// initialise servos and timer
void init_servos(void) {
  
  // set servoport as output 
  SERVODDR = 0xFF;
  SERVOPORT = 0xFF;

  // soft-PWM timer0 in ctc mode with prescaler 8
  TCCR0 = (1<<WGM01) | (1<<CS01);

  // enable timer0 compare match interrupt
  TIMSK = (1<<OCF0);

  // timer0 compare value
  OCR0 = 200;
}

[c]
// timer0 soft-PWM interrupt
ISR(TIMER0_COMP_vect) {

  // when counter value is servo value set pin low
  if(pwmcounter == servo_pos[0]) {
    SERVOPORT &= ~(1<<SERVO0);
  }

  // reset soft-PWM counter set all pins high
  if( pwmcounter++ == 200) {
    pwmcounter = 0;
    SERVOPORT = 0xFF;
  }
}
[c]

Autor: STk500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>uint8_t pwmcounter = 0;

mach den mal volatile


Und das Thema "Modellservo ansteuern" hatten wir hier schon zuhauf...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter F. schrieb:

> Zählschleife im Interrupt macht daraus 20ms wenn "pwmcounter" einen Wert
> von 200 hat:
> 0.0001 * 200 = 0,02 Sekunden
>
> Jetzt wird "servo_pos[0]" mit "pwmcounter" vergliechen.
> Eine Pulsweite von 1,5ms würde also einem "servo_pos[0]"-Wert von 150
> entsprechen.
> Eine Pulsweite von 2,5ms würde also einem "servo_pos[0]"-Wert von 250
> entsprechen.

Hmm
Ein Stück weiter oben hast du ausgerechnet, dass ein wert von 200 ganzen 
20ms entspricht. Und hier wäre dann ein wert von 250 auf einmal nur 
2.5ms?

Um es mit Ede Zimmermann zu sagen: Da stimmt doch was nicht.


Im übrigen: kleb nicht an den 20ms. Die sind das unwichtigste in der 
ganzen Ansteuerung.

PS2: Ein einzelnes Servo kann ein Timer auch ganz alleine in einem PWM 
Modus ansteuern.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.