Problem mit Casts von Datentypen

OP #2745949
Hallo!
Ich möchte für meinen ATXmega eine Funktion schreiben, die den Wert des 
internen Temperatursensors in °C umwandelt:
1
int8_t calcTemperature(void)
2
{
3
  return (((uint16_t)((ADCA_CH1_RES * (uint32_t)tempCalcCoeff)>>13)) - 273);
4
}
Wenn ich nun das disassembler anschaue, sehe ich, dass vom Wert in 
Kelvin nur 0x11 und nicht 0x111 (=273) abgezogen werden:
1
return (((uint16_t)((ADCA_CH1_RES * (uint32_t)tempCalcCoeff)>>13)) - 273);
2
00000124  LDS R18,0x022C    Load direct from data space 
3
00000126  LDS R19,0x022D    Load direct from data space 
4
00000128  LDS R22,0x2001    Load direct from data space 
5
0000012A  LDS R23,0x2002    Load direct from data space 
6
0000012C  LDI R24,0x00    Load immediate 
7
0000012D  LDI R25,0x00    Load immediate 
8
0000012E  LDI R20,0x00    Load immediate 
9
0000012F  LDI R21,0x00    Load immediate 
10
00000130  CALL 0x0000024E    Call subroutine 
11
00000132  MOVW R26,R24    Copy register pair 
12
00000133  MOVW R24,R22    Copy register pair 
13
00000134  LDI R18,0x0D    Load immediate 
14
00000135  LSR R27    Logical shift right 
15
00000136  ROR R26    Rotate right through carry 
16
00000137  ROR R25    Rotate right through carry 
17
00000138  ROR R24    Rotate right through carry 
18
00000139  DEC R18    Decrement 
19
0000013A  BRNE PC-0x05    Branch if not equal 
20
}
21
0000013B  SUBI R24,0x11    Subtract immediate 
22
0000013C  RET     Subroutine return
Ich habe schon alle möglichen Varianten mit typen-cast ausprobiert, aber 
es hat alles nichts gebracht.
Könnt ihr mir helfen?
Vielen Dank!
Erdbewohner
Gast
Raphael F. schrieb:
> Wenn ich nun das disassembler anschaue, sehe ich, dass vom Wert in
> Kelvin nur 0x11 und nicht 0x111 (=273) abgezogen werden:

273-256 = 0x11

die 0x11 ist also richtig für das low-byte.

Ich würde die rechenschritte mal einzeln machen.

uint16_t tmp = (ADCA_CH1_RES * (uint32_t)tempCalcCoeff)>>13;
tmp -= 273;
return tmp;

wie gross ist denn ADCA_CH1_RES?
> int8_t calcTemperature(void)
  ******

Ich denke hier liegt das "Problem".

Ob du nur vom Lowbyte 0x11 abziehst, oder von einem unsigned 16 Bit 
Ergebnis 0x0111 ist ziemlich irrelevant, wenn du dann sowieso vom 
Ergebnis das High_byte verwirfst und das ganze danach als eine Zahl mit 
Vorzeichen verkaufst.
OP
Arrrrrggg!!
Natürlich!
Meine Überlegung war, dass der Wert in Kelvin ja noch grösser als 128 
ist, und dass darum auch 273 und nicht nur 17 abgezogen werden sollten. 
Aber wenn man das High Byte weglässt und annimmt, dass es 1 ist (sonst 
geht es sowieso nicht), geht es natürlich.
Vielen Dank!
Gast
Raphael F. schrieb:
> return (((uint16_t)((ADCA_CH1_RES * (uint32_t)tempCalcCoeff)>>13)) - 273);

Bei solchen Zeilen wird mir schlecht. Schreib dein Zeugs doch besser 
einzeln und nicht in einem Klumpen.

long temp;

temp = ADCA_CH1_RES * tempCalcCoeff;
if (temp>blabla) temp = blabla;  // Sättigung ist besser als Abhacken
temp = temp>>13;
return temp;

Bei einem einigermaßen vernünftigen Compiler kommt damit ein optimaler 
Code heraus, weil temp sowieso in einem Register gehalten wird. Es ist 
also überhaupt kein Grund vorhanden, mit Typecasts um sich zu schmeißen.

Merke: Typecasts sollten die Ausnahme sein, nicht die Regel. Wenn 
jemand für jeden Furz einen Typecast braucht, dann macht er etwas 
gründlich falsch.

W.S.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.