Servo Ansteuerung

Gast #810481
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^^
Gast #810508
Lesenswert?
• ▲
▼
Misst, ich mein Tiny2313, aber kommt ja (fast) aufs gleiche raus^^
ich habs mal kurz zusammengeschrieben, kanns aber erst heut abend 
testen.
1
void main (void){
2
DDRB |= (1<<PB3) | (1<<PB4);
3
OCR1AH = 0x03;
4
OCR1AL = 0xE8;
5
TIMSK |= (OCIE1A);      //Output Compare Match Interrupt
6
TCCR1B |= (1<<CS12);    //Run Timer1 prescaler 256 -> 16ms
7
sei()
8
     
9
while(1){;}                              
10
}
11

12
ISR (TIMER1_COMPA_vect){
13
TCCR1B = 0x00;  //Timer1 Stop
14
TIMSK &= ~(1 << OCIE1A); //Output Compare Interrupt
15
TIMSK |= (1<<TOIE1);    //Timer1 Overflow Interrupt
16
TCCR1A |= (1<<COM1A1) | (1<<COM1B1);   //Clear OC1A/OC1B on compare Match
17
/*
18
OCR1AH = 
19
OCR1AL = 
20
OCR1BH = 
21
OCR1BL = 
22
*/
23
PORTB |= (1 << PB3);
24
PORTB |= (1 << PB4);
25
TCCR1B |= (1<<CS10);    //Run Prescaler 1  
26
}
27

28

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

34
OCR1AH = 0x03;
35
OCR1AL = 0xE8;
36
  
37
TCCR1B |= (1<<CS12);    //Run Timer1 Prescaler 256
38
}
Gast #810515
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
Gast #810519
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 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.