C Syntax & AVRStudio4

Gast #778878
Lesenswert?

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
Gast #778885
Lesenswert?

>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.
Gast #778888
Lesenswert?

>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.
Gast #778940
Lesenswert?

> 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;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren