Forum: Compiler & IDEs Denkfehler mit Servo über Timer0?


von Dirk W. (bastelator) Benutzerseite


Lesenswert?

Hallo zusammen,

irgendwo habe ich bei der Ansteuerung eines Servos via Timer0 einen 
Denkfehler drin. Kann mir jemand einen Hinweis geben?

Das ganze schien mir sooo schön einfach :(

Gruß,
Dirk



[...]
int main (void) {
OSCCAL = eeprom_read_byte(0x00);

DDRB|=(1<<PB0);
PORTB&=~(1<<PB0);

TCCR0B = (1<<CS01); //Teiler 8 --> 1.000.000 Hz
TIMSK = (1<<TOIE0); //Overflow-Interrupt
TCNT0 = 0x00-100;   //10.000 Hz bei 100Bit Overflow
sei();

  for (;;) {

  delay_ms_(1000);
  servowert = 10;
  delay_ms_(1000);
  servowert = 20;

  }

}



SIGNAL(SIG_OVERFLOW0)
{
TCNT0 = 0x00-100;    //10.000 Aufrufe/sec  --> alle 0,1msec
timer0temp++;      //--> 200 Aufrufe für 20 msec

  if (timer0temp <= servowert){  //servowert zwischen 10 (1ms) und 20 
(2ms)
      PORTB|=(1<<PB0); //ein
  }else{
      PORTB&=~(1<<PB0); //aus
  }

  if (timer0temp == 200)  timer0temp = 0;

}

von Björn R. (sushi)


Lesenswert?

Sorry, hab gerade keine Zeit mir deins ganz durchzulesen, aber schau 
doch mal auf meiner Homepage, da gibts den Quellcode für nen 
Servotester. In C und auch mit dem Timer gemacht. Sieht mir genau aus 
wie das was du vor hast. Einfach mal angucken, vielleicht hilfts dir ja. 
Der link zum Artikel: 
http://modellbau.bug-soft.net/index.php?cat=et&art=servotester
Ich guck morgen nochmal hier rein, wenn ich Zeit hab, und guck obs 
geklappt hat. Wenn nicht stehe ich zur Verfügung, weil ich das mit dem 
Servo schon fertiggebracht habe und dann vielleicht auch mal helfen kann 
g
Aber davon jetzt nicht abschrecken lassen es nochmal selbst zu 
versuchen!
LG, Björn

von Dirk W. (bastelator) Benutzerseite


Lesenswert?

Hallo Björn,

danke für den Link, ich wollte das ganze aber nur mit dem 
Overflow-Interrupt lösen (mal schauen, ob das geht). Per Hardware-PWM 
habe ich das auf einem Mega32 auch schon einmal hinbekommen, ist aber 
eine Weile her.

Ein bisschen weiter bin ich schon: Der Servo funktioniert mit dem o.g. 
Programm, alle Änderungen der relevanten Variablen werden aber 
ignoriert. Er stellt sich immer auf den Initialwert ein. Vermutlich ist 
die Interrupt-Schleife zu lange, auch wenn ich mir das nicht so richtig 
vorstellen kann. Evtl. zieht der Servo den AVR auch ständig in den Reset 
wg. Strombedarf. Werde morgen mal den Oszi anwerfen. Die einfache 
Timer0-Overflowschleife funktioniert aber im Prinzip -- und man kann sie 
noch für andere Timingzwecke missbrauchen.

Beste Grüße und gute Nacht,
Dirk

von Björn R. (sushi)


Lesenswert?

Hast du auch das volatile bei der deklaration von servowert nicht 
vergessen?!?

von Dirk W. (bastelator) Benutzerseite


Lesenswert?

AAAAAHHH! Björn, Du bist mein Held des Tages! Das wird's sein, jetzt 
setze ich mich noch einmal kurz dran.

Das kommt davon, wenn man einen Germanisten auf µCs loslässt ;)

[... 1min später...]

Ja, das wars.

Tausend Dank und beste Grüße,

Dirk

p.s.: Für's Forenarchiv: Codefragment im Anhang (gewiss optimierbar, 
aber läuft jetzt)

von Dirk W. (bastelator) Benutzerseite


Angehängte Dateien:

Lesenswert?

s. Anhang (ging nicht mit Editierfunktion)

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.