Hallo, ich lese mit folgender Funktion die Temperatur eines DS1624 aus. Allerdings bekomme ich so die Nachkommastelle nur als 0.5 ich möchte die Nachkommastelle aber genau bekommen. Im Datenblatt steht das +25.0625 Grad = 00011001 00010000 Bin = 1910 Hex sind. Aber ich werde daraus irgendwie nicht schlau. Ich brauche von euch auch kein Code bespiel oder so was. Ich möchte nur gerne wissen die sich diese Temperatur zusammen setzt. Eine Fukntion kann ich mir dann daraus bestimmt selber zusammenbasteln. u08 get_temp_a_temp1, get_temp_a_temp2; // Temperatur LSB/MSB u16 get_temp_a_temp3; // Umgerechnete Temperatur char get_temp_ac[7]; // Konvertierte Temperatur INT->ASCII char* get_temp_a(unsigned char i2c_address){ i2c_init(); // I2C initialisieren i2c_start(i2c_address); // I2C starten i2c_write(0xEE); // Start Convert T i2c_stop(); // I2C STOP i2c_rep_start(i2c_address); // I2C Schreiben an DS16xx i2c_write(0xAA); // Befehl zum Temperatur lesen an DS16xx i2c_stop(); // STOP i2c_rep_start(i2c_address+1); // I2C Lesen an DS16xx get_temp_a_temp1 = i2c_readAck(); // MSB der Temperatur lesen get_temp_a_temp2 = i2c_readAck(); // LSB der Temperatur lesen i2c_write(0x22); // Stop Convert T i2c_stop(); // I2C Stop get_temp_a_temp3 = get_temp_a_temp1*0x0A; // temp1 mit 10 multiplizieren, damit keine Kommazahlen enstehen if(get_temp_a_temp2 > 0x80) { get_temp_a_temp3 +=0x05; } // Wenn temp2 groesser als 128 dann 5 addrieren itoa(get_temp_a_temp3, get_temp_ac, 10 ); // Temperatur von INT nach ASCII return get_temp_ac; } Gruß & Danke Nico
Hallo, habe deinen Code jetzt nicht durchforstet, aber das Format ist eigentlich relativ einfach. Wenn du die zwei ausgelesenen Bytes betrachtest, hast du ja automatisch 16 bit. Die Auflösung des DS1624 beträgt jedoch 13 bit. Die drei letzten bit, also die drei kleinsten bit des ausgelesenen LSB kannst du also verwerfen. Übrig bleiben 13bit, deren Wert multipliziert mit 0,03125°C genau deinen Temperaturwert ergibt. Angeordnet sind die bits wahrscheinlich so, weil du für ganze Grad dann nur das MSB auswerten musst und direkt die Temperatur hast. Die 5 höherwertigen bits des LSB geben also genau den Nachkommawert an, wenn du ihn mit 0,03125 multiplizierst. Zusammengefasst: 16bit-Wert auslesen, durch 8 teilen, mit 0,03125°C malnehmen = Temperatur in voller Auflösung. Ich hoffe, ich konnte helfen. Gruß WiWil
Hi Nico, das erste Byte ist die Mantisse und berechnet sich so wie man es vom dualen Zahlensystem her kennt: 25 = 00011001 das zweite Byte ist der Exponent und dessen Aufbau sieht so aus: binär dezimal 2e-1 00000001 0,5 2e-2 00000010 0,25 2e-3 00000100 0,125 2e-4 00001000 0,0625 2e-5 00010000 0,03125 2e-6 00100000 0,015625 2e-7 01000000 0,0078125 2e-8 10000000 0,00390625 ein kleines Rechenbeispiel findest Du hier: http://board.gulli.com/thread/447189-gleitkommaoperation-binaer-ausfuehren-mantisse-und-exponent-gegeben-bitte-um-hilfe/
Hallo GRMusik, Das passt aber dann nicht mit der Wertetabelle aus dem Datenblatt zusammen. Nach deiner Berechung kommt man mit 1910h, seinem Beispielwert auch nicht auf 25,0625 °C, oder?
Die Tabelle "binär" ist falsch herum, außerdem ist es kein Exponent, sondern normale Nachkommastellen, nach dem Komma beginnend mit der 0,5
Hallo, ich habe jetzt eine Lösung: u08 get_temp_a1, get_temp_a2; char get_temp_rv[8]; float temp; char* get_temp_a(unsigned char I2C_ADDRESS){ i2c_init(); i2c_start(I2C_ADDRESS); i2c_write(0xEE); i2c_stop(); i2c_rep_start(I2C_ADDRESS); i2c_write(0xAA); i2c_stop(); i2c_rep_start(I2C_ADDRESS+1); get_temp_a1 = i2c_readAck(); get_temp_a2 = i2c_readAck(); temp = get_temp_a1 + (get_temp_a2/8)*0.03125; dtostrf(temp, 6, 3, get_temp_rv); return get_temp_rv; } Ich hoffe ihr könnt damit was Anfangen. Wenn doch noch ein Fehler drinne sein sollte, bitte ich um verbesserung. MfG Nico
Ja, so gehts auch, erspart bei einem 8-bitter etwas Rechenpower, weil er nur mit einem Byte Multiplizieren muss.
So, jetzt kommt der Fixed-Point-Fan und rechnet ganz einfach: Vorkomma geht 1:1 0x19 ist 25 Nachkomma: 0x10 multipliziere ich mit 0x27 (39 dez) und erhalte 16*39=624. Das zeige ich 4 stellig an (mit führender 0) und erhalte: 25,0624 (statt 25,0625). Eine einzige 8x8-bit-Multiplikation, ohne Float 25,500 wird als 25,4992 angezeigt (0x80*0x27=0x1380=4992). Noch genauer wird es, wenn man vorher /8 rechnet (man verliert keine gültigen Bits) und dafür mit 10000/32=312(,5) multipliziert - denkste, ist auch nicht genauer. Aber man kann 313 verwenden, dann kommt statt 0x1908: 25,03125 25,0313 0x1910: 25,0625 25,0626 0x1980: 25,5000 25,5008 0x19f8: 25,96875 25,9703 Braucht allerdings eine 6x9-bit-Multiplikation, also 8x16->16. Wer es wirklich genau will, nimmt eine 8x16->24 Mult ohne Schieben: 0x80*0x2710=0x138800 128 * 10000=1280000 (8x16->24bit) 0x1388 1280000/256= 5000 (unterstes Byte weglassen ->4 Nachkommastellen) 0xf8*0x2710=0x25D780 248 * 10000=2480000 0x25d7 2480000/256= 9687 ->25,9687 Noch Fragen?
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.