Guten Abend, ich versuche gerade den Software-Uart-Code vom Roboternetz ( http://www.rn-wissen.de/index.php/Software-UART_mit_avr-gcc ) auf einem ATtiny25 zum laufen zu bekommen und verstehe die Funktion folgender Zeile nicht ganz: OCR1A = (uint16_t) ((uint32_t) F_CPU/BAUDRATE); Ich kenne diese Typedefs bis jetzt nur aus den herkömmlichen Variablendeklarationen, aber das hier scheint etwas Anderes zu sein. Meine Vermutung: "(uint32_t) F_CPU/BAUDRATE" teilt dem Compiler mit, dass er 32 Bit für den Wert reservieren soll, weiter links wird dann abgerundet. Aber man merkt wohl, dass ich das Konzept noch nicht so ganz durchschaut habe. Kann mir jemand etwas genauer erklären, was hier geschieht? Vielen Dank schonmal! Marc
>Ich kenne diese Typedefs... Welche Typedefs. Ich sehe hier keines. >... bis jetzt nur aus den herkömmlichen Variablendeklarationen Typedefs werden in Typdeklarationen verwendet, nicht in Variablendeklarationen. Der von Dir gezeigte Code aber ist eine Zuweisung; weder eine Variablen- noch eine Typdeklaration. >..."(uint32_t) F_CPU/BAUDRATE" teilt dem Compiler mit, dass er 32 Bit für >den Wert reservieren... Nein. Hier wird nichts "reserviert", sofern man unter reservieren das im Computerbereich übliche vorbehalten von RAM-Bereichen versteht. Vielmehr wird gesagt, dass F_CPU ein uint32_t ist. >...weiter links wird dann abgerundet. Hier wird nirgends gerundet, weder links, noch rechts, noch oben, noch unten. Aber das Ergebnis der Division von F_CPU durch BAUDRATE wird in ein uint16_t umgewandelt bevor es OCR1A zugewiesen wird.
>OCR1A = (uint16_t) ((uint32_t) F_CPU/BAUDRATE); >F_CPU/BAUDRATE Berechnet eine Division. Damit das Ergebnis auch noch sinnvoll ist, wird F_CPU auf uint32_t gecastet, also sein Zahlenbreich vergrößert. Damit das Ergebnis auch wieder ins OCR1A-Register passt, wird zurück auf uint16_t gecastet. Sollte aber unnötig sein. Sofern F_CPU und BAUDRATE keine Variablen sind, sollte man sich da Gecaste sparen können.
>... bis jetzt nur aus den herkömmlichen Variablendeklarationen >Typedefs werden in Typdeklarationen verwendet, nicht in >Variablendeklarationen. >Der von Dir gezeigte Code aber ist eine Zuweisung; weder eine Variablen- >noch eine Typdeklaration. Typischer Fall von Verwechslung mangels soliden Grundwissens. Danke für die Richtigstellung - ich muss das alles dringend aufarbeiten. >Damit das Ergebnis auch noch sinnvoll ist, wird F_CPU auf uint32_t >gecastet, also sein Zahlenbreich vergrößert. Ok, jetzt wird's langsam klar, vielen Dank! Und mit "casting" hab' ich das richtige Stichwort. Eine Frage noch: Bezieht sich das casting allein auf F_CPU oder auf das Erebnis der Division?
Marc schrieb: > Ok, jetzt wird's langsam klar, vielen Dank! Und mit "casting" hab' ich > das richtige Stichwort. > > Eine Frage noch: Bezieht sich das casting allein auf F_CPU oder auf das > Erebnis der Division? Operatoren Reihenfolge.(Stichwort für google: "operator precedence C") http://www.difranco.net/cop2220/op-prec.htm Casts stehen in der Hierarchie fast ganz oben, binden also sehr stark. Dementsprechend bezieht sich dieser Cast nur auf F_CPU (Wobei diese Casts in diesem Ausdruck überflüssig sind. Der Ausdruck würde auch dann richtig berechnet, wenn keine Casts da wären. In diesem Fall sollte man sich an die Regel halten: Caste nur dann, wenn es wirklich unbedingt notwendig ist, ansonsten lass den Compiler seine Arbeit tun)
>http://www.difranco.net/cop2220/op-prec.htm > >Casts stehen in der Hierarchie fast ganz oben, binden also sehr stark. >Dementsprechend bezieht sich dieser Cast auf F_CPU Ok! Vielen Dank und einen sonnigen Tag noch!
die division wird aber auch in 32bit durchgeführt? oder nicht? eine Komponente hat ja 32Bit, erst das ergebins wird auch 16Bit zurechtgestutzt.. PS: die uart Routinen von hier sind wesentlich besser...
... ... schrieb: > die division wird aber auch in 32bit durchgeführt? oder nicht? eine > Komponente hat ja 32Bit, erst das ergebins wird auch 16Bit > zurechtgestutzt.. Ja. An dieser Stelle wird es Zeit den obligaten Hinweis zu geben: Du brauchst vernünftige Literatur (zb einen Kernighan&Ritchie). Da steht das alles (und noch viel, viel mehr) drinnen. Ohne Unterlagen kann man eine Sprache wie C nicht vernünftig erlernen. Da gibt es viel zu viele kleine (und auch größere) Stolpersteine.
#define F_CPU 1000000UL die Typisierung 'UL' würde das casten auch überflüssig machen, könnte aber zu Fehlern führen wenn es dann fehlt. Wenn man verschiedene Quelltext mixt dürfte das explizite casten im Makro narrensicherer sein.
JojoS schrieb: > aber zu Fehlern führen wenn es dann fehlt. Wenn man verschiedene > Quelltext mixt dürfte das explizite casten im Makro narrensicherer sein. Grundsätzlich ja. Aber nicht in diesem konkreten Fall. Hier gibt es keine Möglichkeit eines Überlaufs. Durch die Division wird das Ergebnis ja nur kleiner als die Ausgansgzahlen. Wenn die Ausgangszahlen int sind, dann wird auch das Ergebnis in int reinpassen. Ist eine der Ausgangszahlen zu groß für einen int, dann hebt der Compiler diese Zahl sowieso von sich aus von int eine Stufe höher (auf long). Das einzige was passieren könnte ist, dass man mit signed/unsigned ein Problem bekommt. Allerdings wird nach menschlichem Ermessen weder F_CPU noch BAUDRATE je negativ werden, wobei dann allerdings die Frage interessant wäre was denn das richtige Ergebnis sei. Bleibt also nur noch der Fall, dass der Compiler eine der beiden Zahlen aufgrund des Zahlenwertes als long ansieht, obowhl er das nicht müsste, weil es sich in einem unsigned int noch ausgehen würde. Der Fall ist aber müssig, da durch den Cast die ganze Berechnung auf jeden Fall (selbst bei kleinen Zahlen, ok, geschenkt F_CPU wird höchst wahrscheinlich auf AVR immer einen int sprengen) auf long angehoben wurde. Laufzeitproblem ist das allerdings auch keines. Sind alles konstante Zahlenwerte, die der Compiler im Constant-Folding auswerten wird.
[OT]
>Vielen Dank und einen sonnigen Tag noch!
Bei uns regnet es...
[/OT]
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.