Forum: Compiler & IDEs Preprozessor / Rechnen


von kies (Gast)


Lesenswert?

Hallo Mikrocontroller.net Gemeinde!!!
Als absoluter neuling auf diesem Gebiet möchte ich eine Frage stellen .

Also ich ich verstehe nur teilweise diese Zeile:
TCNT0 = (unsigned char)(signed short)-(XTAL / 1024 * 10e-3 + 0.5);


Diese Zeile ist in einer ISR

zu meine Fragen

1 Wirde diese Rechnung beim copillieren vom Preprozessor berechnet oder 
im Programm??

2 Wozu wird 0.5 adierrt ??

Vielen Dank

Grüsse

von Andreas K. (a-k)


Lesenswert?

kies wrote:

> 1 Wirde diese Rechnung beim copillieren vom Preprozessor berechnet
> oder im Programm??

Weder noch. Sie wird im Compiler berechnet. Eingeschaltete Optimierung 
vorausgesetzt.

> 2 Wozu wird 0.5 adierrt ??

Rundung zum nächstliegenden ganzzahligen Wert. Konvertierung von 
Fliesskommawerten zu Ganzzahlen rundet nicht sondern schneidet den 
Nachkommaanteil ab.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

kies wrote:
> Hallo Mikrocontroller.net Gemeinde!!!
> Als absoluter neuling auf diesem Gebiet möchte ich eine Frage stellen .
>
> Also ich ich verstehe nur teilweise diese Zeile:
> TCNT0 = (unsigned char)(signed short)-(XTAL / 1024 * 10e-3 + 0.5);
>
>
> Diese Zeile ist in einer ISR
>
> zu meine Fragen
>
> 1 Wirde diese Rechnung beim copillieren vom Preprozessor berechnet oder
> im Programm??

Kommt drauf an... jedenfalls wird's nicht vom Präprozessor berechnet. 
Falls XTAL eine zur Compilezeit bekannte Konstante ist -- wovon ich mal 
ausgehe -- dann wird der Ausdruck vom Compiler ausgewertet. Zumindest 
macht GCC das so, nennt sich dann "Faltung der Konstanten". AFAIK gehört 
die Konstantenfaltung zu den Optimierungen, die auch bei deaktivierter 
Optimierung gemacht werden.

Falls XTAL nicht zur Compilezeit bekannt ist, dann muss es zur Laufzeit 
berechnet werden.

Das wäre selbst dann der Fall, wenn XTAL eine Konstante wäre etwa dann, 
wenn man XTAL als Symbol definierte. Dann würde erst der Linker auflösen 
können, zu spät für eine Auswertung ausserhalb des µC. Dieser letzte 
Fall (Linker-Symbol) ist hier aber wohl auszuschliessen, da in dem 
Kontext exotisch.

Die Zeile dient wohl dazu, Timer0 wieder so aufzuziehen, daß er in 1ms 
den nächsten Interrupt per Overflow auslöst (also IRQ-Rate von ca 1kHz). 
Die 1024 ist vermutlich der Prescaler, mit dem der Timer initialisiert 
ist. XTAL ist die Frequenz, mit der der µC getaktet wird.

>
> 2 Wozu wird 0.5 adierrt ??

Zum Runden

>
> Vielen Dank
>
> Grüsse

Na ich hoffe mal, daß meine Antwort mehr Klarheit schafft als Verwirrung 
;-)

von kies (Gast)


Lesenswert?

Also das mit dem runden ist mir noch nicht zun 100% klar ???


Danke & Grüße

von Johannes M. (johnny-m)


Lesenswert?

kies wrote:
> Also das mit dem runden ist mir noch nicht zun 100% klar ???
Nun, es soll eine Gleitkommazahl in ein Integer-Format konvertiert 
werden. Nehmen wir mal an, der Ausgangswert sei 345,67. Bei der 
Konvertierung nach "ganzzahlig" wird im Normalfall einfach der 
Nachkommateil abgeschnitten und das, was vor dem Komma steht, 
übernommen. Das wären in diesem Fall 345. Das ist aber nicht korrekt 
gerundet. Deshalb wird vor der Typkonversion 0,5 hinzuaddiert, so dass 
die Zahl 346,17 konvertiert wird, und das ergibt korrekt gerundet 346.

Wenn der Nachkommateil des Ausgangswertes kleiner als 0,5 ist, wird 
nicht zur nächstgrößeren Ganzzahl aufgerundet, weil dann "Nachkommateil 
+ 0,5" kleiner als 1 ist. Z.B. 345,45 wäre nach der Addition 345,95, und 
das ist nach der Typkonversion (Abschneiden des Nachkommateils) 345, 
also abgerundet.

Und zur Funktionsweise des Präprozessors:
Den Präprozessor interessieren nur Zeilen, die mit einer Raute (#) 
beginnen. Nur diese Zeilen werden vom Präprozessor wirklich verarbeitet. 
Alle anderen Zeilen (also auch die von Dir genannte) werden 1:1 so, wie 
sie da stehen, dem Compiler übergeben. Deshalb rechnet der Präprozessor 
da auch nichts.

von kies (Gast)


Lesenswert?

Vielen Dank für deine schnelle und ausfürliche Antwort !!!

So jetzt hab ichs sogar Verstanden !!!



Vielen Dank schönen Abend !!!!!!!!

von Johannes M. (johnny-m)


Lesenswert?

Johannes M. wrote:
> Und zur Funktionsweise des Präprozessors:
> Den Präprozessor interessieren nur Zeilen, die mit einer Raute (#)
> beginnen. Nur diese Zeilen werden vom Präprozessor wirklich verarbeitet.
> Alle anderen Zeilen (also auch die von Dir genannte) werden 1:1 so, wie
> sie da stehen, dem Compiler übergeben. Deshalb rechnet der Präprozessor
> da auch nichts.
Hmmm, das kommt davon, wenn beim Tippen das Telefon klingelt und man im 
Eifer des Gefechts auf "Absenden" klickt...

Also, da fehlen noch ein paar Sätze:
Vom Präprozessor werden natürlich auch innerhalb von normalen Codezeilen 
Textersetzungen (die mittels #define vereinbart wurden) vorgenommen. 
Außerdem kann der Code, den der Compiler letztendlich zu Gesicht 
bekommt, in Abhängigkeit von Bedingungen "zusammengeschnitten" werden 
(mit #if, #ifdef usw.).

Ich hoffe, das hat jetzt nicht zu Missverständnissen geführt. Im Prinzip 
ist der Präprozessor nur ein "Textverarbeitungsprogramm", das dem 
Compiler den Code vorkaut.

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
Noch kein Account? Hier anmelden.