Berechnungen in C fehlerhaft

#4011504
Lesenswert?

Hallo,
ich versuche ein BMP180 an einem MSP430 mit CCS6 zum Laufen zu bekommen. 
Leider sind die Ergebnisse der Berechnungen völliger Quatsch:

B5 ist definiert als long und abhängig von der Temperatur zur Zeit 3446.
1
long B6;
2
B6 = B5-4000;


B6 = -272302634
#4011579
Lesenswert?

A. K. schrieb:
> foobar schrieb:
>> würde doch a-b unsigned berechnen und anschließend auf signed long
>> casten, oder?
>
> Beim MSP430 ja, aber nicht casten, sondern konvertieren. Nur kommt dabei
> kein -272302634 raus.

Allrdings ist dieses Ergebnis in Hex 0xEFC4FDD6

und das unsigned Ergebnis von 3446 - 4000 macht 0xFDD6

Aufffallend ist, dass das Lower-Word übereinstimmt. Da steckt irgendwo 
ein Datentypfehler im nicht gezeigten Code.
Fazt, und man möchte hinzufügen: eigentlich so wie fast immer, zeig 
deinen ganzen Code und nicht nur die 3 Zeilen, die du für relevant 
hältst Denn wenn dort der Fehler wäre, hättest du ihn (normalerweise) 
längst schon selbst gesehen. Hast du aber nicht. Ergo sizt das Problem 
woanders (ausser das es eigentlich vor der Tastatur sitzt)
#4011617
Lesenswert?

Hier die entsprechenden Funktionen. Bei p kommt mist raus, weshalb ich 
mich auf die Suche gemacht habe.
1
int AC1;
2
int AC2;
3
int AC3;
4
unsigned int AC4;
5
unsigned int AC5;
6
unsigned int AC6;
7
int B1;
8
int B2;
9
int MB;
10
int MC;
11
int MD;
12

13

14
long B5;
15
unsigned long p;
16

17

18

19
void Temp180(void){
20
  unsigned int UT;
21
  long X1;
22
  long X2;
23

24
  UCB0CTL1 = UCSWRST;
25
  UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC;      // I2C master mode
26
  UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
27
  UCB0BR0 = 0x29;                          // < 400 kHz
28
  UCB0I2CSA = 0x77;                       // address
29
  UCB0CTL1 &= ~UCSWRST;
30

31

32
  //write start temperature
33
  UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
34
  while (!(IFG2 & UCB0TXIFG));
35
  UCB0TXBUF = 0xF4;
36
  while (!(IFG2 & UCB0TXIFG));
37
  UCB0TXBUF = 0x2E;
38
  while (!(IFG2 & UCB0TXIFG));
39
  UCB0CTL1 = UCSSEL_2 + UCTXSTP;
40
  while (UCB0CTL1 & UCTXSTP);
41

42
  _delay_cycles(80000);//5 ms
43

44

45
  //go to register
46
  UCB0CTL1 = UCSSEL_2 + UCTR + UCTXSTT; // I2C RX, start condition
47
  while (!(IFG2 & UCB0TXIFG));
48
  UCB0TXBUF = 0xF6;
49
  while (!(IFG2 & UCB0TXIFG));
50

51
  //read register
52
  UCB0CTL1 = UCSSEL_2 + UCTXSTT; // I2C RX, start condition
53
  while (!(IFG2 & UCB0RXIFG));
54
  UT = UCB0RXBUF<<8;
55
  while (!(IFG2 & UCB0RXIFG));
56
  UT += UCB0RXBUF;
57

58

59
  UCB0CTL1 = UCSSEL_2 + UCTXSTP;
60
  while (UCB0CTL1 & UCTXSTP);
61

62
  //Temp
63
  X1 = (((long)UT-AC6)*AC5)>>15;
64

65
  //X3 = MC;
66
  X2 = ((long)MC<<11)/(X1+MD);
67

68
  B5 = X1 + X2;
69

70
}
71

72
void Pres180(){
73
  unsigned long UP;
74
  long X1;
75
  long X2;
76
  long X3;
77
  unsigned long X4;
78
  long B3;
79
  unsigned long B4;
80
  long B6;
81
  unsigned long B7;
82

83

84
  UCB0CTL1 = UCSWRST;
85
  UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC;      // I2C master mode
86
  UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
87
  UCB0BR0 = 0x29;                          // < 400 kHz
88
  UCB0I2CSA = 0x77;                       // address
89
  UCB0CTL1 &= ~UCSWRST;
90

91

92
  //write start pres
93
  UCB0CTL1 = UCSSEL_2 + UCTR + UCTXSTT; // I2C TX, start condition
94
  while (!(IFG2 & UCB0TXIFG));
95
  UCB0TXBUF = 0xF4;
96
  while (!(IFG2 & UCB0TXIFG));
97
  UCB0TXBUF = 0xF4;
98
  while (!(IFG2 & UCB0TXIFG));
99
  UCB0CTL1 = UCSSEL_2 + UCTXSTP;
100
  while (UCB0CTL1 & UCTXSTP);
101
  _delay_cycles(416000);//26 ms
102

103
  //go to register
104
  UCB0CTL1 = UCSSEL_2 + UCTR + UCTXSTT; // I2C RX, start condition
105
  while (!(IFG2 & UCB0TXIFG));
106
  UCB0TXBUF = 0xF6;
107
  while (!(IFG2 & UCB0TXIFG));
108

109
  //read register
110
  UCB0CTL1 = UCSSEL_2 + UCTXSTT; // I2C RX, start condition
111
  while (!(IFG2 & UCB0RXIFG));
112
  UP = UCB0RXBUF;
113
  //blaa[0] = UCB0RXBUF;
114
  while (!(IFG2 & UCB0RXIFG));
115
  UP = (UP<<8) + UCB0RXBUF;
116
  //blaa[1] = UCB0RXBUF;
117
  while (!(IFG2 & UCB0RXIFG));
118
  UP = (UP<<8) + UCB0RXBUF;
119
  //blaa[2] = UCB0RXBUF;
120

121
  UCB0CTL1 = UCSSEL_2 + UCTXSTP;
122
  while (UCB0CTL1 & UCTXSTP);
123

124
  UP = UP>>5;
125

126

127

128

129
  //Pres
130
  B6 = (signed long)(B5)-4000;
131
  X1 = (((B6*B6)>>12)*B2)>>11;
132
  X2 = (AC2*B6)>>11;
133
  X3 = X1 + X2;
134
  B3 = (((((long)AC1<<2)+X3)<<3)+2)>>2;
135
  X1 = (AC3*B6)>>13;
136
  X2 = (((B6*B6)>>12)*B1)>>16;
137
  X3 = (X1 + X2 + 2)>>4;
138

139
  if ((X3 + 32768) < 0){X4 = ~(X3 + 32767);}
140
  else{X4 = X3 + 32768;}
141
  B4 = (AC4*X4)>>15;
142
  B7 = (UP-B3)*(50000>>3);
143
  if (B7 < 0x80000000){p = (B7<<1)/B4;}
144
  else{p = (B7/B4)<<1;}
145
  X1 = (p>>8)*(p>>8);
146
  X1 = (X1*3038)>>16;
147
  X2 = (7357*p)>>16;
148
  p = p + (X1 - X2 + 3791)<<4;
149

150

151

152

153
}
#4011711
Lesenswert?

H. D. schrieb:
> Mark Brandis schrieb:
>> Die Variablennamen sind wirklich zum Abgewöhnen :-(
>
> Übernomen aus dem Datasheet ...
>
> Joachim B. schrieb:
>> B6 ist long B5 ist long also sollte doch das hier reichen:
>>
>> B6 = B5-4000L;
>
> keine Wirkung:
>
> B5 = 3324;
> --> B6 = -1392181924

wo hast du den Wert her?
Machst du eine Ausgabe oder bist du in irgendeinem Debugger?
(Hintergrund: Mit diesen Zahlen sieht das so aus, als ob im High-Word 
Schmutz wäre. Das soll es bei Debuggern schon gegeben haben, dass sie 
mit manchen Datentypen nicht zurecht gekommen sind. Letzten Endes sind 
die tatsächlich in B6 vorhandenen Bytes wichtig.)
#4011977
Lesenswert?

Karl Heinz schrieb:
> Nur um sicher zu gehen.
> Kannst du mal ein neues Projekt aufsetzen, in dem tatsächlich nur diese
> Berechnung
>
1
> long B6;
2
> B6 = B5-4000;
3
>
> drinn ist (natürlich mit den entsprechenden Variablen und Datentypen wie
> in deinem Projekt) uns sonst nichts anderes?
> Hast du dort dasselbe fehlerhafte Ergebnis?

Geht nicht, weil er das wegoptimiert.


Ergänze ich die Funktion von oben durch:
1
  long T5 = 3333;
2
  long T6;
3

4
  T6 = T5 - 4000;
5

6
  B1 = T6;

T5 = -667;
T6 = 1014431077;

Das Ding will mich doch verarschen!

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