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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren