Hallo bluespark,
mal nicht mit allen immer gleich so schwer ins Gericht gehen! Fällt nämlich häufig auch auf einen selbst zurück. Es kann immer mal passieren, das sich jemand verwerkelt oder etwas übersieht.
Da muss ich allerding sagen, habe ich auch schon ganz schön geschlafen.- Du vertauschst in der Read-Funktion beim Einlesen der Werte im zweiten 16bit-Transfer LSB und MSB. Zuerst wird das MSB übertragen!
Soweit ich sehe, schneidet er doch nirgend wo ein Vorzeichen ab.-- Du rechnest die Zweikomplementwerte falsch in vorzeichenbehaftete Werte um. Das darf nie durch Abschneiden der Vorzeichenbits geschehen. Zweikomplementwerte und vorzeichenbehaftete Werte werden immer durch die Operationen "Komplement bilden"--"Eins addieren" in das jeweils andere Format umgewandelt.
-- Deswegen dürfen nicht alle 12bit Werte sowie auch nicht alle 14bit-Werte gleich maskiert werden. Ich würde das switchen also eher auf die "address" anwenden und darin dann für jede Adresse separat die Umwandlung der beiden Bytes dummy/result_int in ein float vornehmen.Wenn ich mir den Code mal gerade ansehe, muss ich sagen, das dieser auf den ersten Blick schon Funktionieren sollte. (Unter Berücksichtigung der impliziten Typumwandlungen der Kompiler). Zudem hab ich nie gesagt, das der Code besonders gut oder schlecht programmiert wurde.Code:signed int result_int; unsigned int dummy; result_int = result_int << 8; // Schiebe MSB um 8 nach links result_int |= dummy; // Füge LSB hinzu switch(bit_count) // Bit Maskieren { case 12: result_int &= 0x0FFF; break; // Maskiere oberste 4 Bit --> 12-Bit Wert ** Fehlerhaft bei Auslesen vom >>Sensor Temperature Data<< -Register (Fällt bei pos. Werten unter Umständen gar nicht auf) case 14: result_int &= 0x3FFF; // Maskiere oberste 2 Bit --> 14-Bit Wert result_int = result_int << 2; // Shifte um 2 nach li. wegen Vorzeichen ** Fehlerhaft bei Auslesen vom >>Angel<< -Register break; // wird mit /4 beim Scalefactor kompensiert } result_float = result_int; // Resultat als float abspeichern result_float = (result_float * scale_factor); // Counts skalieren
soweit ich das im Datenblatt erkennen kann, hab ich da gelesen, das diese Register >> NONVOLATILE<< sind. Diese Register werden während des Startups selbstständig vom internen ASIC wider restauriert..-- Deine Init-Routine schafft es nicht, einen bekannten Anfangszustand herzustellen. Die Register SMPL_PRD und GYRO_SCALE müssen abgeprüft und ggf verändert werden.
Wie schon geschrieben, habe ich nie gesagt, das der Code besonders gut oder schlecht programmiert wurde. Es gibt hier sehr viel Optimierungspotentieal. Zudem nutzt man bei solchen Anwendungen am besten gar keine floats. Die produzieren nämlich aufgrund ihrer Darstellung nur Fehler.-- Das Belegen der Register "dummy" und "rsult_int" durch VerODERn ist fehleranfällig. Wieso weist du im ersten Schritt nicht direkt zu?
Warum soll ichs dann erwähnen ?-- in der Funktion Read sendest du im zweiten Transfer die adress erneut. Da ist unnötig, aber nicht falsch. Du wertest ja die ersten beiden Bytes die zurückkommen nicht aus.
hab ich in meinem Beitrag vom 17.12.2007, 09:45 erwähnt.eins habe ich vergessen: in der Init-Funktion sollte die startup-time von 160ms sichergestellt werden!
Habe ich auch im überarbeiteten Code unten geschrieben. Wobei ich mich in der Reihenfolge vertan habe, was mir fumir dankbarer weise gleich mitgeteilt hat, so das wirs klar gestellt haben.-- Nach Autonull hingegen in der Init machst du zuwenig Pause: Stelle sicher dass mindestens 50ms (!!!) gewartet wird, denn nach Autonull folgt automatisch ein flash-update und das braucht lange.
Gruß, Volker
Lesezeichen