Forum: Mikrocontroller und Digitale Elektronik LM 75 negative Temperature


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von D. R. (misterdimi1992)


Bewertung
0 lesenswert
nicht 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

von A. B. (Gast)


Bewertung
0 lesenswert
nicht 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.

von Pete K. (pete77)


Bewertung
0 lesenswert
nicht lesenswert
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();

von D. R. (misterdimi1992)


Bewertung
0 lesenswert
nicht 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?

von D. R. (misterdimi1992)


Bewertung
0 lesenswert
nicht lesenswert
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!

von Falk B. (falk)


Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.