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?
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_Arithmetik/Sinus_und_Cosinus_%28CORDIC%29
In der Regel kommt man mit einer LUT aber gut hin.
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
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)
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.
Wie kommst du darauf, daß CORDIC zu ungenau ist? Das Programm hier:
http://www.frank-buss.de/SignalGenerator/software/table/table.c
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.
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.
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
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...
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.
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:)
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.
:-)
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
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.
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.