Servo mit 16Bit PWM ansteuern

OP #2904252
Lesenswert?

ich möchte ein Servo mit dem 16Bit Timer per PWM ansteuern. Dazu habe 
ich folgenden Code geschrieben.
1
#include <avr/io.h>
2
#include <util/delay.h>
3

4
#define F_CPU 1000000                 // CPU-Frequenz = 1MHz (1 Clockzyklus = 1 / 1MHz = 1us)
5

6
int main(void)
7
{
8
  DDRD = 0xFF;                   // PD2 (OC1A) = Ausgang
9

10
  TCCR1A = (1<<WGM11)|(1<<COM1A1)|(1<<COM1A0);   // Set OC1A on compare match
11
  TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10);     // Fast PWM, Top = OCR1A, Prescaler = 1
12

13
  ICR1 = 19999;                   // compare match auf 19999 setzen
14

15
  while(1)
16
  {
17
    OCR1A = ICR1 - 800;             // Servo nach rechts drehen
18
    _delay_ms(100);               // 100ms warten
19
    OCR1A = ICR1 - 2200;             // Servo nach links drehen
20
    _delay_ms(100);               // 100ms warten
21
  }
22
}

Leider erhalte ich am Ausgang (OC1A) kein PWM Signal.
Hat wer eine Idee wo der Fehler liegt?

Mein Controller: AT90PWM316
Gast #2904278
Lesenswert?

H. G. schrieb:
> ICR1 = 19999;                   // compare match auf 19999 setzen
> OCR1A = ICR1 - 800;

Was soll das werden?

Das ICR ist dein TOP-Register, enthält also den Wert, bis zu dem gezählt 
und dann wieder von 0 angefangen wird.
Wenn ICR das TOP-Register sein soll, musst du Timermode 14 auswählen, 
wie Spess schon geschrieben hat.

Den Capturewert OCR1A solltest du noch mal nachrechnen.
Die Impulse sind 1-2ms lang - nicht 17,8 bis 19,2 ms...
#2904295
Lesenswert?

Vielleicht sollten wir erst mal eines klären

> Leider erhalte ich am Ausgang (OC1A) kein PWM Signal.

Wie hast du das verifiziert?

Hast du ein Oszi drann gehängt und es kommen wirklich keine Pulse
oder
hast du ein Servo drann gehängt und das rührt sich nicht vom Fleck, weil 
die Pulslängen falsch sind

Also. Was ist es?
Gast #2904302
Lesenswert?

Hi

>Ah ja, Sorry das Kommentar ist falsch. Muss heissen Top = ICR1

Ja, das hat mich irritiert. Du bist im Mode 14.

Im Moment fällt mir kein Fehler auf. Allerdings erschließt es sich mir 
nicht, warum du invertierte PWM mit der komischen Umrechnung (OCR1A = 
ICR1 - 800) benutzt. Bei nichtinvertierter PWM brauchst du einfach nur 
deinen Wert nach OCR1A schreiben.

MfG Spess
#2904306
Lesenswert?

Hmm. Ich seh allerdings nichts im Programm, was da jetzt dagegen 
sprechen würde.

Sicher das das Programm richtig geflasht wurde. Sicher das, der µC 
läuft? Sicher, dass du am richtigen Pin bist?

Mach da mal ein
1
  while(1)
2
  {
3
    OCR1A = ICR1 - 800;             // Servo nach rechts drehen
4
    _delay_ms(100);               // 100ms warten
5
    OCR1A = ICR1 - 2200;             // Servo nach links drehen
6
    _delay_ms(100);               // 100ms warten
7

8
    PORTD ^= ( 1 << PD0 );    // <-----    
9
  }

rein. AM Pin PD0 müsstest du Pulse sehen.
OP #2904327
Lesenswert?

also ich hab das jetzt so gemacht:
1
  while(1)
2
  {
3
    //OCR1A = ICR1 - 800;               // Servo nach rechts drehen
4
    //_delay_ms(100);               // 100ms warten
5
    //OCR1A = ICR1 - 2200;             // Servo nach links drehen
6
    //_delay_ms(100);               // 100ms warten
7
    PORTD ^= (1<<PD2);
8
    PORTD ^= (1<<PD0);
9
  }

Am PD0 erhalte ich die Impulse und am PD2 nichts. Ich werde mal mein 
Board nachprüfen.

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