Sinus mit AVR effizient berechnen

Gast #2061279
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?
#2061283
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_Arithmetik/Sinus_und_Cosinus_%28CORDIC%29
In der Regel kommt man mit einer LUT aber gut hin.
Gast #2061328
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)
Gast #2061516
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.
#2061522
Lesenswert?

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.
#2061538
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.
Moderator (Firma: Titel) Persönliche Seite #2061575
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...
#2061640
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.
Gast #2061658
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:)
Gast #2061661
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.
:-)
#2061727
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
Gast #2061746
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.
#2061755
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren