Forum: Mikrocontroller und Digitale Elektronik Ansteuerung LM75 *** Datenformat


von Andreas Ortner (Gast)


Lesenswert?

Hallo!

Ich habe einen LM75 eingesteuert und kann auch die 2 Register für die
Temperatur auch aulesen.
Das Erste Byte (MSB) hat den dezimalen Wert 85
Das Zweite Byte(LSB) hat den dezimalen Wert 255

Der Wert ist 9Bit breit. Der erste Bit sagt aus ob der
temperaturbereich positiv oder negativ ist.
Um den Temperaturwert in einem Byte zu haben schiebe ich die Bits im
ersten Byte 1x nach links.Das wäre 85*2=170 -- das ist 85°C da die
Temperaturaflösung 0,5°C ist. Aber das ist doch falsche Temperatur.Ich
weiß nicht woran es liegt.

Hat da jemand Erfahrung?

Danke!

von Eddi (Gast)


Lesenswert?

Im Datenblatt steht :
Temperature data is represented by a 9-bit, two’s complement word with
an LSB (Least Significant Bit) equal to 0.5°C

Also solltest Du den Wert besser nach rechts schieben, dann passt
es...


Gruss
Eddi

von Andreas Ortner (Gast)


Lesenswert?

Hallo µC Fans,

die Temperatur einzulesen vom LM75 klappt bereits- die Steht bei mir in
einem unsigned char als 8-Bit. Bei 25,5°C have ich im Byte den Wert 51 -
den die Auflösung ist 0,5°C. Um die Temperatur in einer unganzen Zahl
darzustellen (z.B. 25,5) wollte ich den wert in eine float Variable
kopieren und dann durch 2 teilen. Aber es klappt nicht.

Zwei Fehlermöglichlkeiten:

1.Die Typumwandlung funktioniert nicht (value_0 ist unsigned char und
soll in float f_temperat geschrieben werden)
2.Der sprintf(s, "Temperatur= %f",f_temperat); Befehl funktioniert
nicht richtig. Den auf dem Display wird ein String ausgegeben "Integer
only ... -lfp"


Copmiler ist ICC

Mein Code
f_temperat=(float)value_0;
sprintf(s, "Temperatur= %f",f_temperat);
lcd_WR_string(LCD_L4,&s[0]);


für printf Befehl Steht im Handbuch (ich komme damit nicht klar):

int printf(char *fmt, ..)

prints out formatted text according to the format specifiers in the fmt
string. The format specifiers are a subset of the standard formats. The
full conversion specification is:

%[flags]*[width][.precision][l]<conversion character>

The flags are:

#     - alternate form. For the 'x' or 'X' conversion, a 0x or 0X is
generated. For the floating point conversions, a decimal point is
generated even if the floating point value is exactly an integer.

- (minus)  - left align the output

+ (plus)  - add a '+' sign character for positive integer output

' ' (space)  - use space as the sign character for positive integer

0    - pad with zero instead of spaces

The width is either a decimal integer or '*', denoting that the value
is taken from the next argument. The width specifies the minimal number
of characters that will be printed, left or right aligned if needed and
padded with either spaces or zeros, depending on the flag characters.

The precision is preceded by a '.' and is either a decimal integer or
'*', denoting that the value is taken from the next argument. The
precision specifies the minimal number of digits for an integer
conversion, the maximum number of characters for the 's' string
conversion, and the number of digits after the decimal point for the
floating point conversions.

The conversion characters are as follows. If an 'l' (letter el)
appears before an integer conversion character, then the argument is
taken as a long integer.

%d - prints the next argument as a decimal integer

%o - prints the next argument as an unsigned octal integer

%x - prints the next argument as an unsigned hexadecimal integer

%X - the same as %x except that upper case is used for 'A'-'F'

%u - prints the next argument as an unsigned decimal integer

%s - prints the next argument as a C null terminated string

%c - prints the next argument as an ASCII character

%f - prints the next argument as a floating point number in decimal
<aaa>.<bbbb> format

%e, %E - prints the next argument as a floating point number in
scientific notation <a>.<bbb>e<exp> format. %e uses small 'e' and %E
uses capital 'E'

%g, %G - printfs the next argument as a floating point number in either
decimal or scientific notation.

printf is supplied in three versions, depending on your code size and
feature requirements (the more features, the higher the code size):

Basic: only %c, %d, %x, %u, and %s format specifiers without modifiers
are accepted.
  Long: the long modifiers %ld, %lu, %lx are supported, in addition to
the width and precision fields.
  Floating point: all formats including %f for floating point are
supported.

The code size is significantly larger as you progress down the list.
You select the version to use in the Compiler Options dialog box.

printf returns the number of characters printed

von Marcus M. (Gast)


Lesenswert?

Hallo Andreas,

da ich selbst schon öfters mit dem LM75 gebastelt habe, hier ein
kleiner Tip.

Überprüfe, ob die erste Stelle des letzten Bytes gesetzt ist. Dann hast
den folgenden Fall: Temperatur += 0,5°C.

Wie gebe ich das aus?
XXX.Y°C
Ich stelle das reste Byte an die Stelle XXX, indem ich die Zahlen
entsprechend zerlege und anschließend wird die Y Stelle entweder auf
Null oder fünf entsprechend o.g. vorgehen "händisch" gesetzt. Sprich,
Cursor auf die Stelle Y setzen und entweder ne Null (0x48) oder eine
fünf schreiben (0x4d).
So kannst Du Dir das printf und damit auch viel Codeplatz sparen.

Gruß Marcus

PS: Das vorgehen ist wesendlich schneller als eine Floatoperation

von Andreas Ortner (Gast)


Lesenswert?

Danke für den Tip,

ich denke mit diesemVorschlag kann ich leben, aber mir kommt es darauf
an daß ich es "professionell" mache egal ob es viel oder wenig Code
ist. Mein Ziel ist es auch die float-Operationen verarbeiten zu können.

Ganz gerne hätte ich paar Beispiele angeschaut wo mann die flat
Operationen verarbeitet werden mit ICC Compiler.

Jetz habe ich ein i²c-Board gebaut mit Keypad Anschluß, LCD-Anschluß,
Anschluß für leuchtdioden, LM75-Temperatur und natürlich auch ein
RTC-Bausctein mit PCF8573. es ist ein super board geworden- jetz wird
der Code angepaßt. Mein Ziel ist eine universelle Platine für
allgemeine Steuerungen.

Danke

von Zucker (Gast)


Lesenswert?

Hallo,
ich suche eine TWI Routine zum auslesen des LM75 mit einem ATmega16.
Welche Grundeinstellung im TWSR und TWBR verwendet ihr?

von Andreas Ortner (Gast)


Lesenswert?

Damit arbeite ich bisher! Bloß da gibt es paar Klemmer mit der
Umwandlung in float!

Bitte um Vorschläge!

float i2c_LM75_TemperRead (u08 address)
{unsigned int u16_temperature=0;
 u08 value_0,value_1; float f_temperat;
 i2c_start();
 i2c_WR_byte((address<<1));//send address to wr modus
 i2c_WR_byte(0x00);
 i2c_stop();
 delus(2);
 i2c_start();
 i2c_WR_byte((address<<1)|0x01);//send address to rd modus

 value_0=i2c_RD_byteAck();
 value_0<<=1;
 value_1=i2c_RD_byteNak();
 value_1>>=7;
 value_0|=value_1;
 i2c_stop();

 sprintf(s, "Temperat/2=%d",value_0);
 lcd_WR_string(LCD_L3,&s[0]);
 f_temperat=(float)value_0;
 sprintf(s, "f%-%f",f_temperat);
 lcd_WR_string(LCD_L4,&s[0]);
 f_temperat/=2;
 return f_temperat;
}


void i2c_start(void) //1
{TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //make start
 while (!(TWCR & (1<<TWINT))); //wait until start done
 if ((TWSR & 0xF8) != START) {ERROR("startB");} // check start
}

void i2c_WR_byte(unsigned char data)
{
 TWDR = data;
 TWCR = (1<<TWINT) | (1<<TWEN); //Load DATA into TWDR Register. Clear
TWINT bit in TWCR to start transmission of data
 while (!(TWCR & (1<<TWINT)));
 }

u08 i2c_RD_byteAck(void)
 {TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); //Load DATA into TWDR
Register. Clear TWINT bit in TWCR to start transmission of data
  while (!(TWCR & (1<<TWINT)));
  //if ((TWSR & 0xF8) != DAT_TX_ACK_RX){sprintf(s, "er%X",(TWSR &
0xF8));ERROR(&s[0]);}
  return TWDR;
 }

u08 i2c_RD_byteNak(void)
{TWCR |= (1<<TWINT); //start reading by setting TWINT to 1 (clear
TWINT)
 while (!(TWCR & (1<<TWINT)));
 return TWDR;
}

void i2c_stop(void)//@brief Terminates the data transfer and releases
the I2C bus
{
 TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}

von Zucker (Gast)


Lesenswert?

Oh ich seh' gerade das es sich dabei nicht um Assembler handelt. Ich
kann leider nur mit Assembler umgehen. :-(

von Andreas Ortner (Gast)


Lesenswert?

Assembler ist nur für kleine Programme oder bei Zeitechten Programmen.
Es ist meiner Meinung der Schnee von Gestern!

von Zucker (Gast)


Lesenswert?

Klar es ist wesentlich aufwendiger aber man lernt halt mehr dabei. Der
Vorteil liegt darin das man ohne großen Aufwand (ohne eine Hochsprache
zu können) programmieren kann.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.