LM 75 negative Temperature

OP #5140779
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
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
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?
OP
Pete K. schrieb:
> Das #define    F_CPU  8000000 gehört in das Makefile.
>
> Und hier fehlt eine Klammer auf "{" nach while:
> int main(void)
> {
>
>     while (1)
>  /****Reading in values of temp register LM75  I²C ***/
>
>
> lcd_init();

Habe beim Einfügen des Textes die Kommentare gelöscht. Habe wohl die von 
dir erwähnte Klammer beim löschen erwischt!

Aber danke!
@ 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

Eine eigene Frage? Dieser Thread ist über 9 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.