Forum: Mikrocontroller und Digitale Elektronik Frequenz von 10Hz bis 1000Hz generieren


von TravelRec. (Gast)


Lesenswert?

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!

von Karl heinz B. (kbucheg)


Lesenswert?

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?

von Uwe N. (ulegan)


Lesenswert?

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...

von inoffizieller WM-Rahul (Gast)


Lesenswert?

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...).

von TravelRec. (Gast)


Lesenswert?

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.

von Christoph Kessler (db1uq) (Gast)


Lesenswert?

ja DDS ist das sinnvollste.
Dann gäbe es noch den Binary rate multiplier mit 2*74167
http://pdf1.alldatasheet.com/datasheet-pdf/view/109191/TI/SN74167.html
oder eine PLL-Schaltung (in Analogtechnik, etwas entsprechendes 
digitales müßte man sich erst mal überlegen).

von Lothar (Gast)


Lesenswert?

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

von TravelRec. (Gast)


Lesenswert?

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 ;-) ).

von Martin Schneider (Gast)


Lesenswert?

Ich habe mal den Generator von Jesper

http://www.myplace.nu/avr/minidds/index.htm

nachempfunden - geht ganz prima.

Ahoi, Martin

von Karl heinz B. (kbucheg)


Lesenswert?

> 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.

von TravelRec. (Gast)


Lesenswert?

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!

von AVRFan (Gast)


Lesenswert?

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".

von TravelRec. (Gast)


Lesenswert?

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!

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.