Forum: Mikrocontroller und Digitale Elektronik Atmega: int_8t aus 2 halben int8_t zusammensetzen


von Alexander B. (alex1891)


Lesenswert?

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

von Ingo L. (corrtexx)


Lesenswert?

Zeig doch mal deine Bitschieberei

von AnaLogExp (Gast)


Lesenswert?

"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);

von Alexander B. (alex1891)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von AnaLogExp (Gast)


Lesenswert?

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

von AnaLogExp (Gast)


Lesenswert?

@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.

von Alexander B. (alex1891)


Lesenswert?

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.

von Alexander B. (alex1891)


Lesenswert?

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...

von Alexander B. (alex1891)


Lesenswert?

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)

von Lutz (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.