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)
Tom schrieb: > Es handelt sich um > eine Art Referenzschwingung. Muss diese unbedingt digital erzeugt werden?
Ja, denn er muss nicht nur Sinussignale sondern auch andere Muster erzeugen.
Nenn' mal den Frequenzbereich und die Abtastrate, der dir vorschwebt.
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.
Was für ein AVR verwendest du denn? 1 MSPS wirst du mit den üblichen Microcontrollern nicht hinbekommen.
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
Nimm eine Sin-Tabelle (ca 100 Werte) und entwickle von dem Punke aus eine Taylorreihe.
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...
Neben dem CORDIC und Nachguck-Tabelle gibt's noch (lineare) Interpolation: http://www.mikrocontroller.net/articles/AVR_Arithmetik/Sinus_und_Cosinus_(Lineare_Interpolation%29 Diese ist schneller als CORDIC, streut deutlich weniger und sin ist im Gegensatz zum CORDIC in [0, π/2] monoton.
Hallo! Vieleicht waere ne Direct Digital Synthesis sinnvoll. Wie z.B. hier angewandt http://www.myplace.nu/avr/minidds/index.htm gruß, Bjoern
Tishima schrieb: > Vieleicht waere ne Direct Digital Synthesis sinnvoll. Um die machen zu können, muss man erstmal einen Sinus haben.
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.
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.