www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Sinus mit AVR effizient berechnen


Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe einen AVR mit angeschlossenem 16Bit DAC. Ich suche nun nach 
einer effizienten Möglichkeit, einen Sinus zu berechnen um diesen dann 
ausgeben zu lassen. Ein Lockup-Table scheidet bei so vielen Werten wohl 
aus, aber welche für einen kleinen 8Bit AVR geeigneten Möglichkeiten 
gibt es noch?

Autor: Lukas K. (carrotindustries)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> Ich habe einen AVR mit angeschlossenem 16Bit DAC. Ich suche nun nach
> einer effizienten Möglichkeit, einen Sinus zu berechnen um diesen dann
> ausgeben zu lassen. Ein Lockup-Table scheidet bei so vielen Werten wohl
> aus, aber welche für einen kleinen 8Bit AVR geeigneten Möglichkeiten
> gibt es noch?

http://www.mikrocontroller.net/articles/AVR_Arithm...
In der Regel kommt man mit einer LUT aber gut hin.

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stellt sich die Frage nach der Frequenz, die du erreichen willst. Egal 
mit welchem Verfahren, bei echten 16bit wird die ziemlich klein sein.
-mit kleiner Frequenz zufrieden sein
-sich von den 16bit verabschieden
-passenden Prozessor wählen

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Frequenz ist egal, solange sie konstant bleibt. Es handelt sich um 
eine Art Referenzschwingung.
CORDIC ist mir leider zu ungenau, die 16Bit möchte ich schon ausnutzen, 
da der DAC auch ein ziemlich guter ist (eigentlich ein 18Bit Typ mit 
2Bit INL)

Autor: Lukas K. (carrotindustries)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> Es handelt sich um
> eine Art Referenzschwingung.

Muss diese unbedingt digital erzeugt werden?

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, denn er muss nicht nur Sinussignale sondern auch andere Muster 
erzeugen.

Autor: Lukas K. (carrotindustries)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nenn' mal den Frequenzbereich und die Abtastrate, der dir vorschwebt.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie ich bereits gesagt habe ist es eine Art Referenzsignalgenerator. 
Gibt keine genauen Anforderungen bezüglich Frequenz. Der DAC ist ein 
18Bit 1MSPS Teil, 16Bit Genauigkeit erreiche ich damit locker, also 
sollte auch die Ansteuerung mit 16Bit arbeiten.

Autor: Andreas K. (derandi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sinus von AVR berechnen lassen, alles in großen RAM schreiben und von da 
aus in den DAC schieben.

Autor: Frank Buss (foobar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie kommst du darauf, daß CORDIC zu ungenau ist? Das Programm hier:

http://www.frank-buss.de/SignalGenerator/software/...

ist auf 32 Bits genau. Damit habe ich die Implementierung getestet, die 
ich hier dann eingesetzt habe:

http://www.frank-buss.de/SignalGenerator

Bei nur 16 Bits geforderter Auflösung sollte man die Anzahl Schritte 
drastisch reduzieren können (waren bei mir 27 für 32 Bit). Falls dein 
Microcontroller allerdings einen Hardware-Multiplier integriert hat, 
dann gibt es bessere Algorithmen.

Autor: Frank Buss (foobar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was für ein AVR verwendest du denn? 1 MSPS wirst du mit den üblichen 
Microcontrollern nicht hinbekommen.

Autor: Rudi D. (rulixa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> Ich habe einen AVR mit angeschlossenem 16Bit DAC. Ich suche nun nach
> einer effizienten Möglichkeit, einen Sinus zu berechnen um diesen dann
> ausgeben zu lassen. Ein Lockup-Table scheidet bei so vielen Werten wohl
> aus, aber welche für einen kleinen 8Bit AVR geeigneten Möglichkeiten
> gibt es noch?

Welche Genauigkeit willst du?

Von 0..45° genügt es ja an sich. Die Cosx Reihe ist 1 -x²/2 +x⁴/4!
Kannst ja probieren ob du mit x²/2 auskommst.
quadrieren ist ja einfach, halbieren noch einfacher.
Fixkomma mit 16bit sollte auf jeden FAll reichen.

Autor: Marcus B. (raketenfred)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie schnell kann denn ein avr polynome ca 10. grades berechnen??

dann könnte man doch theoretisch alles über eine taylor nährerung+modulo 
sinvoll machen oder?

auch wenn ich glaube, dass die RAM-cache variante die flotteste sein 
wird, muss

Autor: Helmut (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nimm eine Sin-Tabelle (ca 100 Werte) und entwickle von dem Punke aus 
eine Taylorreihe.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> Der DAC ist ein 18Bit 1MSPS Teil, 16Bit Genauigkeit
Tja, wieder mal eine Anhängekupplung an einen Fiat 126 gebaut und damit 
den 4to Anhänger ziehen wollen...  :-o

> wie schnell kann denn ein avr polynome ca 10. grades berechnen??
Du wirst den DAC niemals auch nur annähernd mit einem AVR in Echtzeit 
ausreizen können, entweder mußt du Abstriche an der Auflösung oder an 
der Frequenz machen...

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neben dem CORDIC und Nachguck-Tabelle gibt's noch (lineare) 
Interpolation:

http://www.mikrocontroller.net/articles/AVR_Arithm...

Diese ist schneller als CORDIC, streut deutlich weniger und sin ist im 
Gegensatz zum CORDIC in [0, π/2] monoton.

Autor: Tishima (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Vieleicht waere ne Direct Digital Synthesis sinnvoll.


Wie z.B. hier angewandt
http://www.myplace.nu/avr/minidds/index.htm

gruß,
Bjoern

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tishima schrieb:

> Vieleicht waere ne Direct Digital Synthesis sinnvoll.

Um die machen zu können, muss man erstmal einen Sinus haben.

Autor: Helmut S. (helmuts)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habs.
Da du nur eine feste Frequenz erzeugen willst, speichere eine 
Sinus-Periode mit z. B. 128 Werten a 16bit im Flash. Die gibst du per 
Interrupt mit der 128fachen Frequenz aus. An den Ausgang des DAC kommt 
dann ein Tiefpass-Filter.

Du kannst auch jede andere Anzahl von Werten nehmen, z. B. 100.
Je mehr Werte du hast um so unkritischer ist das Filter. Einfache Filter 
sind automatisch auch temperaturstabiler.

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hello,
Du brauchst auch nur 1/4 der Periode in einer Tabelle speichern. Den 
Rest kannst du dir dann zusammenbauen. Zumindest mache ich es so bei der 
Ansteuerung meiner 3-Phasen -Brushless Motoren. Mit 2Kbyte Speicher 
kannste so 4096 Stützpunke für deinen Sinus basteln...

Well done:)

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> Wie ich bereits gesagt habe ist es eine Art Referenzsignalgenerator.
> Gibt keine genauen Anforderungen bezüglich Frequenz. Der DAC ist ein
> 18Bit 1MSPS Teil, 16Bit Genauigkeit erreiche ich damit locker, also
> sollte auch die Ansteuerung mit 16Bit arbeiten.

Ich denke du hast keine Vorstellung der benötigten uC Rechenzeit.
So als Beispiel von mir:

Frequenzgenerator mit einem tiny26 und r2r-Netzwerk an Port A.
Sinus als 256 Punkte LookUp-Table, F_CPU 8 MHz.
Programm in Assembler und optimiert auf Geschwindigkeit, die 
Hauptschleife benötigt 8 Takte. Gibt eine Phasenänderung pro us.
Wenn ich z.B. einen 100kHz Sinus ausgeben will, hab ich nur 10 Punkte, 
die ich pro Phase ausgeben kann -> Sinus wird eckig.

Daher fragen dich die ganzen Leute auch, was dir für Frequenzen 
vorschweben.
Bevor du da nix festlegst, macht das keinen Sinn weiterzudiskutieren.
:-)

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> Tishima schrieb:
>
>> Vieleicht waere ne Direct Digital Synthesis sinnvoll.
>
> Um die machen zu können, muss man erstmal einen Sinus haben.

Den legt man bei DDS üblicherweise mit im ROM ab.


Ich verwende zur Berechnung von Orthodromen auf einem 8051 dies:

sin (x) = x+(x^3/-6)+(x^5/120)+(x^7/-5040)+(x^9/362880)+(x^11/-39916800)

... in Assembler ...

Edit: Er schafft keine 100 Sinusberechnungen in der Sekunde ...


Gruß

Jobst

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab nur geschrieben, dass der DAC 1MSPS kann. Nicht dass ich glaube, 
das auch annähernd ausnutzen zu können. Angesteuert wird übrigens per 
SPI, also gibts da auch schon mal eine Beschränkung, aber egal.
Mich hat nur der Algorithmus interessiert. Werds mal mit CORDIC 
probieren, aber ev. doch gleich mit einem STM32.

Autor: Helmut S. (helmuts)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du nur eine feste Frequenz brauchst, dann ist es unsinning 
irgendwas zu rechnen. Einfach die festen Stützpunkte nacheinander aus 
einer Tabelle auslesen und auf den DAC geben.

Ach und noch was. Wenn du keine exakte Reaktionszeit zwischen 
Timer-interrupt und DAC-Ausgabe hinbekommst, dann kannst du die 16bit 
gleich vergessen. Neben der Amplitudengenauigkeit ist nämlich die 
Phasengenauigkeit am DAC-Ausgang auch wichtig. Das wird beim STM32 wohl 
ganz übel aussehen mit minimaler und maximaler Interrupt-Reaktionszeit.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.