Hallo Leute,
für ein Schrittmotortestgerät möchte ich in 10Hz-Schritten eine Frequenz
von 10 bis 1000 Hz erzeugen, um Motorkennlinien aufzunehmen. Meine
Lösung wäre eine recht hohe Timerfrequenz durch einen hochauflösenden
Teiler via LookUp-Table herunterzuteilen, so daß es die gewünschte
Frequenz trifft. Gibt es da vielleicht noch andere programmtechnische
Möglichkeiten, das Ganze eleganter zu bewerkstelligen? Der Controller
ist ein AtTiny2313, programmiert wird in ASM.
Vielen Dank für eure Mühe!
Wenn du den Vorteiler nicht ändern musst, sollte es
doch eine Formel geben, die den Zusammenhang zwischen
Timerfrequenz und gewünschter Ausgabefrequenz beschreibt
und aus der du den Teilerfaktor rauskriegst.
Wie berechnest du den Teilerfaktor für 10 Hz?
DDS?
Programmiere einen Interrupt mit 2560Hz. In jedem Interrupt addierst du
f/10 zu einem Register dazu. In deinem Fall also Werte von 1..100. Wenn
das Register einen Wert größer 128 enthält, setzt du deinen Ausgang,
sonst löschst du ihn. Bei höheren Frequenzen dürfte allerdings die
Symmetrie des Signals nicht mehr optimal sein...
Das Problem an der Sache wird sein, dass man beim Timer nicht die
Frequenz, sondern die Periodenpauer einstellt.
Somit ist ein Sprung von 10Hz auf 20Hz ziemlich groß, ein Schritt von
990Hz auf 1000Hz aber sehr klein.
Für eine (lineare) Rampe (100Hz-2kHz) habe ich das mal mit einem
Lookup-Table gemacht (100 Werte oder so; müsste ich nachgucken...).
Na okay, vielen Dank - ich probiere mal DDS-Variante durch und berichte
dann. Die Signalsymmetrie ist übrigens Bockwurst, da sie nur zum
Initiieren des nächsten Steps für den Motor dienen soll.
Grüße!
TravelRec.
Hallo,
damit Du nicht so viel Zeit verballerst, schau mal in die letzte
Elektor. Da sind einige Schnipsel für den R8C vorgestellt. Auch ein DDS
Generartor, alles in C, damit locker portierbar und immer noch reichlich
Luft für eigene Experimente.
Grüße
Lothar
Lothar, vielen Dank, aber C ? Nee, das nicht auch noch ;-) Ich guck mal,
was ich in ASM zusammenstricken kann, mir hat ja eigentlich nur ein
Lösungsansatz gefehlt (war damals in Mathe krank ;-) ).
> mir hat ja eigentlich nur ein> Lösungsansatz gefehlt (war damals in Mathe krank ;-) ).
Ich nehme meinen Vorschlag mit der Formel wieder
zurück. Rahul hat Recht. Das gibt einen ekeligen
1/x Zusammenhang. Grob geschätzt denke ich, dass
eine vorgefertigte Tabelle einfacher sein dürfte.
Excel lässt grüssen.
So, also probiert und für gut befunden: die Lösung von Uwe Nagel trifft
denselben quasi genau auf den Kopf, jetzt habe ich eine schön lineare
Funktion innerhalb der Grenzen, wo ich sie brauche.
DANKE UWE!
Es ist übrigens auch kein Problem, mit diesem Verfahren ein
grundsätzlich perfekt symmetrisches Signal zu erzeugen. Dazu musst Du
die ganze Sache nur genau doppelt so schnell machen und "Wenn das
Register einen Wert größer 128 enthält, setzt du deinen Ausgang"
ersetzen durch "Wenn das Register einen Wert größer 128 enthält,
toggle den Ausgang (--> Frequenzhalbierung) und setz das Register auf
0 zurück".
Der Tip ist gut, aber ich schalte keinen Pin, sondern ein Flag. Um dies
zu realisieren, habe ich den Überlauf des Registers (Carry) verwendet,
da sonst das Flag ständig gesetzt würde, wenn der Wert 128 überschritten
wird. Allerdings habe ich auch selbst gerade gemerkt, daß es dann zu
regelmäßigen Sprüngen kommt, weil durch die Addition ungerader Zahlen
immer ein Rest im Register verbleibt, auf den dann wiederum addiert
wird. Jetzt habe ich kurzerhand 2 Register genommen, wobei ich nur eine
Variable von 0-255 benutze und den Überlauf des 2. (oberen) Registers
als Ausgabewert benutze. Das Ergebnis ist ein "kerzengerader" Lauf des
Motors in einem ausreichend weiten Bereich. Nochmals danke für die
Anregungen!