Hallo,
Ich versuche mich gerade daran, über einen µC einen Schrittmotor sauber anzusteuern. Der Code steht und läuft auch bedingt.
Zum Aufbau:
Atmega 168 - 20 PU
16 Mhz
Verwendeter Timer: Timer1, 16bit, Prescale 64 ->250000Hz
getakteter Ausgang zum Ansteuern eines Schrittmotortreibers mit Halbschritt (800Im/Umdrehung)
Der Atmega 168 berechnet die Beschleunigungsrampe simultan im Interrupt und passt den Timer1 entsprechend an. Die Berechnung muss aus Genauigkeitsgründen mit zwei Variabeln des Typs Single erfolgen da sonst ein Fehler auftritt.
Bei kleineren Drehzahlen, wenn der Timerwert oberhalb von ca. 100 Counts (entspricht 3U/s) bleibt, läuft die Rampe sauber bis zum Ende.
Steigere ich die Drehzahl kommt er hier wahrscheinlich zu Verzögerungen - die Hochlaufzeit erhöht sich deutlich und der Motor dreht unsauber am Ende der Hochlauframpe.
Den hohen Prescale habe ich gewählt, um dem Controller genug Rechenzeit zu lassen, leider kann ich -meines Erachtens nach- nicht viel an der Berechnung ändern. Ohne Float-Werte hängt sich die Rampe irgendwann auf!
Hier der Code-Ausschnitt aus dem eigentlichen Interrupt:Code:$regfile = "m168def.dat" $crystal = 16000000 ' used crystal frequency $hwstack = 32 ' default use 32 for the hardware stack $swstack = 8 ' default use 10 for the SW stack $framesize = 24 $baud = 19200 Config Timer1 = Timer , Prescale = 64 '250000 Hz On Timer1 X_irq Enable Interrupts Dim C0 As Integer Dim Cn As Single Dim Cn_s As Single Dim Steps As Word Steps = 0 C0 = 8450 Cn = 8450 Load Timer1 , C0 Enable Timer1
Nun bin ich mir nicht sicher, ob ich irgendwo am Code etwas ändern kann, oder ob es vielleicht einen stärkeren Atmega für diese Aufgabe gibt?Code:X_irq: Toggle Pul Incr Steps Cn_s = Cn Cn = 2 * Steps Cn = Cn + 0.5 Cn = Cn_s / Cn Cn = Cn_s - Cn Load Timer1 , Round(cn)
Würde es eventuell helfen einen Atmega mit mehr Ram zu verwenden, oder eventuell auf 20Mhz umzusteigen?
MFG Erik







Zitieren


Lesezeichen