Forum: Mikrocontroller und Digitale Elektronik Servo Ansteuerung


von Sascha (Gast)


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^^

von Sascha (Gast)


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
}

von Michael K. (Gast)


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

von Michael K. (Gast)


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

von Sascha (Gast)


Lesenswert?

Danke
so ist natuerlich perfekt :)

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
Noch kein Account? Hier anmelden.