Rechnen mit Konstanten liefert unterschiedliche Ergebnisse

Gast #5686897
Lesenswert?

Hallo zusammen,

ich habe das Problem bei der Chip - Temperatur - Berechnung meines µC. 
Bisher hatte ich die zur Berechnung notwendigen Kalibrierungswerte stets 
als Konstante fest angelegt. (Variante 1) Da sich diese aber von µC zu 
µC unterscheiden habe ich das umgestellt, indem der µC sich die 
Parameter selber aus den Speicher liest. (Variante 2)

•
1
//#define TL 30                             // Variante 1 
2
                       
3
  #define TL     (CALIBRATION0 & 0XFF)      //Variante 2

Die Inhalte beider Varianten habe ich überprüft, indem ich diese in 
Variablen eingelesen habe. (siehe Bild) Für beide Varianten erhalte ich 
dieselben Werte.

Die eigentliche Temperaturberechnung läuft dann allerdings ohne das 
einlesen in Variablen ab. Hier werden die Konstanten aus Variante 1 oder 
Variante 2 dann direkt genutzt.

•
1
float_Zaehler =  (TL*VPH*ui16_Temperatur_CTAT) - (VPL*TH*ui16_Temperatur_CTAT) - (TL*VCH*ui16_Temperatur_PTAT) + (TH*VCL*ui16_Temperatur_PTAT) ;  //Temperaturberechnung
2

3
float_Nenner =  (VCL*ui16_Temperatur_PTAT)-(VCH*ui16_Temperatur_PTAT)-(VPL*ui16_Temperatur_CTAT) + (VPH*ui16_Temperatur_CTAT) ;
4

5
float_Temperatur = float_Zaehler/float_Nenner;

Die Temperaturberechnung liefert zunächst für beide Varianten dieselben 
Werte. Das ändert sich allerdings, sobald ich die Temperatur mit 
Kältespray auf < 0°C absenke.

Variante 1 liefert das korrekte negative Ergebnis. Variante 2 nicht. Es 
scheint so, als könnte ich mit der Variante 2 keine negativen Ergebnisse 
berechnen.

Dasselbe geschieht, wenn ich für beide Varianten die Konstanten zunächst 
in Variablen hineinschreibe und dann mit diesen Variablen rechne.


Ich würde mich sehr freuen, wenn mir da jmd. ein paar Tips geben könnte.
Angehängte Dateien:
#5686913
Lesenswert?

Wo wird CALIBRATION0 ein Wert zugewiesen bzw. was ist das für ein 
weiteres Makro?
Der Unterschied ist ja dass im zweiten Fall, TL keine Konstante ist, 
sondern genau der Ausdruck dort. Ändert sich CALIBRATION0 nach dem das 
Makro gesetzt wurde, ändert sich auch der efektive Wert von TL.
Gast #5686935
Lesenswert?

Naja doch nicht ganz.

CALIBRATION0 ist der Pointer auf die Speicheradresse, wo die 
Kalibrierungsdaten liegen. Ich hatte den cast auf int32 geändert, 
allerdings ohne Erfolg.

Ich habe das jetzt mit globalen Variablen gelöst. Wo es jetzt wirklich 
gehakt hat, keine Ahnung. Die Lösung ist jetzt aber besser.
Angehängte Dateien:
Moderator #5687067
Lesenswert?

Berechnungen, die sowohl vorzeichenlose als auch vorzeichenbehaftete
Operanden enthalten, sind immer mit etwas Vorsicht zu genießen.

1
#define TL 30                             // Variante 1

TL ist vom Typ int bzw. int32_t, also vorzeichenbehaftet.

1
#define TL     (CALIBRATION0 & 0XFF)      //Variante 2

Hier ist der hinter TL steckende Ausdruck vom Typ uint32_t, also
vorzeichenlos. Damit wird die Berechnung von float_Zaehler in uint32_t
ausgeführt. Ein negatives Ergebnis wird deswegen als der im
Zweierkomplement entsprechende positive Wert interpretiert und ist
damit um 2³² zu groß, was zu einem unsinnigen Gesamtergebnis führt.

1
int32_t TL = 0;

Hier ist TL wieder vorzeichenbehaftet, weswegen das obige Problem
nicht entsteht.

1
TL = (CALIBRATION0 & 0XFF);

(CALIBRATION0 & 0XFF) ist zwar vorzeichenlos, wird aber bei der
Zuweisung an TL in int32_t konvertiert.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren