guten abend, die herren, ich hätte ein paar fragen zu c-syntax und avr-studio4. auf dieser webseite habe ich im kapitel "softwareentprellung", das quellcode von Peter Dannegger gefunden. das quellcode enthält folgende zeile: TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); kann jemand diese zeile interprätieren? beim simulieren würde ich gerne die zwischenwerte meiner variablen, die ich deklariert habe, sehen. bis jetzt kann ich nur die zustende von den ports anschauen. gibt es irgendein zusätzliches tool, das sowas ermöglicht, oder kann man was an den einstellungen ändern? danke im voraus
>TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); >kann jemand diese zeile interprätieren? interpr*e*tieren Nee, weil sie Fehler enthält. (int16_t)-(....) Zeilen aus Codes nicht abtippen ! 1:1 kopieren ist besser.
>TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);
erst mal sind da zwei Casts: die Berechnung -(F_CPU / 1024 * 10e-3 +
0.5) wird zu einem int16 (word) gemacht und dann zu einem uint8 (byte).
Die Berchnung selbst ist dann wieder was mit einer Fließkommazahl.
Der Timer wird auf einen bestimmten Wert gesetzt.
kann man das nicht irgendwie einfacher und verständlicher schreiben, weil diese schreibweise hatte ich nie gesehen. und die 2-te frage, hat jemand eine idee?
>und die 2-te frage, hat jemand eine idee?
Nö. Du könntest höchstens die Berechnung in mehrere Schritte (und
Variablen) aufteilen.
die zweite frage war zu avr-studio4, beim testen will ich die werte von meinen variablen. das vereinfacht die fehlersucher erheblich (zumindest für mich) ;)
> kann jemand diese zeile interprätieren? Schlecht lesbarer Code. > TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); "F_CPU / 1024" wird vermutlich dort stehen, weil ein Timer mit 1024er-Hardware-Vorteiler benutzt wird, d.h. F_CPU / 1024 ist die Geschwindigkeit, mit der der Timer zählt. Anders ausgedrückt: dieser Term entspricht "Impulse pro Sekunde". "* 10e-3" ist eine andere Schreibweise für "/ 1000". Wenn man die Impulse pro Sekunde durch 1000 teilt, erhält man die Impulse pro ms. In dieser zeitlichen Grössenordnung, eine Millisekunde, wird gerne entprellt: Der Timer wird so eingestellt, dass in 1 ms ein Interrupt kommt. + 0.5 ist eine (überflüssige) mathematisch korrekte Rundung: die Teilerei ergibt eine Fliesskommazahl und der Compiler muss daraus für die Zuweisung an TCNTO eine Integer-Zahl machen. Indem man vorher 0.5 addiert, wird mathematisch korrekt gerundet Beispiele: aus 10.1 wird 10 (10.1 + 0.5 = 10.6, davon bleibt bei Umwandlung zu Integer der Vorkommateil, die 10). Aus 10.6 wird korrekterweise 11 (10.6 + 0.5 = 11.1, davon bleibt Vorkommaanteil 11). Das "-" sorgt schliesslich dafür, dass nicht der ausgerechnete Wert (Impulse pro ms) in's Timer-Register kommt, sondern die gleich grosse Differenz zum Überlauf des Timers. Beispiel: Man rechnet 10 Impulse/ms aus. Das 8-Bit-Register läuft bei 255 über, danach kommt 0. Also wird der Wert 246 in's Timer-Register geschrieben: nach 10 Impulsen, also in 1 ms, kommt dann der Überlauf zu 0 und damit der gewünschte Interrupt. Dass "-x" dem Wert "Überlauf - x" entspricht, hängt mit binären Rechenregeln zusammen. Zum Nachrechnen: -10 ist definiert als das Zweierkomplement von 10, binär 1111111111110110. Wenn man die unteren 8 Bit davon als vorzeichenlose Integer interpretiert (1111110110), ergibt das 246. > kann man das nicht irgendwie einfacher und verständlicher schreiben Vieleicht so: #define TIMER_PRESCALER 1024 #define TIMER_OVERFLOW 256 #define TIMER_TICKS_PER_MS ((F_CPU / TIMER_PRESCALER) / 1000) TCNT0 = TIMER_OVERFLOW - TIMER_TICKS_PER_MS;
Wenn F_CPU sehr niedrig ist, einen anderen Vorteiler nehmen, damit es nicht auf genaue Rechnug ankommt (also nicht drei Impulse pro ms oder etwas in der Art).
Dietmar E wrote:
> "* 10e-3" ist eine andere Schreibweise für "/ 1000".
Nein, es ist eine irreführende Schreibweise für »/ 100.0«. Offenbar
soll der Timer mit 10 ms Taktperiode laufen.
Man beachte auch, dass »/ 100« etwas anderes als »/ 100.0« hier
bewirken würde.
Jörg Wunsch wrote:
> Nein, es ist eine irreführende Schreibweise für »/ 100.0«.
Die Intention sehe ich natürlich schon (Darstellung des Intervalls
in Millisekunden). Dafür hätte man lesbarer schreiben können:
1 | #define TIME_MS(x) ((x) * 1e-3)
|
2 | |
3 | ... * TIME_MS(10) |
> es ist eine irreführende Schreibweise für »/ 100.0«.
Oops. Da hat er mich erwischt. Wer rechnet schon mit 10 vor dem Komma
bei Exponentialschreibweise.
Also im Original steht ja auch ein Kommentar dahinter:
1 | TCNT0 = (u8)(s16)-(XTAL / 1024 * 10e-3 + 0.5); // preload for 10ms |
Man könnte aber auch schreiben:
1 | #define ms e-3
|
2 | |
3 | TCNT0 = (u8)(s16)-(XTAL / 1024 * 10ms + 0.5); // preload for 10ms |
Peter
Das lässt sich zwar besser lesen, ist aber von den Seiteneffekten für den nichtsahnenden Nutzer fies.
ich bedanke mich bei allen, die mir geholfen haben. echt netter forum. weiter so. MfG ;)
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.