Hallo
Ich steh auf dem Schlauch, oder so... ;)
Wenn ich in meinem Source Code meine Wartefunktion so definiere, stimmt
die Wartezeit:
1
voiddelay_1ms(uint8_tms){
2
while(ms--)
3
_delay_loop_2(4000);// 4 cycles per iteration
4
}
Für meinen atmega168 mit 16Mhz hab ich überschlagen:
4 Mio Iterationen - 1 s
4 k Iterationen - 1 ms
Gut. Um ein bisschen portabler zu schreiben, packe ich die Formel in ein
#define statement und ... meine Funktion tut nicht mehr, die Wartezeit
wird viel zu lang:
1
// delay loop iterations for 1ms
2
#define ONEMS 1 / 4 * F_CPU / 1000
und
1
voiddelay_1ms(uint8_tms){
2
while(ms--)
3
_delay_loop_2((uint16_t)ONEMS);// 4 cycles per iteration
> Du benutzt nicht die fix-und-fertige Funktion aus der AVR-Libc...
Oooch ;) -- ist ja immerhin util/delay_basic.h aus der arv-libc.
F_CPU ist mit 16e6 definiert.
_delay_ms ist weiter nichts als ein Wrapper um _delay_loop_2, der
aus F_CPU und dem angegebenen Wert die für _delay_loop_2 notwendige
Zyklenanzahl berechnet -- also letztlich exakt das, was du willst
(wenn ich dich richtig verstanden habe).
Jörg Wunsch schrieb:
> _delay_ms ist weiter nichts als ein Wrapper um _delay_loop_2, der> aus F_CPU und dem angegebenen Wert die für _delay_loop_2 notwendige> Zyklenanzahl berechnet -- also letztlich exakt das, was du willst
Das ist richtig. Da _delay_ms aber mit float Zahlen rumhantiert, will
ich diesen "teuren" Aufruf/Code wegoptimieren.
Das Resultat meiner Rechnerei im #define sei also Null, versteh ich noch
nicht, weshalb das so ist.
Es entscheidet sich erst bei dem Aufruf der Funktion, von welchem Typ
ONEMS ist. In deinem Fall ist es ein Integer, kann somit nur ganzzahlig
werden. 1/4 ergibt nach Adam Riese 0.25, somit also 0.
Tom M. schrieb:
> Das ist richtig. Da _delay_ms aber mit float Zahlen rumhantiert, will> ich diesen "teuren" Aufruf/Code wegoptimieren.
"teuer" ist das nur für den Compiler. Der macht daraus dann den
gewünschten Integerwert.
Die Intention hinter den Gleitkommazahlen war einfach, dass auf
deinem Quarz ja nicht drauf steht: 7372800 Hz, sondern: 7,3728 MHz.
Damit kannst du schreiben:
1
#define F_CPU 7.3728E6
ohne dir erst überlegen zu müssen, wie viele Nullen du jetzt anhängst.
Außerdem kannst du halt auch bei _delay_ms schreiben:
1
_delay_ms(0.8);
2
_delay_ms(2.2);
Das empfinde ich als die durchaus natürliche Denkweise eines
Ingenieurs. Solche Aufrufe werden oft genug benutzt, um bestimmte
Timing-Werte aus einem Datenblatt zu realisieren, und da stehen sie
auch als Gleitkommazahlen -- weil man das am besten lesen kann.
Die Umrechnung in das, was der Controller kann, sollte man halt dann
dem Computer überlassen können.
(a) das hat nix mit dem Funktionsaufruf zu tun, sondern mit dem
cast-Operator.
(b) dein Define ist falsch, der cast bezieht sich nur auf die 1.
Beispiel:
Hab jetzt auf _delay_ms() umgestellt und siehe da, mein Code a)
funktioniert b) ist nicht wesentlich grösser. Schön. :)
Ich meine mich gerade zu erinnern, dass man dem Compiler mit einem
Suffix mitteilen sollte, wenn man mit nicht-integer Zahlen hantiert,
sowas wie:
Tom M. schrieb:
> Hab jetzt auf _delay_ms() umgestellt und siehe da, mein Code a)> funktioniert b) ist nicht wesentlich grösser. Schön. :)
Endlich :->
> Ich meine mich gerade zu erinnern, dass man dem Compiler mit einem> Suffix mitteilen sollte, wenn man mit nicht-integer Zahlen hantiert,> sowas wie:
Es würde schon helfen, wenn du endlich ein paar verdammte Klammern
setzen würdest:
> Es würde schon helfen, wenn du endlich ein paar verdammte Klammern> setzen würdest:
Hast ja recht, die Klammern... :)
> Und? Gibt nicht 14*10=140 aus, gell? Komisch.
Nee, da nicht: Der Präprozessor tauscht den Text aus, und dann greift
das altbekannte "Punkt-vor-Strich". Mein Cast war allerdings total übel,
oder die Klammern ham gefehlt, oder beides. ;)
Danke euch allen, schönen Abend noch. :)