Hallo Zusammen Ich habe mir ein Programm geschrieben, das eine Frequenz von 10Hz bis ca. 32khz erzeugen soll. Im folgendem Testprogramm ist eine Variable "takt??", die die Frequenz definiert. Jetzt habe ich aber das Problem, dass die Frequenz im Verhältnis zur Variable im Quadrat zunimmt. Beispiel: Variable - Frequenz 32000 - 10hz 16000 - 20hz 8000 - 40hz 4000 - 80 hz ... 10 - 32khz Ich möchte aber das die ganze Sache Linear ist: 32000 - 10hz 16000 - 16khz 10 - 32khz Hier der Code: do takt?? = 32000 gosub wait_takt out (&h378),&b00000010 'Out hight gosub wait_takt out (&h378),&b00000000 'Out low loop wait_takt: ! push ax ! push cx ! mov cx, takt?? wait1: '1. Verzögerungsschlaufe ! dec cx ! mov ax, 300 'Kalibrierwert wait2: '2. Verzögerungsschlaufe ! dec ax ! cmp ax, 0 ! jg wait2 ! cmp cx, 0 ! jg wait1 ! pop cx ! pop ax return Es sind zwei Verzögerungsschlaufen ineinander verschachtelt, wobei die zweite als Kalibrierschlaufe dient, diese hat auch immer die gleiche Dauer. Hat jemand eine schlaue Idee, wie ich das ganze irgendwie Linear hinbekommen ? Aufbau der Verzögerungsschlaufe ?
Nach welcher Rechenregel sollen denn die Zuordnungen 32000 - 10hz 16000 - 16khz 10 - 32khz funktionieren? Was soll sich denn aus der Vorgabe 16001 ergeben? Und was soll sich aus der Vorgabe 11 ergeben? Wenn du das klar und eindeutig erklären kannst, findet sich ein Weg (auch wenn es nicht mit jedem µC machbar sein wird) dies zu programmieren.
Hol Dir einen 16F150x PIC. Der hat einen schicken NCO. (NCO := Numerically Controlled Oscillator) Quasi ein DDS für Rechteck- und Pulssignale. Einfach den Wert in ein Registerpaar schreiben. Fertig. Wenn man will, kann man die Ausgabe des NCO noch mit den integrierten CLC (Configurable Logic Cell) verwursten.
Michael L. schrieb: > Jetzt habe ich aber das Problem, dass die Frequenz im Verhältnis zur > Variable im Quadrat zunimmt. Diese Funktion verläuft wie 1/x und nennt sich Kehrwert... Michael L. schrieb: > Ich möchte aber das die ganze Sache Linear ist: > 32000 - 10hz > 16000 - 16khz > 10 - 32khz Ähm, das wäre eine Art "umgekehrt proportional", aber irgendwie vermischst da beliebig einen Integerwert mit einer Frequenz. Ich hätte an deiner Stelle wenistens gefordert, dass der Verlauf so ist: 32000 - 32kHz // 16000 - 16kHz // 10 - 10Hz > Ich möchte aber das die ganze Sache Linear ist: Das wird mit diesem einfachen Ansatz nicht gehen. Vor allem die Dynamik über mehr als 3 Zehnerpotenzen (10Hz - 32kHz) ist recht sportlich. Der Tipp mit dem NCO geht in die richtige Richtung, aber leider haben das die wenigsten uC eingebaut. Eine Frage hätte ich noch: reichen dir Zehnerschritte (also 10Hz, 20Hz, 30Hz, ...) oder willst du da sogar noch Einerschritte?
Michael L. schrieb: > Jetzt habe ich aber das Problem, > dass die Frequenz im Verhältnis zur Variable im Quadrat zunimmt. > > Beispiel: > Variable - Frequenz > 32000 - 10hz > 16000 - 20hz > 8000 - 40hz > 4000 - 80 hz > ... > 10 - 32khz Was ist daran quadratisch? Der Zusammenhang scheint wie folgt zu sein: 320.000 / Variable = Frequenz > Ich möchte aber das die ganze Sache Linear ist: > 32000 - 10hz > 16000 - 16khz > 10 - 32khz Das geht nicht linear. Durch diese drei Punkte läßt sich keine Gerade legen. Für die ersten beiden Punkte wäre die lineare Funktion folgende: Frequenz = 31990 - Variable * (15990/16000) Damit kommt für einen Wert von 10 aber eine Frequenz von ca. 31,98 kHz raus. Übrigens: Michael L. schrieb: > Verzögerungsschlaufen > Kalibrierschlaufe > Verzögerungsschlaufe Die Dinger heißen nicht Schlaufen, sondern Schleifen.
nun, das Problem ist, man stellt den Timer ein, dieser zählt Takte, misst also die Zeit. Und da die Zeit der Kehrwert der Frequenz ist wird das nie linear werden. Ich hab sowas auch schonmal programmiert (bzw. bin noch dabei 0,2-20Hz). Ich hab dazu eine Tabelle vorher berechnet und als Array abgespeichert. Dieses enthält die Reloadwerte der Timer sowie die Menge der Überläufe bei kleineren Frequenzen. Ich muss es aber noch optimieren. Im Originalaufbau hatte ich den inneren Frequenzgenerator verwendet (weil ich eine bestehende Platine nutzte) aber damit wird das zu ungenau und nicht reproduzierbar. Ich hab keine Lust bei jedem aufgebauten Gerät Manuell die Werte nachzujustieren... Wenn die finale Hardware fertig ist mach ich da weiter. Es gibt genug Timerrechner im Netz, welche dir die Rechnerei abnehmen. oder du schreibst dir schnell was in Excel.
Vielen Dank erstmal für eure tipps !! Die Variable ist der Zeitwert, also Anzahl der Schleifen Wiederholungen. Wenn die Variable auf 10 ist, so wird nur ganz kurz zwischen High und Low gewartet. Soweit sollte das jedem verständlich sein.... Beim genannten Wert 10, habe ich eine Frequenz von etwa 32khz, würde ich den Wert auf 5 setzten, so habe ich eine Frequenz von 64khz, aber soviel brauche ich nicht. Letztlich spielt es mir keine Rolle, ob die Variable von 0 - 32000, oder 32000 - 10 die entsprechende Frequenz ausgibt. Es muss einfach linear sein. Ich brauche eine Frequenz von min 10hz bis ca. 30 - 32 khz. Am besten mit einer Auflösung von etwa 5hz. Wie gesagt, muss die maximal Frequenz nicht genau 32khz sein, 30khz reichen auch. Noch etwas: Das ganze läuft nicht auf einem uC, sondern auf einem ganz normal PC mit DOS, die Frequenz wird am LPT ausgegeben. Jedoch zum programmieren ist es genau gleich wie bei einem uC. Das ganze wird eine Schrittmotorensteuerung, die Frequenz gibt dann die Drehzahl des Motors vor, deshalb brauche ich eine "linear regelbare Frequenz". Die Kalibrierschleife dient dazu, damit die Drehzahl genau kalibriert werden kann. Wenn jemand einen Lösungsvorschlag oder einen Tipp hat, wie man das bewerkstelligen könnte, währe ich ihm dankbar.
Was ist denn "ganz kurz" für eine Zeiteinheit? Kann man die zwischen 29,999 und 30,000 kHz vernachlässigen? Oweh, Wünsche hat er, aber Denken mag der TO nicht. Tschüs.
Bernie schrieb: > Kann man die zwischen 29,999 und 30,000 kHz vernachlässigen? Ja, denn Michael L. schrieb: >> mit einer Auflösung von etwa 5hz. D.h. 29,999 und 30,000 kHz sind gleich. Aber 29,995 und 30,000 kHz sind unterschiedlich... > aber Denken mag der TO nicht. Nicht zu weit aus dem Fenster lehnen... ;-) Michael L. schrieb: > Beim genannten Wert 10, habe ich eine Frequenz von etwa 32khz, würde ich > den Wert auf 5 setzten, so habe ich eine Frequenz von 64khz, aber soviel > brauche ich nicht. Ja klar. Aber damit hast du vom Wert 10 nach 11 auch keinen 5Hz Schritt, sondern gut 3kHz. Für die von dir gewünschte feinere Auflösung müsstest du also etwa 600 mal schneller sein. So wie ich das Ganze ansehe schaffst du aber bestenfalls (nach Weglassen der 300er-Schleife und der Push-Pop Orgie) eine Beschleunigung um den Faktor 150-200. Deine Schritte würden also dort im 32kHz Bereich mindestens 20Hz groß werden. Um die 5Hz-Granularität bei 30kHz jitterfrei zu bekommen bräuchtest du einen (Hardware-)Zähler, der mit mindestens 200MHz läuft. > Noch etwas: Das ganze läuft nicht auf einem uC, sondern auf einem ganz > normal PC mit DOS, die Frequenz wird am LPT ausgegeben. Jedoch zum > programmieren ist es genau gleich wie bei einem uC. Oh, scheiss Salamitaktik. Die Antwort lautet: Vergiss es. Denn allein der Jitter, den dir irgendwelche Interrupts auf diesem Gerät machen, wird dein Konzept zerlegen. Aber: wenn du schon einen Rechenboliden hast, dann sollte doch die Berechnung des Kehrwerts nach der oben geposteten Formel nicht allzu schwer sein... @ Michael: Das 'H' in Hertz schreibt man weltweit GROSS!
Du solltest ernsthaft darüber nachdenken, den 8253 Timer des PC zu benutzen. Gut, Channel 0 ist schon auf den Ticker eingestellt mit 18,2 Hz, Channel 1 besorgt mit ca. 66kHz den DRAM Refresh, aber Channel 2 versorgt den PC Speaker und das ist der, mit dem du bestens rumspielen könntest. Alles andere ist zu sehr abhängig vom CPU Takt und auch wg. der oben erwähnten Interrupts einfach nicht brauchbar. http://computer-programming-forum.com/40-scheme/fa1ab14f38fe7211.htm http://computer-programming-forum.com/46-asm/cbb489b2413bf90c.htm
Also alle störenden Interrupts habe ich ausgeschaltet. "OUT (&H21), 252". Einige sind jedoch noch aktiv, wie beispielsweise die Systemuhr, aber die stören nicht, respektive, die Systemuhr brauche ich noch für andere Aufgaben. Mit der Schleifen-taktik, habe ich die Frequenz gemessen, und diese ist konstant. Für meine Anwendung einwandfrei. Mit dem 8253 Timer habe ich mich bereits auch schon herumgeschlagen, aber irgendwie klappts nicht so richtig... Wenn es funktionieren würde, währe das eine feine Sache, unabhängig vom CPU takt. Ich habe, wie Matthias beschrieben hat, den Kanal 2 des Speakers verwendet. Jedoch weis ich nicht, wie ich den Timer konfigurieren muss, damit ein Interrupt ausgelöst wird, wenn dieser bei 0 ankommt. Somit könnte ich in einer ISR den Ausgang auf high oder low schalten. Oder gibts eine andere Möglichkeit ? Konfiguration des Timers: OUT (&H61), INP(&H61) OR 1 'Lautsprecher und damit Zähler 2 aktivieren OUT (&H43), 176 '8253 Zähler 2 auf Modus 0 setzen
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.