Hallo zusammen, bin gerade in den Anfängen der Mikrocontrollerprogrammierung - über das LED blinken lassen bin ich entwischen schon raus und bin beim 1Wire-Bus angekommen. Der Bus läuft auch schon und es geht mir um die Interpretation des Temperaturwertes. Kurze Hintergrundinfos: Ich benutze die 12 Bit Wandlung und erhalte 16bit zurück. Im LSB sind die hinteren 4 Bit der Wert der Nachkommastelle und der Wert vor dem Komma setzt sich aus den unteren 4 Bit im MSB und den oberen 4 Bit im LSB. Mein Problem: Ich will zwei 8bit Variablen nutzen - eine für den Wert vor dem Komma und eine für den Wert nach dem Komma. Ich habe das durch Bitverschriebung und Maskierung auch schon hinbekommen, nur springt der Wert machmal seltsamer weiße um 1 Grad nach oben oder unten. Ich habe das überprüft und mir den zurückgelieferten Wert anzeigen lassen ohne die Bitmanipulationen -> Der Wert springt nicht, also liegt es an meiner Bitmanipulation. Kann mir jemand Spontan ein Codebrocken herwerfen um evtl. mein Problem zu erkennen? Vielen Dank schonmal
"LSB" und "MSB" beziehen sich auf Bits. Was Du meinst, ist "High Byte" und "Low Byte". Du willst vermutlich folgendes:
1 | byte wert_vor_dem_komma = (byte)(high_byte<<4) | (low_byte>>4); |
2 | byte wert_nach_dem_komma = (byte)(low_byte<<4); |
AnaLogExp schrieb:1 | byte wert_vor_dem_komma = (byte)(high_byte<<4) | (low_byte>>4); |
2 | byte wert_nach_dem_komma = (byte)(low_byte<<4); |
Danke! Sieht meinem ziemlich ähnlich, ich hatte nur noch ein Teil ausmaskiert:
1 | int8_t wert_vor_dem_komma = ((high_byte & 0x0F)<<4) | ((low_byte & 0xF0)>>4) |
Also so in etwa hab ich das gelöst, allerdings habe ich meinen Code gerade nicht zur Hand. Aber irgentwie Kippt mir immer im in der Variable wert_vor_dem_komma das LSB und ich kanns mir nicht erklären
Alexander B. schrieb: > Also so in etwa hab ich das gelöst, allerdings habe ich meinen Code > gerade nicht zur Hand. > > Aber irgentwie Kippt mir immer im in der Variable wert_vor_dem_komma das > LSB und ich kanns mir nicht erklären Das wär schon mal wichtig. Genauso wie die Datentypen wichtig sind! Wenn du auf Byteebene operierst, und auf der Ebene auf der du dich momentan bewegst sollten man wahrscheinlich erst mal von Bytes ausgehen, dann ist ein uint8_t der Datentyp der Wahl! In den meisten Fällen wird es so sein, dass man zuerst mal alles einfach als Byte ansieht, ohne Ansehen irgendeines Vorzeichens. Dort schiebt man die Bits zurecht und erst dann ist der Zeitpunkt gekommen, auf einen Datenttypen mit Vorzeichen zu wechseln. Es gibt zwar durchaus auch Ausnahmen, aber oft ist das ein erster vernünftiger Ansatz. Denn was du auf keinen Fall willst, das ist, dass sich hier
1 | .... low_byte & 0xF0)>>4 .... |
ein auf 1 gesetztes Bit 7 in irgendeiner Art und Weise speziell auswirkt.
0. Keine signed-Variablen verwenden. (byte) ist klarer bei Bit-Manipulationen. 1. Vergiß beide UND-Masken, denn Du shiftest die dadurch auf 0 gesetzten Bits ohnehin aus dem Wertebereich heraus. Auch high_byte und low_byte müssen byte-Variablen sein, damit der rechts-Shift Nullen nachschiebt. 2. Mein cast nach (byte) ist wichtiger, da sonst auf 16-Bit-Breite geodert wird. 3. Vielleicht ist Dein Fehler, daß Du nicht sicherstellst, daß Du das Low-Byte vor dem High-Byte aus dem ATmega ließt. Also zuerst sowas wie:
1 | byte low_byte = BLA_BLA_L; |
2 | byte high_byte = BLA_BLA_H; |
Ist übrigens wirklich wichtig, was genau Du in Deinem Code hast. Und nicht nur die zwei Zeilen sondern beginnend beim Einlesen der Hardware
@Karl Heinz: Er hätte bei signed Variablen natürlich zuerst schieben und dann mit 0x0F undieren können, dann wäre es wieder richtig gewesen. Aber unsigned-Variablen sind hier logischer, klarer, eindeutiger und in Deinem Fall sogar zum richtigen Ergebnis führend.
Karl Heinz schrieb: > Wenn du auf Byteebene operierst, und auf der Ebene auf der du dich > momentan bewegst sollten man wahrscheinlich erst mal von Bytes ausgehen, > dann ist ein uint8_t der Datentyp der Wahl! Mir fällt gerade auf -> ich habe tatsächlich uint8_t verwendet. Nun -> ist der cast wirklich notwendig und warum kippt mir nur im manipulierten Byte das Bit und nicht beim Realen Rückgabewert den Sensors. Und noch eine kurze Frage nebenbei: ich könnte ja auch ein uint16_t nehmen, aber da ich ein 8 bit Controller nutze halte ich das für eine weniger elegante Lösung, liege ich da richtig? Edit: Oh ihr wart schneller als ich, also werte ich heute Nachmittag mal ausprobieren zu casten und mein undieren rauschmeißen und euch mit meinem genauen code versorgen, falls es nicht funktioniert. P.S. vorzeichen ist eher nebensächlich da ich in erster Linie Raumtemperaturen aufzeichen will und die (hoffentlich) nie im negativen Bereich sein werden :D Natürlich will ich am Ende das Vorzeichen miterfassen, aber das ist ja kein Problem und an den oberen 4 bit im high_byte abzufragen.
Also ich habe das jetzt mal geändert aber die Stelle hüpft immernoch manchmal, was mir aufällt, es ist scheinbar nurnoch an einem Sensor, vlt hat der ja einen Schuss...
So jetzt scheints stabil zu laufen, lag scheinbar am internen Takt, hab jetzt ein 16Mhz quarz und konnte es seitdem nicht mehr beobachten... (bis jetzt)
Alexander B. schrieb: > Ich habe das überprüft und mir den zurückgelieferten Wert anzeigen > lassen ohne die Bitmanipulationen -> Der Wert springt nicht, also liegt > es an meiner Bitmanipulation. Alexander B. schrieb: > So jetzt scheints stabil zu laufen, lag scheinbar am internen Takt, hab > jetzt ein 16Mhz quarz und konnte es seitdem nicht mehr beobachten... > (bis jetzt) Das paßt aber gar nicht zusammen. Wenn der rohe Wert nicht springt, sondern nur der Berechnete?
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.