Forum: Mikrocontroller und Digitale Elektronik AVR Integer-Arithmetik


von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Hallo allerseits,

folgende Berechnung:
1
value = freq * 2^32 / 50MHz

würde ich gerne in uint32 durchführen. freq liegt im  Bereich 0..25MHz

2^32 / 50E6 ist zwar konstant, aber gebrochen (85.899...)

irgendwie stehe ich gerade wieder mal auf dem Schlauch, wie ich das so 
umschreibe, das alles möglichst gut in uint32 Platz findet....


guten Rutsch!

von Uwe S. (de0508)


Lesenswert?

Hallo,

Stichwort: das erste Argument auf den Zieldatentyp casten.

ZZ. Du möchtest das FTW für einen DDS berechnen..

: Bearbeitet durch User
von Dispol (Gast)


Lesenswert?

1
value = freq * 86 - ( (freq * 103) >> 10);

wäre mit 85,899414063 anstatt 85,89934592 schon recht nahe dran, 0.8ppm 
Fehler.


1
value = freq * 86 - ( (freq * 103) >> 10) - ( (freq * 143) >> 21);

Hier sind es 85,899345875 und somit nur noch 0,005ppm Fehler.

von Oldie (Gast)


Lesenswert?

Mit dem Faktor 2^32 katapultierst du dich gerade so aus
uint32 heraus.

Erzähl doch erst mal, was rauskommen soll.

von Dispol (Gast)


Lesenswert?

Nachtrag:
0.8ppm Fehler sind also 20 Digits Fehler
0.005ppm Fehler sind 0.1 Digits Fehler

Beides bei 25MHz.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Uwe S. schrieb:
> Stichwort: das erste Argument auf den Zieldatentyp casten.

Da kann ich grad nicht folgen...

> ZZ. Du möchtest das FTW für einen DDS berechnen..
ich weiss zwar nicht was das FTW ist, aber DDS ist heiss: Es geht um 
einen AD9835

Dispol schrieb:
> value = freq * 86 - ( (freq * 103) >> 10) - ( (freq * 143) >> 21);

Sieht sehr vielversprechend aus!

Nur - wie kommt man darauf? Wie leitet man das her? Ich brauch das zwar 
konkret nicht, aber was ist wenn die 50 MHz mal nicht 50 MHz sind? (wäre 
aber auf jeden Fall eine Konstante die zur Compile-Time bekannt ist)

: Bearbeitet durch User
von Dispol (Gast)


Lesenswert?

>Nur - wie kommt man darauf?
85,89934592 sollen's sein.
Dann nimmst Du 86 und ziehst wieder (86-85,89934592) = 0,10065408 ab.

0,10065408 nehm ich jetzt so viele Mal x2, bis "fast" wieder ein Integer 
raus kommt.
103,06977792 (also 0,10065408 * 1024) ist nahe an 103.

Das ist die erste Zeile.
Leider ist dass auch noch etwas zu groß, deshalb macht ich das dann 
nochmals mit dem Rest vom Rest.

Immer natürlich aufpassen, dass die Zahl nie größer als 170 
(32Bit/25MHz) wird, damit es keinen Überlauf gibt.

von Uwe S. (de0508)


Lesenswert?

Hallo Michael,
1
FTW = freq * 2^32 /50^6 = freq * 86,8993..
Das wird zu nächsten größeren ganzen Zahl aufgerundet und der Fehler 
wieder abgezogen.
1
86 -0,1007..

Der Fehlerwert -0,1007 lässt sich durch einen Faktor 1024 auf eine ganze 
Zahl aus /Z skalieren.
1
K1 = -0,1007 * 1024 = -103
Den Skalierungsfaktor 1024 = 2^10 muss man später wieder herausrechnen.

Also ist der aktuelle Näherungswert:
1
86 - 103/1024

Der nächste Korrekturterm wäre dann
f2 = 2^21
K2 - (86 - 103/1024) * f2
K2 = (2^32 /50^6) - (86 - 103/1024) * f2
K2 = -142,9052 = -143

Somit gilt
1
FTW = freq * (86 -(103 >> 10) -(143 >> 21))

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Ich danke euch! (unglaublich zu welchen Zeitpunkten man hier Hilfe 
bekommt!)

ich glaube ich habe verstanden....

Aber eine Folge-Frage: Angenommen, ich wollte den "input-parameter" 
verhundertfachen, um "centiHertz" (Hundertstel Hz) abbilden zu können.

also maximal 25E8, was sich gerade noch in 32bit abbilden lässt

Der Faktor 85.irgendwas verkleinert sich damit auf 0.85

allerdings hab ich bei der Multiplikation keinen "Headroom" mehr, oder

ginbge das auch?

von Dispol (Gast)


Lesenswert?

Ginge auch.
Angenommen, es wäre 0.75, dann wäre es ja:

1
value = freq - frq >> 2;


jetzt ist's halt etwas (sehr langes) in der Art:
1
value = freq +- frq >> 1 +- frq >> 2 +- frq >> 3 +- frq >> 4 +- frq >> 5 ...;

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Danke, funktioniert super!

von Uwe S. (de0508)


Lesenswert?

Guten Morgen und ein schönes neues Jahr,

für alle Interessierten am DDS AD9835 sei noch auf das PDF verwiesen:

/AN-621: Programming the AD9832/AD9835/
http://www.analog.com/static/imported-files/application_notes/AN-621.pdf

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Uwe S. schrieb:
> für alle Interessierten am DDS AD9835 sei noch auf das PDF verwiesen:
>
> /AN-621: Programming the AD9832/AD9835/
> http://www.analog.com/static/imported-files/application_notes/AN-621.pdf

Und da gibts noch die AN-1108, die nicht minder spannend ist:
http://www.analog.com/static/imported-files/application_notes/AN-1108.pdf

: Bearbeitet durch User
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
Noch kein Account? Hier anmelden.