Ich stehe gerade etwas auf dem Schlauch! Ziel ist die Generierung eines Sinussignals mittels des Cordic-Verfahrens. Für den Winkelbereich -90° bis +90° liefert meine MATLAB-Implementierung korrekte Ergebnisse. Kann mir jedoch mal jemand erklären wie man den Cordic für beliebige Eingangswinkel nutzen kann? Diesen MATLAB-Quellcode habe ich im Netz entdeckt, jedoch leider nicht verstanden: if angle > 90, tmp = x_in; x_in = -y_in; y_in = tmp; angle = angle-90; end if angle <-90, tmp = x_in; x_in = y_in; y_in = -tmp; angle = angle+90; end Vielen Dank!
Nee, nee, so wird das nix. du hast ja nur 90 Grad Rotationen und keinerlei Iteration. Das muss kontinuierlich fortgesetzt werden. Guck Dir mal die Formel auf Wikipedia an.
Da ein Cordic nur 90° berechnet musst du 1) den Quadranten bestimmen, 2) den Input normalisieren, 3) den Cordic durchlaufen lassen 4) zuletzt den Winkel in den richtigen Quadranten verschieben
Maike schrieb: > Kann mir jedoch mal jemand erklären wie man den Cordic für beliebige > Eingangswinkel nutzen kann? 1. Winkel auf 4 normalisieren (1 Multiplikation), also 4 entspricht Vollkreis. 2. ganzen Teil abtrennen und für Quadrantenzuordnung merken (Bitoperation) 3. gebrochenen Teil zurück normalisieren (2Pi entspricht Vollkreis) oder Cordic so umschreiben, daß er mit dem auf 4 normalisierten Winkel klarkommt. (nix oder 1 Multiplikation) 4. Cordic ausführen 5. je nach ganzem Teil Ergebnis zu den Quadranten zuordnen. Eigentlich ist alles außer Punkt 4 für beliebige Winkel erforderlich. Auch Reihenentwicklungen gelten nur in begrenztem Argument-Bereich. W.S.
Durch Rundungsfehler wächst die Schwingung entweder oder klingt aus. Es muss noch eine Pegelregelung rein. Das DDS-Verfahren liefert dagegen von Natur aus konstanten Pegel.
Die Frage geht um eine Sinussignalerzeugung mittels fortlaufender CORDIC-Sinusberechnungen. Also Schwingungen. https://www.mikrocontroller.net/articles/AVR-CORDIC#Sinus.2FCosinusgenerator daher die Beschränkung auf +/-90 Grad, darüber konvergiert der Iterationsalgorithmus nicht mehr.
:
Bearbeitet durch User
Ich bräuchte doch noch einmal eure Hilfe. Ich habe mir gerade folgendes Video auf Youtube zum Thema Cordic angesehen: https://www.youtube.com/watch?v=TJe4RUYiOIg (selbst ohne Verilog Kenntnisse im Großen und Ganzen gut verständlich) Hier wird ab Minute 16:30 ebenfalls auf das Thema der Winkelbereichserweiterung eingegangen. Der Autor verwendet hier, ähnlich wie in meinem ersten Post, eine sogenannte Pre-Rotation durch, falls der Eingangswinkel außerhalb des Bereichs -90°/90° liegt: x' = -d*y y' = d*x z = z-d(pi/2) und d = +1 falls y > 0, ansonsten -1. Das funktioniert bestens, trotz allem ist es mir noch nicht wirklich klar. Ich bin von folgendem Szenario ausgegangen: Ich möchte einen Vektor [x1,y1], der sich im zweiten Quadranten befindet (angenommen der Winkel beträgt 150°), um -90° drehen, so dass er sich schlussendlich im ersten Quadranten befindet (resultierender Winkel wäre nun 60°). Ich multipliziere folglich meinen Vektor mit der zweidimensionalen Roationsmatrix R(-90°). Wenn ich nun diese ausrechne lande ich bei folgendem Ausdruck: x2 = x1*cos(-90°)-y1*sin(-90°) = y1 y2 = x1*sin(-90°)+y1*cos(-90°) = -x1 Leider passt das nicht zu der oben aufgeführten Eingangswinkel-Korrektur!?! Wo liegt hier mein Denkfehler? Vielen Dank
Die kannst die Quadranten auch dadurch erreichen, dass Du die 4.tel spiegelst!
Christoph K. schrieb: > Die Frage geht um eine Sinussignalerzeugung mittels fortlaufender > CORDIC-Sinusberechnungen. Also Schwingungen. ok, aber dass Schwingungen rauskommen, wenn man den Sinus berechnet ist nicht an den Algo gekoppelt sondern Charakter der Funktion. Der Satz hört sich so an, als ob der Algo beim Konvergieren zum Schwingen neigt. Das ist nicht der Fall. Und es ist auch so, dass SIN nicht nur für Schwingungen gebraucht wird sondern oft einfach für Winkel. Und Cordic kann überdies auch Wurzel und Tangens und die sind monotin.
>Die Frage geht um eine Sinussignalerzeugung mittels fortlaufender
CORDIC-Sinusberechnungen. Also Schwingungen.
Nee, ein DDS funktioniert anders. Ein DDS hat einen Pointer im
Phasenraum, welcher immer eine Groesse von 2^N (zB 2^32) hat, also
periodisch rundrum laeuft. Durch (rechts) Bits weglassen skaliert man
auf 2^M (zB 2^10) runter und wirft diesen Wert in eine Sinustabelle.
Oh D. schrieb: >>Die Frage geht um eine Sinussignalerzeugung mittels >>fortlaufender CORDIC-Sinusberechnungen. Also Schwingungen. > > Nee, ein DDS funktioniert anders. So? > Ein DDS hat einen Pointer im Phasenraum, welcher immer > eine Groesse von 2^N (zB 2^32) hat, also periodisch > rundrum laeuft. Durch (rechts) Bits weglassen skaliert > man auf 2^M (zB 2^10) runter und wirft diesen Wert in > eine Sinustabelle. Ach. Und was macht man, wenn man keine Sinustabelle will? Hmm. Mal schauen. Interpolationspolynom?! Hmm. Nee. Zuviel Multipliziererei. ... grübel... grübel... ...grübel...
Possetitjel schrieb: > So? Possetitjel schrieb: > Ach. Tja. Das sag ICH. Ist doch logisch, daß ein DDS was ganz anderes ist als ein CORDIC. Muß ich dir das erklären? Also: ein DDS liefert bei konstanter Samplefrequenz den Phasenwinkel eines Ausgangssignals relativ beliebiger Frequenz. Deren Auflösung hängt nur von der Mantissenbreite des DDS, also dessen Zeigerlänge ab. Wenn du dann aus dem Phasenwinkel, der per se einen Sägezahn ergibt, einen Sinus oder Cosinus oder weiß der Geier was sonst haben willst, brauchst du ne Umrechnung, also sin(Phasenwinkel) oder eben geier(Phasenwinkel). Possetitjel schrieb: > Interpolationspolynom?! Hmm. Nee. Zuviel Multipliziererei. > ... grübel... grübel... Tja, wenn du keine Tabelle für sowas haben willst, dann rechne eben. Der Cordic ist ein Rechenverfahren, was man mit etwas Geschick auf verschiedenste Funktionen zurechtschneidern kann. Im Prinzip besteht er aus einer Pseudodivision, gefolgt von einer Pseudomultiplikation. Wenn du jetzt "hä?" denkst, dann guck mal: Ein Beispiel für e^X: e^(A+B+C+D) ist ja gleich 1 * e^(A) * e^(B) * e^(C) * e^(D) gelle? Nun denke dir, daß A..D so sind, daß e^(A)= 1.1 ist, e^(B)= 1.01, e^(C)= 1.001 und e^(D)= 1.0001 Wie machst du am kürzesten die obige Multiplikation aus e^(A)...e^(D) ? Eben, du brauchst bloß zu schieben und zu addieren. Das ist die Pseudo-Multiplikation. Jetzt brauchst du eine Zahl X bloß nach A..D zu zerlegen. Das ist die Pseudo-Division. Sie besteht nur aus tentativen Subtraktionen, also so etwa: if X >= A then ( X-A, merke A für später) if X >= B then ( X-B, merke B für später) .. usw. Jetzt hast du Merker für A..D, womit du Erg = 1 if merk(A) then Erg = Erg + Erg*0.1 if merk(B) then Erg = Erg + Erg*0.01 if merk(C) then Erg = Erg + Erg*0.001 usw. Da wir sowas nicht dezimal, sondern binär tun, braucht es da nur Additionen und Schiebereien. Klaro? Ach, nochwas: Mit jedem Schritt wird bei der Zerlegung der Rest ja immer kleiner und bei der folgenden Pseudomultiplikation verschwindet (binomische Regeln) das quadratische Glied in Richtung null. Was übrig bleibt, ist ein immer lineareres stück, so daß man z.B. beim Sinus den schieren Rest einfach so verwenden kann - ohne weitere Pseudodivision. Soweit ich das mal gehört hab, wurde dieses Verfahren zum Berechnen transzendenter Funktionen per Subtraktionen, Verschiebungen und Additionen in frühen Taschenrechnern von HP benutzt. W.S.
W.S. schrieb: > Soweit ich das mal gehört hab, wurde dieses Verfahren zum Berechnen > transzendenter Funktionen per Subtraktionen, Verschiebungen und > Additionen in frühen Taschenrechnern von HP benutzt. So ist es. Das ist auch mein Kenntnisstand. Der Cordic-Algorithmus ist schon sehr gebrauchsfähig, braucht aber im Einzelfall sehr hohe Auflösungen der Vektoren.
Man kann mit dem Cordic auf zwei Arten ein Sinussignal erzeugen. Entweder wie ich es gemeint habe durch (relative) Winkelberechnungen bezogen auf den vorherigen, mit einem sehr kleinen Winkelvorschub. Das läuft schnell aus dem Ruder. Ähnlich sind auch schwingende IIR-Filter, die können auch als Sinusgenerator parametriert werden, man muss dort aber auch die Amplitude nachregeln. Oder man nimmt den Addierer eines DDS und ersetzt die Sinustabelle durch eine (absolute) Sinusberechnung, also im Bereich 0 bis 360 Grad. Das hat keine bleibende Amplitudenänderungen. Der Cordic ersetzt nur die Tabelle.
Christoph K. schrieb: > Der Cordic ersetzt nur die Tabelle. So ist es und das erzeugt somit zunächst keinerlei Schwingung sondern nur einen einzelnen Wert. Ob das einen Sinus gibt, hängt von den Argumenten ab. Man kann auch mit einer Parabelgleichung eine Schwingung erzeugen, wenn man die Argumente entsprechend vorgibt. Beispiel: x = MOD7(x + y/2) y = 3x*x - 3x - 1
Der Cordic algorithmus ist die Bestimmung des Sinuswertes aus einem Winkelwert. Wenn man dein Winkelwert kontinuierlich hochzählt und den Sinus bestimmt hat man eine Schwingung das ist bereits eine Anwendung des Cordicalgorithmuses und wird auch in der Literatur NCO (numeric controlled oscilator) bezeichnet. Zurück zum Cordic. Die eingentliche Genialität bestäht darin mit einfachen Digitalen Gatern dies aufzubauen. Die Grundidea ist, von einem bekanntem Startpunkt nähert man sich dem zu ermittelnden Wert. Wie kann man sich entlang der Sinusfunktion langhangeln? Mit der 1.Ableitung und bei einem Sinus ist die 1.Ableitung der Kosinus. Deshalb wird der Sinus uns der Kosinus immer parallel ermittelt.
wie ermittelt man dann den Cosinus? Erst einen Sinus berechnen? Da beisst sich aber die Henne ins Ei, oder?
Nein, man kann beide parallel berechnen und die Zwischenergebnisse kreuzweise benutzen.
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.