Also grundsätzlich gilt bei I²C:
Erstmal ist der Master (bzw derjenige, der die Arbitrierung letztendlich gewinnt) Sender, Transmitter. Er sendet die Zieladresse, und mit dem letzten Bit dieses Bytes bestimmt er außerdem, ob er für den Rest des Telegrammes Transmitter oder Receiver sein will.
Nach diesem SLA+R/W-Byte können beliebig viele Bytes folgen, wobei die Festlegung der Rollen (Transmitter/Receiver) wie festgelegt bleibt. Der Receiver ACKt jedes Byte, NACKt er, ist das Telegramm für ihn ja auch beendet, der Master könnte also entweder den Bus freigeben (Stop Condition), oder ein neues Telegramm mit SLA+R/W (mit einer ggf anderen Adresse und/oder Datenrichtung) starten (repeated Start Condition ohne vorheriges Stop, er bleibt im Busbesitz).
Beim Lesen von Speicherbausteinen hast Du zB oft:
Slaveadressierung mit SLA+W (Master weiterhin Transmitter)(versuchte) Businbesitznahme mit Startcondition
adressierter Slave (Speicherbaustein) ACKt
Übertragung der gewünschten Speicher/Registeradresse
Slave ACKt (und setzt seinen internen Lesepointer entsprechend)
(Können ggf auch mehrere Bytes sein, wenn der Speicher zb groß ist)
Master generiert repeated start
Master sendet SLA+R (ab jetzt will er lesen)
Slave ACKt
Master liest (beliebig viele) Byte(s) und ACKt (bzw NACKt nach dem letzten).
Master gibt den Bus frei (StopCondition).
Der Slave kann zB nach jedem einzelnen Byte seinen Lesepointer inkrementieren, wodurch der Master sequentiell Lesen kann.
Fürs Schreiben gilt sinngemäß dasselbe, hier muß hal nur nicht die Datenrichtung (mit repeated start und SLA+R) umgekehrt werden.
Dein Sensor ist aus I²C-sicht quasi auch nur ein Speicher...
Beim lesen des Result ist es ähnlich. Habe ich auch teilweise in anderen Projekten gemacht. Es wird erst msb mit 8 Bit gelesen, dann lsb mit 8 Bit gelesen. Kommen in eine 16 Bit Variable. Erst msb und nach links verschieben dann noch lsb. Diese 16 Bit Variable wird durch Bitschubsen in Exponent mit Bit 15 bis 12 zerlegt und in Mantisse Bit 11 bis 0.
Wobei das weitere zerlegen nicht unbedingt nötig ist. Deine 16Bit-Variable enthält eine 16Bit-Fließkommazahl mit vier Bit Exponent und zwölf Bit Mantisse. Einfach genaue Fließkommazahlen (single) werden quasi genau so gespeichert, nur eben mit 32Bit, davon ein Vorzeichenbit, acht Exponentenbits und 23 Mantissenbits.
Du hast mit der 16bit-float irgendwie sowas ähnliches wie 'ne (unsigned) halbgenaue Fließkommazahl (
@dino03 ,
@Dirk usw bitte nicht steinigen), die Frage ist, was DU(!) jetzt weiter damit anfangen willst.
Irgendwas mit halbgenauen Fließkommazahlen weiterrechnen -> dann brauchst Du nichts weiter wandeln, aber Rechenoperationen, die auf dieser halben Genauigkeit arbeiten.
Irgendwas mit genaueren Fließkommazahlen weiterrechnen -> dann mußt Du diese "half"s in singles/doubles umwandeln, und kannst fertige Hochsprachenoperationen nutzen.
Die Kommazahl nur irgendwie ausgeben -> dann kannst Du die Formel aus dem Datenblatt Seite 20 anwenden - die Multiplikation mit 0,01 erledigst Du durch hinzumogeln eines Kommas, bei 2hochExponent bin ich mir grad nicht sicher(*), das sollte eigentlich auch ganz einfach gehen, bleibt 'ne Multiplikation einer 4Bit und einer 12Bit-Zahl.
Als Ergebnis erhälst Du einen Integer bzw eine Fixkommazahl (der 0,01-Faktor).
(Ob sich die Multiplikation und die Dezimalstellenzerlegung (ggf->String) bereits in einem Arbeitsgang erledigen läßt, ist mir (noch) nicht klar - aber eigentlich ist das Dein Problem -> Dein Hirnschmalz
)
Edit zu (*): wäre das nicht genau Exponent * Mantisse (also die 4-Bit-ZAhl mal die 12-Bit-Zahl)? dann müßte man sich nurmal die Multiplikationsroutine genauer ansehen, um die Schleife Registereffizient zu halten...