Timer Programmierung

Hallo an alle

Heute muß ich mal Euch um Eure Hilfe bitten.

Ich programmiere gerade eine Beschleunigungskurve für einen Schrittmotor.
Mein Problem ist, daß die Zeit für die Berechnung der einzelnen Teilkurven bzw der Zeitberechnung der Verzögerungszeit bei konstanter Geschwindigkeit nicht gleich ist. Der Unterschied ist ca 36 µS zu 180µS.

Da ich bis jetzt die Rechteckspannung für die Absteuerung des Pololu Schrittmotortreibers mit delay() gemacht haben und mein Testaufbau ein alter Schlitten mit Spindelantrieb ist, welchen ich im 16-Microstepp sehr schnell drehen lassen kann (ca 12500Hz, 250 U/min 200 Schritte/U) ist der Einfluß der Zeit für die Berechnung der Kurve sehr significant gegenüber der reinen Delay()-Verzögerung.

Die Zeitbasis für die Rechteckspannung kann ich natürlich mit micros() programmieren, aber ich möchte einen Timer benutzen.
Der Bereich der Periode meines Schrittsignal und damit der Zeitverzögerung sollte von 100000µS bis ca 200 µS gehen.

Kann mir jemand helfen und die Verwendung eines Timers für diesen Zweck erklären?

Danke im voraus
Uwe

Timer werden bei der Arduino-Programmierung eher stiefmütterlich behandelt. Das liegt vermutlich daran, dass dieses Thema ziemlich komplex ist und Einsteiger eher überfordert. Daher stellt die Arduino-IDE auch keinen Befehlssatz für die entsprechende Programmierung zur Verfügung, die Programmierung muss damit hardwarenah erfolgen, indem man manuell die Register des verwendeten Mikrocontrollers setzt.
Ich bin weit davon entfernt, mich als Experte bezeichnen zu können. Ich komme ursprünglich aus der Bascom-Ecke, da sind entsprechende Timer-Funktionen schon in der Sprache enthalten. Somit kann ich zwar in der Theorie etwas mithelfen (hoffe ich zumindest), die Umsetzung des Ansatzes ist allerdings eine andere Frage. :wink:

Der Uno und auch der Duemilanove verwenden ja einen Atmega328. Wenn man sich deren Datenblätter ansieht findet man folgendes:

– Two 8-bit Timer/Counters with Separate Prescaler and Compare Mode
– One 16-bit Timer/Counter with Separate Prescaler, Compare Mode, and Capture Mode

So ein Timer macht eigenlich nichts anderes, als stumpf vor sich hinzuzählen. Ganz einfach wie die Uhr im Nachbarzimmer: ohne mein Zutun verstreicht Stunde um Stunde. Als Basis hat sie ihren Sekundentakt, einen Takt brauchen wir ebenso beim Timer des Mikrocontrollers. Es liegt also nahe, direkt auf den des Mikrocontrollers zurückzugreifen, der durch unseren Quarz vorgegeben ist. Man kann auch externe Takte benutzen, soll aber hier nicht behandelt werden.

Aber zurück zu unserem Quarz: 16 MHz ist aber ganz schön viel, daher gibt es sogenannte Prescaler (Vorteiler). Wenn die aktiviert sind, wird nicht 16 Mio. mal in der Sekunde ausgewertet, sondern anhand des angegebenen Teilungsverhältnisses (8, 64, 256, 1024 gem. Datenblatt). Bei einem Prescaler von 1024 also nur noch 16.000.000/1024 = 15625. 15,625 kHz ist also die Grundfrequenz unserer Timer-Uhr, in Analogie zu unserer Uhr im Nachbarzimmer das nervige Tick-Tack.
Die Sekunden zählen also schonmal munter vor sich hin, zu jeder vollen Stunde wird eine Glocke angeschlagen, die uns weiterhin die Nerven raubt. Wir wissen also, dass uns alle 3.600 Sekunden ein heller Klang aus unserer angestrengten Programmierarbeit reißt. Dieser Ablauf von 3.600 Takten mit anschließendem Akustiksignal entspräche in unserem Beispiel der Vorgabe des Timers: die anfangs erwähnten 8bit-Timer zählen 256 Schritte bis zum Auslösen des Interrupts, der 16bit-Timer gleich 65.536 Schritte. Das klingt zwar alles super hat aber noch nichts mit den Vorgaben von Uwe zu tun, weil bisher noch alles unflexibel abläuft.

Bleibe ich mal beim Uhrenbeispiel. Zu jeder vollen Stunde bekommen wir einen Schreck, werden aus unseren Tagträumen gerissen... Es ist nun 11:10 Uhr, Mittagessen soll pünktlich um 12:00 Uhr auf dem Tisch stehen. Nun nutzt es mir ja nichts, das Glockensignal um 12 Uhr abzuwarten, man will ja dem holden Weib zumindest ein bisschen Arbeit abnehmen und den Tisch decken, Getränke aus dem Keller holen etc.. Wir brauchen also etwas Vorlauf, die Wanduhr hat aber keine separate Weckfunktion. Wir sind ja nicht dumm, und verstellen die Uhrzeit von 11:10 auf 11:25. Resultat: Die Glocke schlägt 15 Minuten früher an, genug Zeit also noch für die anderen wichtigen Dinge.

Und genau das selbe machen wir mit dem Timer. Er muss nicht immer von 0 bis 255 (8bit) bzw. bis 65.536 (16bit) zählen. Wir können ihn mit einem flexiblen Wert einfach vorladen, womit wir wieder Herr über die Glocke äh den ausgelösten Interrupt werden!

Uwe kann für seine flexiblen Zeiten einfach unterschiedliche Werte vorladen und den Interrupt auslösen lassen und dort den nächsten Motorschritt vorgeben, abhängig vond er Motorposition bzw. der Anzahl der verstrichenen Motorschritte ist dann ein anderer Wert vorzuladen, um Anfahrrampen zu programmieren.

Warum nicht gleich im Mikrocontroller.net schauen? Dort sitzen die echten Experten :wink:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Zähler_des_AVR

Hallo Udo

Hatte schon angefangen zu lesen, wollte aber mal ausnahmsweise den Schnarotzer spielen :wink: :wink: :wink:

Sweit ich verstanden hab,e muß ich den 16 Bit Timer nehmen und den Prescaler während der Kurve wechseln, da der gesamte Bereich nicht abgedeckt ist.

Außerdem hab ich ein bißchen die Besorgnis daß mir eine Bibliothek dazwischenfunkt.

Mal sehen
Grüße Uwe

Man kann auch Timer hintereinander schalten. Dann kann man sogar 24 bzw. 32 bit Auflösung erreichen.

Man kann fast alles hintereinander schalten, - so bekommt man auch '11,7' statt 10 Bit Auflösung ( mit Oversampling ).
Fragt sich immer ob der Aufwand und die Rechenzeit dafür gerechtfertigt sind.

MfG

Gurkengraeber:
Man kann fast alles hintereinander schalten, - so bekommt man auch '11,7' statt 10 Bit Auflösung ( mit Oversampling ).
Fragt sich immer ob der Aufwand und die Rechenzeit dafür gerechtfertigt sind.
MfG

Hallo Gurkengraeber
Das klingt interessant; wie kann ich also den Timer oversampeln?
Danke in Voraus für die Hilfe
Grüße Uwe

@Gurkengräbar, der Aufwand ist gering falls man noch Pins frei hat. Man verbindet den Eingang eines Timers mit dem Ausgang eines Anderen. Das ist kein Oversampling und relativ einfach.

Was Du genau mit Oversampling meinst würde ich aber gerne verstehen.

Ich "spiele" auch immernoch mit dem Timer zur Schrittmotoransteuerung.
Hilft Dir Frequenzerzeugung mit Timer - Deutsch - Arduino Forum schon etwas weiter?
So langsam bekomme ich das hin, nur an der praktischen Umsetzung haperts noch.