Ich will einen LM75 ansteuern und den Wert über RS232 übertragen.
Als Vorlage habe ich folgendes Programm genommen:
http://www.mikrocontroller.net/attachment/32519/simple_lm75.c
Nur verstehe ich nicht ganz, was da gemacht wird:
whole_number_degrees = lm75_temp >>8;
lm75_temp >>=7;
UDR0 = whole_number_degrees;
Mein Code:
TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN);//read and send ACK
124
TW_BUSY_WAIT();
125
status=TW_STATUS;
126
CHECK_TW_ERROR(TW_MR_DATA_ACK);
127
ret_val=TWDR<<8;//get highbyte
128
129
TWCR=(1<<TWINT)|(1<<TWEN);// read and send NAK
130
TW_BUSY_WAIT();
131
CHECK_TW_ERROR(TW_MR_DATA_NACK);
132
ret_val|=TWDR;//get low-byte
133
TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
134
returnret_val;
135
}
whole_number_degrees ist irgentwie immer 0 und lm75_temp überträgt mir
den Wert 192, welcher auch nicht ganz korrekt sein kann.
In die Abfrage geht er problemlos hinein, dh kein Error.
Vorallem ändert sich der Wert 192 nicht wirklich.
Habt ihr da ein Paar Tipps für mich?
Wenn ich durch 32 dividiere habe ich ja nur 8 mögliche Zahlen ander
kommastelle, also falsch.
Richtig wäre ja 10/256*dat2 oder?
Empfangsystem:
UTIL_uint2str(res, (int)(10/256*RxData) , 1, 1 ); //Kommastellen
Beim Auslesen der Temperatur des LM75 hängt sich der Prozessor auf, wenn
ein Signal über USART reinkommt, versteh das nicht wirklich.
Usart funktioniert Problemlos wenn ich die Zeile auskommentiere:
// temperatur = TWI_empf(ADRESSE_R);
wenn ich sie drinlasse, hängt sich der Prozessor ab und zu auf, wenn
über USART etwas empfangen wird während diesen Befehls.
Ist sehr strange, habt ihr da eine Idee?
Programm:
1
#define F_CPU 16000000UL //Takt 16MHz
2
3
#include<avr/io.h>
4
#include<avr/interrupt.h>
5
#include<util/delay.h>
6
#include<util/twi.h>
7
#include"i2c.h"
8
9
/* Programm Libs */
10
#include"defines.h"
11
12
13
volatileuint8_tIRFlag;
14
volatileuint8_tIR_zaehl=0;
15
volatileuint8_tRxData;
16
17
intmain(void)
18
{
19
/* TIMER INIT */
20
SETBIT(TCCR0,CS00);// Prescaler von 1024 16MHz/1024 = 15,6kHz = 64us
abc schrieb:> Datenblatt:> http://docs-europe.electrocomponents.com/webdocs/0...
Du erzählst die ganze Zeit von LM75 und hast einen LM75A? Ich bin von
9-Bit Auflösung ausgegangen. Deiner hat aber 11.
> temperatur = TWI_empf(ADRESSE_SENSOR3_R); //Für LM75> komma=10/8*(dat2>>5); //Für LM75
komma=10/8*(dat2>>5); ist sinnlos, weil der Compiler das von links nach
rechts rechnet:
Aber das funktioniert auch nur für positive Temperaturen. Der
Temperaturwert ist im 2er-Komplement. Das muss man sich immer vor Augen
halten, wenn man da selber Hand anlegt.
Teste mal folgenden Temperaturwert in deiner Berechnung:
1
/** 111 1111 1111 == -0.125 °C */
2
dat1=0xff;
3
dat2=0xe0;
> temperatur = (TWI_empf(ADRESSE_SENSOR1_R)<<1)|((dat2>>7)); //für LM76> komma=(10*(dat2>>3&0b00001111))/16; //für LM76
Auch das kann nicht für negative Temperaturen funktionieren, weil hier
ebenfalls ein 2er-Komplement verwendet wird.
Gruß Oliver
Ích will nur Temperaturen von ca. 15° bis 35° messen, also sind mir
negative Zahlen ganz egal, danke für den Tipp mit dem >>.
Werde gleich ein Paar Werte testen.
Sorry ich bin selbst davon ausgegangen dass LM75 und LM75A die selben
sind, hab aber immer ins Richtige Datenblatt geschaut.
abc schrieb:> Ích will nur Temperaturen von ca. 15° bis 35° messen, also sind mir> negative Zahlen ganz egal, danke für den Tipp mit dem >>.
[ironie]
Das ist die richtige Einstellung. Weiter so.
[/ironie]
So wirds auch für negative Temperaturen funktionieren:
Hab jetzt:
/* temp_sensor2.temp = TWI_empf(ADRESSE_SENSOR2_R); //Für LM75
temp_sensor2.komma= (dat2>>5)*10/8; //Für LM75 */
in:
TWI_empf(ADRESSE_SENSOR2_R);
temp_sensor2.temp = (dat1<<3) | (dat2>>5);
if (dat1 & (1<<7)) temp_sensor2.temp |= 0xf800; /* restore twos
complement */
temp_sensor2.temp=temp_sensor2.temp*10 / 8;
geändert, aber angezeigt wird jetzt F0 statt 22.
Ich will übrigens komma und temp getrennt haben, da ich die dann per
USART übertrage. Am liebesten wär komma einfach 0-9 und Temp halt die
Temperatur.
Also ich will 8-Bit für Temperatur haben
und
8-Bit für die Kommastelle, wobei ich nur die Kommastelle übertrage.
Das für LM76 und LM75.
Aktueller Code:
abc schrieb:> unsigned char>> Gruß,> abc
Mach mal int16_t draus und der Wert sollte stimmen. Wie sollen auch mehr
als 8 Bit in einen unsigned char passen?
Gruß Oliver
Wie ich vorher schon verscuht habe zu erklären will ich nur 8Bit, da ich
dieses Byte dann per USART übertragen will.
Will die Temperatur übertragen in 1Byte, danach die Kommastellen.
Alles funktioniert bis auf die Kommastellen beim LM76.
gruß,
abc
abc schrieb:> Wie ich vorher schon verscuht habe zu erklären will ich nur 8Bit, da ich> dieses Byte dann per USART übertragen will.
Wenn du meinen Code verwenden willst, dann reichen 8-Bit nicht aus.
Gruß Oliver
Also, wie gesagt in meinem Projekt sind negative Werte nicht nötig, da -
Temperaturen an dem Einsatzort das Ganze Jahr nicht auftreten können.
Ich würde nur gerne wissen wieso dass nicht funktioniert:
temp_sensor1.komma= ((dat2>>3)&0b00001111)*10/16; //für LM76
gruß,
abc
abc schrieb:> Das Problem ist eigentlich dass D3-D6 beim LM76 immer High sind, ist da> der Sensor Kaputt?
Hast du schon mal versucht, den Sensor zu konfigurieren? Der LM75A z.B.
kann zwar 12 bit auflösen, liefert aber per Default nur 9 bit!
HTH
Michael
PS: Sorry, aber wozu gibts eigentlich Datenblätter!?
abc schrieb:> Wie kommst du eignetlich darauf dass der LM75A per Default 9Bit liefert?> Also mir liefert dieser Problemlos 12Bit.
Woher bekommst du das 12te Bit?
Laut Datenblatt (NXP B.V. 2007, 7.4.3) liegen im Temperaturregister
genau 11 Bits (D0..D10). Das deckt sich auch mit den 11 Bit des ADC und
der angegebenen Auflösung von 0.125°C
abc schrieb:> Naja wie auch immer beim LM76 habe ich immer noch keine Lösung gefunden> :(.
Kommunizierst du auch richtig mit dem Sensor? Poste mal für einen Fall
beide gelesenen Bytes vom LM76.
Gruß Oliver
Raumtemperatur ca. 22,5°:
dat1:
0b00001001
dat2>>3:
0b00011111
temp_sensor1.temp= (dat1<<1)|((dat2>>7));
= 22 DEZ
temp_sensor1.komma= ((dat2>>3)&0b00001111)*10/16; //für LM76
= 9 DEZ
Die High bei dat2 sind das Problem.
Übrigens ich frage ca. alle 2 Sekunden die Sensoren ab.
Dat2>>3 ändert sich aber aufjedenfall mit der Temperaturstelle:
0b00011111
0b00001111
je nach dem ob Gerade oder Ungerade Zahl bei der Temperatur. Aber die
anderen 4 Stellen immer High, und das ist das Problem.
Ganz Komischen Phänomen, habe gerade den LM76 direkt beim Controller
angeschlossen, ohne die Anderen Teilnehmer und jetzt zeigt er neben 9
als Kommastelle
0b00001111 auch noch 1 an 0b00000011, aber die anderen Kommastellen
nicht.
Hardware übrigens jetzt 10cm entfernung vom Prozessor, Pull ups 20kOhm.
100nF entstörkondensator beim LM76.
abc schrieb:> Übrigens ich frage ca. alle 2 Sekunden die Sensoren ab.
Das sollte im grünen Bereich sein.
> je nach dem ob Gerade oder Ungerade Zahl bei der Temperatur. Aber die> anderen 4 Stellen immer High, und das ist das Problem.
Sicher das es sich um den selben Sensor handelt, der in dem von dir
verlinkten Datenblatt beschreiben ist? Wie ist die genaue Bezeichnung
auf dem Chipgehäuse des LM76?
Wie schnell betreibst du den I2C-Bus?
Gruß Oliver
Vielen dank,
hab echt keinen Plan warums nicht ging, aber jetz mit anderen Libs
gehts, wahrscheinlich muss man wirklich erst das config register
ansprechen.
abc schrieb:> Also ich hab die Datenblätter schon Gründlich durchsucht, finde keine> Antwort auf meine frage.>> Wie kommst du eignetlich darauf dass der LM75A per Default 9Bit liefert?> Also mir liefert dieser Problemlos 12Bit.
Hattest du geschrieben, um welchen Hersteller es ging?
> http://docs-europe.electrocomponents.com/webdocs/0b4c/0900766b80b4c8ed.pdf
Naja, dann isses wieder was anderes. Ich hatte hier grad ne Doku vom 75A
von Microchip.
Sorry.