AVR: PWM-Ansteuerung eines Servo funktioniert nicht richtig

OP #958361
Lesenswert?

Aalso ich benutze ein Board mit einem ATMEGA 644P. ICh habe einen 
Servomotor angeschlossen...dieser braucht ja eine PWM mit einer 
Periodendauer von 20ms was 50 Hz entspricht und eine Pulsbreite von 1 
bis 2 ms.
Dies habe ich in C so realisiert:

int main(void){

DDRB = 1<<4;

/*
Ich nutze also den Port OC0B, einen der beiden Pinne des 8-Bit-Timers.
Ich überlege noch einen der 16-Bit-Pinne zu nutzen, aber zunächst sollte
es ja auch so laufen.
*/

TCCR0A = (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
TCCR0B = (1<<WGM02)|(1<<CS02);
OCR0A = 78;
OCR0B = 6;

/*
Die WGM-Bits stellen Fast-PWM ein, und zwar zählt der Zähler bis OC0RA, 
also 195 um dann wieder von 9 zu starten. Die IO-Frequenz von 1 Mhz 
(interner 8 Mhz RC-Oscillator wird genutzt mit per Fusebits 
eingeschaltetem Vorteiler 8) wird durch 256 geteilt. Den Zähler um eins 
zu erhöhen dauert also 1s/(1000000/256) =0.256ms. Wenn der Zähler immer 
bis 78 zählt ist also eine Periodendauer von 19.2ms erreicht was 
ziemlich genau dem verlangten Wert entspricht. OCR0B von 6 ergibt in 
Kombination von nicht-invertiertem Betrieb eine Pulsbreite von ziemlich 
genau 1.5ms (78*1.5/20)
*/

while(1){}

return(0);
}

So. Der Servomotor ist an einem anderen Board getestet worden, bei 1ms 
Pulsbreite ging er zum einen Anschlag, bei 2ms zum Anderen und bei 1.5ms 
in Mittelstellung.

Nun verhält er sich ganz anders. Egal was ich einstelle er dreht gegen 
den Uhrzeigersinn bis zum Anschlag und versucht weiter zu laufen. Egal 
was ich bisher eingestellt hab. selbst wenn ich gar kein PWM-Signal 
draufgebe und nur 5V und Masse anschließe. Hat jemand ne Idee was da los 
ist? Ist in meiner Überlegung zur PWM mit AVR vielleicht etwas 
Grundlegendes falsch? Oder ist der Motor in der kurzen Zwischenzeit wohl 
doch kpuatt gegangen? Wie gesagt vor kurzem lief er wie er sollte.

Danke im Vorraus.
OP #958474
Lesenswert?

Ich hab mal versuchsweise eine PWM künstlich gemacht indem ich einen 
normalein portpin high setze, 1 bis 2 ms delay mache, ihn low setze und 
20ms delay mache, das alles in einer while(1) schleife.
Auch bisschen die Zeiten variiert...aber die Motoren drehen nur in eine 
Richtung, mit konstanter Geschwindigkeit, teilweise ruckend, aber ohne 
zu versuchen eine bestimmte Position anzusteuern...was ist hier los?
#958652
Lesenswert?

#include <avr\io.h>

int main(void)
{
//volatile unsigned char temp = 1<<4;

DDRB = 1<<4;

/*
Ich nutze also den Port OC0B, einen der beiden Pinne des 8-Bit-Timers.
Ich überlege noch einen der 16-Bit-Pinne zu nutzen, aber zunächst sollte
es ja auch so laufen.
*/

TCCR0A = (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
TCCR0B = (1<<WGM02)|(1<<CS02);
OCR0A = 78;
OCR0B = 5;

/*
Die WGM-Bits stellen Fast-PWM ein, und zwar zählt der Zähler bis OC0RA,
also 195 um dann wieder von 9 zu starten. Die IO-Frequenz von 1 Mhz
(interner 8 Mhz RC-Oscillator wird genutzt mit per Fusebits
eingeschaltetem Vorteiler 8) wird durch 256 geteilt. Den Zähler um eins
zu erhöhen dauert also 1s/(1000000/256) =0.256ms. Wenn der Zähler immer
bis 78 zählt ist also eine Periodendauer von 19.2ms erreicht was
ziemlich genau dem verlangten Wert entspricht. OCR0B von 6 ergibt in
Kombination von nicht-invertiertem Betrieb eine Pulsbreite von ziemlich
genau 1.5ms (78*1.5/20)
*/


while(1)
{
  asm volatile ("nop");
}

  return(0);
}


So läuft der Aufbau mit 49,5Hz und 1,52... 1,56ms Pulsdauer, habs eben 
getestet.

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