HI! Für eine DDS ansteuerung benötige ich ein 32 bit Datenwort das dem DDS-Chip die gewünschte Frequenz angibt. pro Hz ergibt sich also die Fromel: 2^32/180MHz = 23,86092942 Wenn ich also eine Frequenz von 121 Hz haben möchte: 121 * 23,86092942 = 2887,17245982 Dieses Ergebnis soll der AVR auf- oder abrunden. somit habe ich 2887 dezimal sind binär 101101000111 Dieses Ergebnis kann bis zu 32 bit erreichen. Nun meine Fragen: Wie sag ich dem AVR das er die gewünschte Freq. mit 23,86... multiplizieren soll, also wie geht das mit den Nachkommastellen ? Wie kann ich es verwirklichen mit 32 bit also 4 Registern zu rechnen? MfG Manuel
Das Zauberwort heißt fixed-point-arithmetik. Du skalierst mit z.B. 1024, 4096 oder einer anderen Zweierpotenz und kürzt nach der Multiplikation. 23. *65536 = 1563749,8706147556 1563750 * 121 = 189213750 189213750 / 65536 = 2887,172698974609375 Runden geht einfach: Du addierst einfach das bit15 des Zwischenergebnisses zum End-Ergebnis. Wenn das Ergebnis 32 bit lang werden kann, muss das Zwischenergebnis mindestens 48 bit lang sein, d.h. Du musst "mit der Hand" multiplizieren. Das ist aber gar nicht soo schwer. Alternativ kannst Du die Formel umstellen: dds = 2^32 * freq / xtal; Die Multiplikation ist einfach: freq um 32 bit nach links, oder anders gesagt: 32 Nullen anhängen. Dann hast Du aber das Problem, dass vielstellig dividiert werden muss. Da ist das Multiplizieren deutlich einfacher. Wenn Du willst, suche ich Dir eine 32x32=64-bit-Multiplikations-Routine.
Erste Grundlagen für die Rechnerei und Zahlenumwandlung gibt es auch hier: http://www.avr-asm-tutorial.net/avr_de/rechnen/index.html Gruss Jadeclaw.
Hallo. Eine Frage von Manuel bleibt da noch offen: Wie rechnet man mit vier Registern. Gar nicht! Man rechnet alle vier Register einzeln und behandelt die Überläufe in das nächsthöhere Byte, z.B. beim Addieren, durch Hinzuaddieren des Carrybits aus der niedrigeren Addition (ADC statt ADD). Beim Malnehmen (Linksschieben) rotiert das höchste Bit ins Carry und von da aus in das nächsthöhere Register (ROL statt LSL). mfg gerd
Ok, erstmal danke für eure Antworten! Ich werde wohl ne Zeit brauchen um das zu verdauen und ein bischen mit dem Studio rumprobieren müssen. Aber das Grundprinzip ist mir schonmal klar geworden. Sollte es dennoch Probleme geben werde ich hier in nächster Zeit wohl noch die ein oder andere Frage stellen. @ Profi: Ich werde es zwar selber versuchen, aber solch eine Routine wäre vielleicht trozdem nicht schlecht. MfG Manuel
In der Codesammlung sind letztens Routinen für Rechenoperationen in Asm aufgetaucht...
man kann auch 10er potenzen nehmen bei der fixed point arithmetik. dank MUL befehl braucht das auch nur 2takte (meine ich).
Die folgenden Beispiele sind so getippt, dass man sie bis einschließlich =-Zeichen markieren, kopieren und in den Win-Rechner im wissenschaftlichen hex-Modus (Alt+a w F5) kopieren kann, der rechnet dann das Ergebnis aus. Man muss praktisch jedes Byte mit jedem des anderen Multiplikanden multiplizieren und das Ergebnis um eine bestimmte Bytezahl nach links versetzt addieren. Beachte: auch die Bitschiebezahl (8,10,18,20) ist hex -> 8,16,24,32 dez. 16 x 8 bit 1234 * 56 = 061D78 -------- 34 * 56 = 1178 12 * 56 = 060C 16 x 16 bit 1234 * 5678 = 06260060 ---------- 34 * 78 = 1860 12 * 78 = 870 34 * 56 = 1178 12 * 56 = 060C 32 x 32 bit 01234567 * 89abcdef = 9CA39DC94E4629 (hat nur 14 Stellen wg. 0123..) 10FEDCB29 E93E937B C28F5BCD 9BE0241F ---------------- 9CA39DC94E4629 6029+ 527B00+ 44CD0000+ 371F000000= 37641FDB29 auf 8x8 Multiplikationen zurückgeführt 67*ef+ 67*cd<8+ 67*ab<10+ 67*89<18+ 45*ef<8+ 45*cd<10+ 45*ab<18+ 45*89<20+ 23*ef<10+ 23*cd<18+ 23*ab<20+ 23*89<28+ 01*ef<18+ 01*cd<20+ 01*ab<28+ 01*89<30= 9CA39DC94E4629 37641FDB29+ 251B4E816B00+ 12D27D27AD0000+ 89abcdef000000= ================== 9CA39DC94E4629 fedcba98*89abcdef= fedcba98*fedcba98=FDBAC096DD413A40 (hat 16 Stellen) 98* 98 + 98* ba < 8+ 98* dc <10+ 98*fe <18+ ba * 98< 8+ ba * ba <10+ ba * dc <18+ ba *fe <20+ dc * 98<10+ dc * ba <18+ dc * dc <20+ dc *fe <28+ fe * 98<18+ fe * ba <20+ fe * dc <28+ fe *fe <30= ================== FDBAC096DD413A40 98* 98+ 98* ba00+ 98* dc0000+ 98*fe000000+ ba00* 98+ ba00* ba00+ ba00* dc0000+ ba00*fe000000+ dc0000* 98+ dc0000* ba00+ dc0000* dc0000+ dc0000*fe000000+ fe000000* 98+ fe000000* ba00+ fe000000* dc0000+ fe000000*fe000000= ================== FDBAC096DD413A40 fedcba98*89abcdef=890F2A50AD05EBE8 98* ef + 98* cd < 8+ 98* ab <10+ 98*89 <18+ ba * ef< 8+ ba * cd <10+ ba * ab <18+ ba *89 <20+ dc * ef<10+ dc * cd <18+ dc * ab <20+ dc *89 <28+ fe * ef<18+ fe * cd <20+ fe * ab <28+ fe *89 <30= ================== 890F2A50AD05EBE8 ffffffff*ffffffff=FFFFFFFE00000001 FEFFFFFF01 FEFFFFFF01 FEFFFFFF01 FEFFFFFF01 ------------------ FFFFFFFE00000001 ffffffffffffffff-FFFFFFFE00000001=1FFFFFFFE=2*ffffffff (beim Hardware-MAC sind 2 Summanden möglich) ffffffff00000000-FFFFFFFE00000001=FFFFFFFF
@Manuel Hallo, Wenn du möchtest 120Hz mit ein DDS chip, du kanst viellecht günstiger mit einer 1 oder 4 MHz Crystal arbeiten. DDS mit 180 MHz sind teuerer als eine mit 25 MHz max Takt. (Hoffe es hilft). Ale
Hallo. Ich finde die Methode von "Profi" nicht so arg attraktiv. Man verliert so leicht den Überblick. Bitweises Addieren und Linksschieben ist nach meinem Geschmack systematischer und vielleicht sogar schneller, insbesondere bei 24*24 Bit. mfg gerd
Hallo, habe das auf ganz einfache weise gelöst, denn ich habe auch mit dem AD9851 einen DDS Synthi aufgebaut: Fout(Hertz) * FF FF FF FF Delta Phase = ------------------------- 0A BA 95 00 im klartext: es sollen 20 MHz ausgegeben werden an die Ausgangsfrequenz einfach noch 4 Register mit 00 00 00 00 sieht dann so aus 01 31 2D 00 00 00 00 00 (20.000.000 Hz) (+ erweiterung) diese 8 Byte Zahl wird jetzt dividiert durch 180.000.000 Mhz also 0A BA 95 00 das Ergebnis lautet 1C 71 C7 1C und kann dierekt in den DDS Chip geladen werden. Moment... ich suche grade mal die routine raus... Gruß, Tubie
Voila und hier die Routine: ;----------------------------------------------------------------------- ; divisionsroutine ; temp 0(MSB)-7(LSB) / temp 20(MSB)-23(LSB) = temp 10(MSB)-17(LSB) ; hilfsreg temp30-temp33 division: push temp30 push temp31 push temp32 push temp33 clr temp10 ; Ergebnis löschen clr temp11 clr temp12 clr temp13 clr temp14 clr temp15 clr temp16 clr temp17 ldi temp,0 cp temp0,temp cpc temp1,temp cpc temp2,temp cpc temp3,temp cpc temp4,temp cpc temp5,temp cpc temp6,temp cpc temp7,temp breq divi_fertig inc temp17 ; Hilfsreg löschen clr temp30 clr temp31 clr temp32 clr temp33 ; Divisionsschleife anfang divi_a: clc ; lösche carry rol temp7 ; nächsthöheres bit in hilfsreg rollen rol temp6 rol temp5 rol temp4 rol temp3 rol temp2 rol temp1 rol temp0 rol temp33 ; Entspricht multiplikation mit 2 rol temp32 rol temp31 rol temp30 brcs divi_b ; Eine 1 ist herrausgerollt, ziehe ab cp temp33,temp23 ; Divisionsergebnis 1 oder 0 ? cpc temp32,temp22 cpc temp31,temp21 cpc temp30,temp20 brcs divi_c ; Überspringe subtraktion, wenn kleiner divi_b: sub temp33,temp23 sbc temp32,temp22 ; subtrahiere divisor sbc temp31,temp21 sbc temp30,temp20 sec ; carry bit setzen, ergebnis ist eine 1 rjmp divi_d ; zum schieben des ergebnisses divi_c: clc ; carry löschen, ergebnis ist eine 0 divi_d: rol temp17 rol temp16 rol temp15 rol temp14 ; carry bit ins ergebnis rollen rol temp13 rol temp12 rol temp11 rol temp10 brcc divi_a ; solange wiederholen, bis eine 1 rausrollt ; ergebnis ist jetzt berechnet und in temp14(MSB)-17(LSB) gespeichert divi_fertig: pop temp33 pop temp32 pop temp31 pop temp30 ret
Wenn man einmal den Wert ausgerechnet hat, kann man sogar problemlos eine Start / Endfrequenz ausrechnen, diese in einzelschritte zerlegen (je nach verwendetem AVR und geschwindigkeit) und dann passend dazu eine Analoge Rampe auf einem externen D/A wandler ausgeben. Der DDS Chip läuft dann von start bis endfrequenz und der Atmel gibt die Rampe aus. Ich habe das ganze programmiert von 0.5 - 25 Hz rampenfrequenz. Ist ne recht feine Sache. Allerdings fehlt mir momentan die Zeit hier weiterzumachen. Gruß, Tubie
@Tubie: ich meine, eine Multiplikation mit dem Kehrwert ist allemal einfacher und schneller als eine Division. Übrigens, Deine Formel hat FFFFFFFF als Multiplikand: 20000000 * 4294967295 = 85899345900000000 1312D00 * FFFFFFFF = 1312CFFFECED300 Das Anhängen von von 4 Nullbytes ist eine Multiplikation mit 4294967296! 20000000 * 4294967296 = 85899345920000000 1312D00 * 100000000 = 1312D0000000000 Du rechnest mit Division: 0131 2D00 0000 0000 / 0ABA 9500 = 1C71 C71C Ich rechne mit Multiplikation: 0131 2D00 * 17 DC65 DEE0 = 1C71 C71C 710D 6000 (ist eigentlich eine 25 x 37 --> 62-Bit-Multiplikation, das Ergebis ist jedoch identisch) So, jetzt kommt die Hohe Kunst der Skalierung zum Zuge, damit wir die Wertebereiche voll ausschöpfen und maximale Genauigkeit erreichen: Als erstes müssen wir die gewünschte maximale Ausgangsfrequenz festlegen, z.B. 33,5 MHz (2^25). Es bleiben noch 32-25=7 Bits übrig, die wir als "Nachkommabits" verwenden können. Wir skalieren (=multiplizieren) mit 2^7=128, d.h. wir können die Frequenz auf 1/128 Hz genau einstellen. Nun brauchen wir den Wert 2^64/180000000=102481911520,60862008889 = 0x17DC65DEE0. Der hat 37 Bits, also skalieren wir durch 2^(37-32=5)=32, bleibt 0xBEE32EF7. 20000000*128 * 3202559735 = 8198552921600000000 9896 8000 * BEE3 2EF7 = 71C7 1C71 C435 8000 71C7 1C71 C435 8000 / 4 = 1C71 C71C 710D 6000 ^ ^ DDS-Wert Einfacher wird es, wenn beide Male mit 2^5=32 skaliert wird, weil dann das Ergebnis nicht mehr geschoben werden muss: 20000000*32 * 3202559735 = 2049638230400000000 2625 A000 * BEE3 2EF7 = 1C71 C71C 710D 6000 ^ ^ DDS-Wert Der Skalierungsfaktor muss nicht unbedingt eine Zweierpotenz sein. Es bietet sich z.B. an, mit 10 zu skalieren, dann erleichtert sich die Dezimalumrechnung. Wenn man beide Zahlen mit dem selben Faktor skaliert, kann dieser jeden x-beliebigen krummen Wert haben. @Gerd: Übersichtlicher? Vielleicht habe ich es unübersichtlich hingeschrieben, aber wenn man sich ein wenig hineinarbeitet, wird das Prinzip schnell klar. Und ohne jetzt die Clock-Cycles gezählt zu haben, das Schiebeverfahren dürfte viel langsamer sein, unabhängig ob mit 24x24 oder 32x32. Was braucht mein Verfahren: 4x 4= 16 Multiplikationen = 32 Cycles 8x15=120 Additionen = 120 Cycles, welche man durch geschicktes Kombinieren der Produkte auf 36 reduzieren kann. Summe: 68 Cycles zzgl. Ladezeiten. Das dürfte kaum unterboten werden können. Wohlgemerkt bei voller Genauigkeit. Wird das Ergebnis nach der Mult wieder auf 32 Bit gekürzt, kann man getrost nochmal 10-20 Cycles einsparen. Im Anhang eine 32x32 Multiplikation in C, für ASM-Konvertierung "vorgekaut". Dürfte in ASM ca. 70 - 100 Zeilen schleifenlosen Code ergeben. Habe leider keinen ASM auf diesem Rechner installiert.
Hallo Profi, alle Achtung! Wie sagt man so schön: Wiele Wege führen nach Rom :-) Habe gerade mal die Divisions Routine durchlaufen lassen bei Fout=20.000.000 Hz und ich komme auf stolze 2097 Zyklen ist also nur unbedeutend langsamer wie deine 68 Zyklen. Damit könnte ich dann endlich mal FM in Angriff nehmen. Dreieck, Rechteck, Sägezahn, Sinus - Sabber! Habe es beim Sweepen bisher immer so gemacht Start und Endfrequenz berechnen und dann überprüfen, was der µC ausgeben kann und dann mir eine Schrittweite ausgerechnet, die ich auf den Basiswert dazuaddierte. Geht auch sehr schnell, da ja eigentlich nur 2 berechnungen gemacht werden. Vorteilhaft wäre dies z.B. beim durchdrehen mittels Drehgeber. Hier merkt man ganz deutlich die 2000 Zyklen. Ganz tolle Leistung! Gruß, Tubie P.S. Ich mache mir nur Gedanken, das solches Gedankengut in den Tiefen des Forums verschwindet denn unter dem Thread "Rechnen mit AVR" kann man viel meinen.
> P.S. Ich mache mir nur Gedanken, das solches Gedankengut in den > Tiefen des Forums verschwindet [...] Vorschlag: Evtl. didaktisch noch etwas nachbearbeiten und in die Codesammlung einstellen. Gruss Jadeclaw.
Und, was ist los? Noch kein ASM file zu sehen? Na, dann habe ich eines gemacht. Mein erstes AVR-Programm! Das ganze Programm incl. Loads hat 71+8=79 Words und braucht 86+8=94 Takte. Fast wie versprochen. Schade, dass der MUL-Befehl das Carry beeinflusst, sonst wäre es nochmal um 12 Words und Takte kürzer geworden. Werde noch einen Wiki-Beitrag dazu schreiben, damit das besagte Wissen gut auffindbar ist. Erweiterung auf jede beliebige Bitzahl ist problemlos möglich, auch ungleiche Breiten der Multiplikanden (z.B. 80x48-->128).
Da war doch wieder mal einer schneller. :-) Wenn ich das Projekt wieder aufgreife, werde ich die Routine auf jeden Fall verwenden. So wird das ganze noch leistungsfähiger. Der große Vorteil, ich habe alles mit 2 AVR's aufgebaut. Der erste steuert das Display, liest einen Drehgeber, die Potis und die Kippschalter ein. Dieser gibt die Werte via RS-232(5V) weiter an den zweiten und dieser generiert mir das DDS wort und generiert dazu passend die Rampe fürs Sweepen. Bin aber momentan noch am bau meines Röhrenverstärkers, der seit 5 Jahren darauf wartet, fertiggestellt zu werden. Falls es jemanden interessiert: http://people.freenet.de/tubefan/ Gruß, Tubie
@Tubie "Vorteilhaft wäre dies z.B. beim durchdrehen mittels Drehgeber. Hier merkt man ganz deutlich die 2000 Zyklen." Wie bitte ? 2000 Zyklen sind 0,25ms bei 8MHz, das kann kein Mensch merken. Alles unter 10ms kann nicht bemerkt werden. Peter
Hallo Peter, rechnerisch mag das eine recht kurze zeit sein, allerdings wenn ich eine Rampe mittels D/A wandler erzeuge und die auf den "External Sweep" Eingang meines Oskars gebe und den DDS von sagen wir 10.6 - 10.8 MHz syncron zur Rampe durchlaufen lasse, dann merkt man schon ein ruckelndes und verwackeltes Bild während des Drehens am Drehgeber also immer dann, wenn eine Berechnung durchgeführt wird. Dies könnte wesentlich besser sein mit der genialen Routine von Profi. Gruß, Tubie
@Tubie "dann merkt man schon ein ruckelndes und verwackeltes Bild während des Drehens am Drehgeber also immer dann, wenn eine Berechnung durchgeführt wird." Diese Störungen haben dann aber eine andere Ursache. Ein biologisches Nervensystem ist definitiv nicht in der Lage, etwas 0,25ms genau zu erkennen oder zu bewegen. Du müßtest also schon den Drehgeber über einen Synchronmotor antreiben und damit auch den Oszi synchronisieren, damit die 0,25ms auffallen. Peter
Bob Pease von National Semiconductor ( www.national.com/RAP ) hat mal vorgerechnet, welche Reaktionszeiten ein Baseballspieler haben muß, ich meine er kam deutlich unter 1 msec, ich sollte mal den Artikel suchen. Er hat auch mal den Dynamikbereich von Auge und Ohr bestimmt, beide zu ca 140dB
Falsch, das "rap" muß klein geschrieben werden, die haben scheints keinen Widows-Rechner, also: http://www.national.com/rap die 140 dB hab ich gefunden: http://www.elecdesign.com/Articles/ArticleID/6059/6059.html nein die Baseball-Geschichte finde ich nicht, aber die schöne Story, wo er (vermutlich mitten in der Nacht) die Resonanzfrequenz seiner Matraze durch "gewobbeltes Summen " bestimmt...: http://www.elecdesign.com/Articles/ArticleID/9328/9328.html
@peter dannegger Ich gebe mich geschlagen. Kann ja wirklich auch sein, das in der Software noch etwas verkehrt läuft und ich den Miesepeter in der längsten Routine gesucht habe. Gruß, Tubie
kann man denn mit der eingebauten mul funktion nichts machen? Fast jeder neue Atmel AVR hat den mul befehl. der dauert jedenfalls nicht so lange wie so eine eigene mul routine
@Christoph: http://www.electronicdesign.com/Articles/ArticleID/6061/6061.html meinst Du den? Ich glaube, es gibt noch einen anderen. mit electronicdesign statt elecdesign geht's ohne Cookies und Skripte. @Simon: der AVR-MUL ist 8x8-->16 bit, hier geht es um 32x32-->64 In meiner Routine verwende ich keine Shifts, sondern 16 MULs. Schau sie Dir mal an.
Genau das wars: And he has learned to release the ball with a precision of as small as 100 µsjust one tenth of a millisecond.* *Computations: If a ball at the end of your arm, at a radius of 3 ft., is moving at 90 mph or 132 ft./s, it will change its ANGLE by 0.0044 radians, or 0.252°, every 100 µs. And an angle of 0.0044 radians corresponds with an uncertainty of 6.4 in. (±3.2 in.), after the ballor rockhas gone 60 ft.
Was mich auch verblüfft hat, ist die Tatsache, dass das Auge problemlos erkennt, wenn eine LED 1µs lang leuchtet (falls die Umgebung relativ dunkel ist). Hab ich selbst probiert. Kann mich sogar an eine Diskussion (war die nicht hier im Forum?) erinnern, dass das Auge sogar einzelne Photonen sehen kann.
Hi! Der Winter geht wieder los, und ich wieder in sachen elektronik aktiv. Ein Grund mehr, mein schon etwas älteres Projekt endlich fertigzustellen. Es fehlt nichtmehr viel, die Peripherie mit LCD, Drehgeber, usw. funktioniert einwandfrei, und auch die serielle übertragung zum dem AVR der für die DDS ansteuerung zuständig ist klappt! Zum berechnen des Datenwortes benutze ich die routine von Profi (Danke!!!) die ich zwar immernochnicht komplett verstehe, aber ich gehe mal fest davon aus das sie funktioniert! Nun muss ich das 8 Byte ergebnis e0 - e7 ja noch durch 65536 teilen und da stehe ich grade noch ein bischen auf dem Schlauch. Ich subtrahiere also 65536 und zähle gleichzeitig 4 Register hoch, also immer nur das LSB und die anderen falls ein carry auftaucht. Aber muss ich mit dem Subrahieren bei e0 oder bei e7 anfangen? Manuel
Welches ist das LSB? Dort fängst du an. Das ist nicht anders als woe wenn du mit Papier und Bleistift subtrahierst. Wenn du durch 65536 dividieren willst, brauchst du gar nicht rechnen. 65536 ist eine 2-er Potenz (2^16). Lass die beiden untersten Bytes weg und schieb alle anderen um 2 Bytes nach rechts. Das ist so, als ob du auf dem Papier eine Zahl durch 100 teilst, indem du wie wild zu rechnen anfängst. 1234 / 100 rechnet dir jeder im Kopf aus, indem er die letzten beiden Stellen wegfallen lässt und alles andere um 2 Stellen nach rechts verschiebt: 1234 / 100 ergibt 12
Oh man, ich habe glaube ich einfach ein Problem mit dem binärsystem... Ich wusste zwar, das es ne 2er potenz ist und habe auch lang überlegt, ob man da nicht einfach was mit rol oder ror machen kann, aber einfach weglassen wäre zu einfach gewesen ums in betracht zu ziehen ;) Ich bin dir sehr dankbar! Gruß Manuel
Hallo allerseits, ich möchte diesen Thread wieder aufleben lassen, nachdem ich die Tage verschiedene Verfahren für die FTW Berechnung eines AD9851 real mit Tickmessung auf einem atMega32 und avr gcc durchgespielt habe: Basierend auf der 32-Bit Skalierung von 2^64 DDS-TAKT 2^5 und anschließendem skalieren der Ziel Frequenz (freq) auf freq32 = (freq << 5); - Beitrag "Re: Rechnen mit AVR" - Beitrag "Re: Rechnen mit AVR" Konnte ich mit der "C" Variante [1] des Algorithmus das FTW in 611 Tick und mit der angepassten ASM-Datei des Algorithmus das FTW in nur 223 Tick berechnen ! Hier noch die Berechnung des FTW:
1 | #ifndef U64_UNION_B
|
2 | typedef union { |
3 | uint8_t b[8]; |
4 | uint16_t w[4]; |
5 | uint32_t q[2]; |
6 | uint64_t o; |
7 | } u64_union_t; |
8 | |
9 | #define U64_UNION_B(var_,id_) ((*(u64_union_t*)&(var_)).b[id_])
|
10 | #define U64_UNION_W(var_,id_) ((*(u64_union_t*)&(var_)).w[id_])
|
11 | #define U64_UNION_Q(var_,id_) ((*(u64_union_t*)&(var_)).q[id_])
|
12 | #define U64_UNION_O(var_,id_) ((*(u64_union_t*)&(var_)).o)
|
13 | #endif
|
14 | |
15 | uint32_t ftw_mul32_32( uint32_t freq32 ) |
16 | {
|
17 | const uint8_t scale = 5; |
18 | const uint32_t revers_dds_takt = 0xBEE32EF7; // 2^64 / F_MHZ(180) / 2^5 |
19 | |
20 | volatile uint64_t ftw; |
21 | |
22 | ftw = mul32_32 ( revers_dds_takt, (freq32 << scale) ); |
23 | |
24 | return U64_UNION_Q(ftw, 1); // liefert die oberen 32 Bit zurück |
25 | }
|
[1] C-Version: http://www.qrpforum.de/index.php?page=Attachment&attachmentID=9921
Freut mich, dass nach 5,5 Jahren mein Code immer noch Beachtung findet. Mich wundert, dass selbst die von Atmel vorgeschlagenen Routinen länger waren. Vor allem wurmt mich, dass das Carry-Bit durch den mul verändert wird, was so gut wie nie ausgewertet wird. Wenn sie schon darauf bestehen, wäre es besser, es gäbe 2 mul-Versionen, eine wie gehabt und eine, die das Carry-Flag unverändert lässt. Zum C-Code: man müsste sich das ASM-Listing mal anschauen, in wieweit optimiert wird, da z.B. statt a[1] = (u16 & 0xff00)>>8; a[1] = u16 >> 8; ausreicht. Sehe ich das richtig, dass die Hopf-Routinen keine muls verwenden, sondern nur schieben und addieren? Vielleicht sollten wir ihn mal hierher lotsen... So weit ich sehe, sind die momentanen Verbesserungen für 64-Bit gcc schon recht gut: http://gcc.gnu.org/viewcvs/trunk/libgcc/config/avr/lib1funcs.S
Je nach verwendetem Browser werden Leerzeichen / Proportionalschrift nicht richtig dargestellt. Liebe Moderatoren, bitte die Berechnung in Code-Tags stellen. Beitrag "Re: Rechnen mit AVR"
1 | 20000000 * 128 * 3202559735 = 8198552921600000000 (dez) |
2 | 98968000 * BEE32EF7 = 71C71C71C4358000 (hex) |
3 | 71C71C71C4358000 / 4 = 1C71C71C710D6000 |
4 | ======== |
5 | FTW-Wert |
und
1 | 20000000*32 * 3202559735 = 2049638230400000000 |
2 | 2625A000 * BEE32EF7 = 1C71C71C710D6000 |
3 | ^^^^^^^^ |
4 | FTW-Wert |
calc.exe ist seit der neuen Windoof-versionen auch nicht mehr so praktsch wie früher.
Vorn N. schrieb: > calc.exe ist seit der neuen Windoof-versionen auch nicht mehr so > praktsch wie früher. Es spricht nichts dagegen, calc.exe von WindowsXP auch noch unter Windows10 zu verwenden. Mit Linux-Hilfe kann man die neumodische und untaugliche Gülle das sogar systemweit dadurch ersetzen. Ja, sieht optisch nicht so ganz passend aus, ist aber nach wie vor deutlich praxistauglicher als der mit Vista eingeführte Unsinn, wo man zwischen "Wissenschaftlich" und "Programmierer" unter Verlust von Ergebnis und Speicherinhalt umschalten muss. Welche komplett unfähigen Programmierer haben sich das bloß ausgedacht... Allein schon die Attitüde... Als wenn es zwischen Wissenschaflichkeit und ernsthaftem Programmieren tatsächlich einen Sprung gäbe, der die Mathematik komplett verändert... Blinde Wichser! Aber erklärt wohl irgendwie die Qualität der Software, die MS in den letzten Jahren so liefert. Wenn's bei solchen Trivialitäten wie einem brauchbaren "Taschenrechner" schon derart hapert, will man eigentlich garnicht mehr wissen, warum diese Scheiße überhaupt noch irgendwie manchmal läuft...
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.