www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Servo Ansteuerung


Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mega48 @ 16Mhz
Hi,
wie Servos funktionieren ist mir klar und ich hab die dinger auch schon 
zum laufen gebracht ;)

Ich möchte 2 Servos mit Timer1 ansteuern und habe mir folgendes 
überlegt:

Timer1 Compare Interrupt auf 16ms (OCR1A = 1000 und prescaler auf 256)

anschliessend auf PWM umschalten und in OCR1A und OCR1B die Position der 
servos laden (davor mit 62 multiplizieren und prescaler auf 1).
Beim Timer1 Overflow wieder auf 16ms

ist das eine "schoene" loesung? so haette die cpu einmal ca.20ms und 
einmal ca. 4ms zeit um andere spielerrein durchzurechnen?!
oder gibt es noch eine einfachere Lösung? meistens wird ja ein 1ms/255 
interrupt erzeugt und darueber die servoposition und 20ms pause 
eingestellt/perechnet, aber dies ist ja doch recht cpu lastig?!

Ich bitte um kritik^^

Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Misst, ich mein Tiny2313, aber kommt ja (fast) aufs gleiche raus^^
ich habs mal kurz zusammengeschrieben, kanns aber erst heut abend 
testen.
void main (void){
DDRB |= (1<<PB3) | (1<<PB4);
OCR1AH = 0x03;
OCR1AL = 0xE8;
TIMSK |= (OCIE1A);      //Output Compare Match Interrupt
TCCR1B |= (1<<CS12);    //Run Timer1 prescaler 256 -> 16ms
sei()
     
while(1){;}                              
}

ISR (TIMER1_COMPA_vect){
TCCR1B = 0x00;  //Timer1 Stop
TIMSK &= ~(1 << OCIE1A); //Output Compare Interrupt
TIMSK |= (1<<TOIE1);    //Timer1 Overflow Interrupt
TCCR1A |= (1<<COM1A1) | (1<<COM1B1);   //Clear OC1A/OC1B on compare Match
/*
OCR1AH = 
OCR1AL = 
OCR1BH = 
OCR1BL = 
*/
PORTB |= (1 << PB3);
PORTB |= (1 << PB4);
TCCR1B |= (1<<CS10);    //Run Prescaler 1  
}


ISR (TIMER1_OVF_vect){
TCCR1B = 0x00;  //Timer1 Stop
TIMSK &= ~(1<<TOIE1);    //Timer1 Overflow Interrupt
TIMSK |= (1 << OCIE1A); //Timer1 Output Compare Interrupt

OCR1AH = 0x03;
OCR1AL = 0xE8;
  
TCCR1B |= (1<<CS12);    //Run Timer1 Prescaler 256
}

Autor: Michael K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht ganz optimal ....

Nimm den Timer1 Mode 14 (Fast PWM).

Also 16MHz -> 62.5ns cycle time.

Für die PWM Periode brauchts rund 20ms.

=> 20ms / 62.5ns = 320.000 ==> Prescaler 8

also

ICR1 = 40000 (PWM Periode)

für OCR1A und OCR1B kannst Du dann Werte zwischen 2000 und 4000 nehmen 
(1 - 2 ms).

Grüße,
Michael

Autor: Michael K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

hier der Code:

// Timer1, Mode 14, Fast PWM, Prescaler 8, OCP A (clear), OCP B (clear)
ICR1     = 40000;
OCR1A    = 3000;
OCR1B    = 3000;
TCCR1A   = (1 << WGM11) | (1 << COM1A1) | (1 << COM1B1);
TCCR1B   = (1 << WGM13) | (1 << WGM12) | (1 << CS11);

Die Servo Impuls Eingänge dann einfach an die Pins PB3 und PB4 ....

Grüße,
Michael

Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke
so ist natuerlich perfekt :)

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.