PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Prinzipielle Fragen zu Rechenoperationen.



PCMan
02.07.2007, 20:38
Hi,
ich will mittels dem Timer0 eine Frequenz an einem Port ausgeben. Meine Überlegungen und auch der Wiki haben mich recht weit gebracht, aber an einer Stelle komme ich nicht weiter:
Wenn ich mir den Vorladewert à la

Preloader=256-(F_CPU/(PRESCALER*Hz));
errechne (F_CPU := 8000000UL, PRESCALER=256, Hz=440), erhalte ich ein anderes Signal als wenn ich mir den Wert auf Papier ausrechne und den verwende, à la

Preloader=185;
. Dann funktionierts nämlich.
Das heißt, der Mega32 rechnet da anders als ich, was mache ich also bei der Rechenoperation falsch?
vG Simon

franzl
02.07.2007, 21:51
Hi,
also ich weiß jetz nicht ob es vielleicht an den Klammern liegt. Ich rechne immer Preloader= 256- F_CPU/Prescaler/f . Probier doch mal ob das klappt.
mfg franz

askazo
03.07.2007, 07:41
Wenn zwei zu Multiplizierende Variablen z.B. int-Typen sind, darf das Ergebnis auch maximal int sein. PRESCALER * Hz (256 * 440 = 112.640) übersteigt aber diese 16Bit vom Integer. Dein Compiler sollte deshalb auch die Warnung "integer overflow in expression" ausgeben.

Franzls Variante hingegen funktioniert einwandfrei, da es hierbei zu keinem Overflow kommen kann.

[edit]
Noch eine Alternative:
Wenn Du mindestens einen der beiden Makros/Variablen PRESACLER bzw. Hz als long-Datentypen deklarierst, klappts auch mit der Multiplikation.
[edit]

askazo

PCMan
03.07.2007, 18:36
Hi,
also verstehe ich das richtig: bei meiner Operation entstehen eben NICHT-INT Datentypen? Aber ich dachte (hatte ich irgendwie im Hinterkopf), dass wenn ein sagen wir mal Float wert rauskommt und einer int Variablen zugewiesen wird automatisch gerundet wird. Stattdessen wird versucht aber Float auf Int zu übertragen, wobei aber die Bitbreite des Int nicht ausreicht!?
Wozu long? Das Ergebnis soll ja einen maximalen Zahlenwert von 255 einnehmen.
Franzls Weg werde ich mal testen, wobei ich nicht verstehe, wieso es da nicht zu einem Overflow kommen kann, denn F_CPY/Prescaler/f ist ja das gleiche wie F_CPU/(Prescaler*f)
vG Simon

EDIT: Blah - ich hab's verstanden. Danke. War vom Punkt irritiert gewesen, hab ihn als Komma verstanden. Error ;)

SprinterSB
28.07.2007, 19:37
F_CPY/Prescaler/f ist ja das gleiche wie F_CPU/(Prescaler*f)

Nö, das ist nicht das gleiche! Das Rechnen im Computer/Taschenrechner geht wegen Rundingsfehlern und Bereichsüberläufen nicht so glatt wie im Matheunterricht!

Das Produkt in Zähler ist größer als 16 Bit, daher:



Preloader = 256- F_CPU / ((unsigned long) PRESCALER*Hz);


ist zwar lästig und tückisch, aber muss eben sein. Steht wohl irgendwo tief in der C-Spez wie das vonstatten geht. Es entstehen ja Ausdrücke wie PRESCALER*Hz, wo weder durch den Input noch dirch den Output festgelegt ist, wie groß der Typ sein soll. In C ist das der größte Typ, der an der Operation beteiligt ist, also 16 Bits. Das Prokukt pass aber nicht in diese 16 Bits rein.

PCMan
29.07.2007, 06:18
hi,
danke hab's inzwischen verstanden.
vG Simon