LM 75 negative Temperature

OP #5140779
Lesenswert?

Guten Tag zusammen,

ich benutze den LM75A und versuche mit Hilfe des Atmega 32 einen 
negativen Temperaturwert auszugeben auf einem LCD Display. Doch leider 
befindet sich in der negativen Berechnung ein Fehler, welchen ich nicht 
finde.

Die positive Temperaturmessung funktioniert.

Hat jemand eine Idee warum es nicht klappt? Lauf dem Datenblatt muss ich 
für negative Werte das Zweierkomplement anwenden und dieses Wert mit 
0,125 multiplizieren. Doch bei -1 Grad Celsius wird mir sofort -7937.000 
Grad auf dem LCD Display angezeigt.

Vielen Dank im Vorraus!






1
#include  <avr/io.h>
2
#define    F_CPU  8000000
3
#include  <util/delay.h>
4
#include  "lcd-routines.h"
5
#include  "i2cmaster.h"
6

7

8

9

10
uint8_t    MSByte_LM75, LSByte_LM75;
11
uint16_t  data_16bit, high_byte, low_byte, tempdata, tempdata_neg;
12
float    fMesswert_LM75, fMesswert_LM75_neg;
13
char    cBuffer_LM75[16], cBuffer_LM75_neg[8];
14
char    temp_min[16], temp_max[16];
15

16

17

18
int main(void)
19
{
20
    
21
    while (1) 
22
 /****Reading in values of temp register LM75  I²C ***/
23
  
24

25
lcd_init();
26
lcd_clear();
27
i2c_init();
28
i2c_start(0x92);      
29
i2c_write(0x00);        
30
i2c_rep_start(0x93);   
31
MSByte_LM75=i2c_readAck();  // Save MSB
32
LSByte_LM75=i2c_readNak();  // Save LSB
33
i2c_stop();    
34
  
35
data_16bit = (MSByte_LM75<< 8) | LSByte_LM75;  
36
tempdata = data_16bit;
37
tempdata = data_16bit >>5;            
38

39
          
40

41
          
42

43
/****negative temperature******/
44

45
if ( MSByte_LM75 & 0x80)  
46
    {  
47
      tempdata_neg = ~ tempdata + 1;      
48

49
      fMesswert_LM75_neg = tempdata_neg;            
50

51
      fMesswert_LM75_neg = fMesswert_LM75_neg *0.125;      
52
              
53
      dtostrf(fMesswert_LM75_neg,5,3,cBuffer_LM75);      
54

55
      lcd_setcursor(0,1);
56
      lcd_string("-");
57
              
58
      lcd_string(cBuffer_LM75);
59
      lcd_string(" ßC IST_Temp");
60

61
} // endif
62

63
else 
64

65
{
66
      fMesswert_LM75 =tempdata;
67
      fMesswert_LM75 = fMesswert_LM75 *0.125;      
68
              
69
      dtostrf(fMesswert_LM75,5,3,cBuffer_LM75);    
70

71
      lcd_setcursor(0,1);
72
              
73
      lcd_string(cBuffer_LM75);
74
      lcd_string(" ßC IST_Temp");
75

76

77

78
}
79

80
     _delay_ms(1000);
81

82

83
    }// end while(1)
84
}// end main
Gast #5140802
Lesenswert?

Der LM75 liefert ein 9-Bit Ergebnis im 2er-Komplement. Nur bezieht sich 
das "2er-Komplement" auf dieses 9-Bit Ergebnis, nicht auf eine 
16-Bit-Zahl. Man muss also nach dem Bilden des 2er-Komplements die nicht 
vorhandenen 7 oberen Bits ausmaskieren.

Aber warum überhaupt so kompliziert? Wenn man das 9-Bit Ergebnis 
*LINKS*bündig als signed int interpretiert und dann nach float 
umwandelt, geht das doch alles automatisch ...
Die ganze Fallunterscheidung ist höchst überflüssig.
OP #5140837
Lesenswert?

A. B. schrieb:
> Der LM75 liefert ein 9-Bit Ergebnis im 2er-Komplement. Nur bezieht sich
> das "2er-Komplement" auf dieses 9-Bit Ergebnis, nicht auf eine
> 16-Bit-Zahl. Man muss also nach dem Bilden des 2er-Komplements die nicht
> vorhandenen 7 oberen Bits ausmaskieren.
>
ich benötige die 11-Bit-Zahl, da ich die negativen Werte auch mit der 
Nachkommazahl angeben möchte. Wie genau kann ich denn die oberen Bits 
ausmaskieren, dass diese nicht mit in die "Berechnung" fallen?
#5140881
Lesenswert?

@ D. R. (misterdimi1992)

>> Der LM75 liefert ein 9-Bit Ergebnis im 2er-Komplement. Nur bezieht sich
>> das "2er-Komplement" auf dieses 9-Bit Ergebnis, nicht auf eine
>> 16-Bit-Zahl. Man muss also nach dem Bilden des 2er-Komplements die nicht
>> vorhandenen 7 oberen Bits ausmaskieren.

Jain, er muss vorzeichenrichtig erweitern, bzw. schieben.

>ich benötige die 11-Bit-Zahl, da ich die negativen Werte auch mit der
>Nachkommazahl angeben möchte. Wie genau kann ich denn die oberen Bits
>ausmaskieren, dass diese nicht mit in die "Berechnung" fallen?

Du musst eine vorzeichenbehaftete Zahl zur Speicherung nutzen. Dann kann 
man auch ohne Hackertricks und kryptische Auswertung damit arbeiten. Und 
mit etwa Know How kann man auch Fließkommazahlen verzichten und mit 
einfacher Festkommaarithmetik arbeiten.
1
#include  <avr/io.h>
2
#define    F_CPU  8000000
3
#include  <util/delay.h>
4
#include  "lcd-routines.h"
5
#include  "i2cmaster.h"
6

7
uint8_t   MSByte_LM75, LSByte_LM75;
8
int16_t   tempdata;
9
char      cBuffer_LM75[16];
10
char      temp_min[16], temp_max[16];
11

12
int main(void) {
13

14
    i2c_init();
15
    lcd_init();
16

17
    while (1) {
18
        /****Reading in values of temp register LM75  I²C ***/
19

20
        i2c_start(0x92);      
21
        i2c_write(0x00);        
22
        i2c_rep_start(0x93);   
23
        MSByte_LM75=i2c_readAck();  // read MSB
24
        LSByte_LM75=i2c_readNak();  // read LSB
25
        i2c_stop();    
26
          
27
        tempdata = MSByte_LM75<< 8) | LSByte_LM75;  
28
        tempdata >>= 7;             // Temperatur mit 0.5 °C Auflösung
29

30
        lcd_clear();        
31
        lcd_setcursor(0,1);      
32
        if ( tempdata < 0) {  
33
            lcd_string("-");
34
            tempdata = -tempdata;             
35
        } else {
36
            lcd_string("+");
37
        }
38
        
39
        // Vorkommastellen      
40
        itoa(tempdata/2,cBuffer_LM75, 10);            
41
        lcd_string(cBuffer_LM75);
42

43
        // Nachkommastelle
44
        if (tempdata & 0x01) {
45
            lcd_string(".5");
46
        } else {
47
            lcd_string(".0");
48
        }
49

50
        _delay_ms(1000);
51
    }
52
}

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