Hallo zusammen,
ich arbeite mich ganz langsam in die Programmierung von einem MSP430 ein
und setzte meine Ziele langsam immer höher. Jetzt möchte ich gerne einen
Temperaturfühler LM75 auslesen.
Ich möchte dabei keinen Interrupt benutzen, weil ich die Sache mit den
Interrupts einfach noch nicht kapiere.
Als Compiler benutze ich den IAR Freeware.
Ich habe mich auch schon durch den User guide und das Datenblatt von dem
LM75 gekämpft. Leider ist mein Englisch nicht das allerbeste, deshalb
habe ich einige Verständnisprobleme.
Trozdem will ich noch nicht aufgeben.
Ich habe an meine Testplatine einen LM75 mit der Adresse 1001100 mit
einem ca. 2m langem Kabel angeschlossen. Die beiden Pullup Widerstände
haben einen Wert von 10k. Ausgeben will ich den Messwert auf eine
7-Segmentanzeige.
Ich habe mich beim Programmieren an einem Beispiel von Texas Instruments
gehängt, habe aber die Interrupt Routine entfernt.
Bitte hängt mich nicht gleich auf wenn ihr meinen Code seht, den ich
zähle mich noch zu den Anfängern.
Ach ja, den Zahlenwert den der LM75 ausgeben soll habe ich noch nicht so
gewandelt, das da ein vernünftiger Temperaturwert heraus kommt. Ich will
ja erst mal sehen ob überhaupt was rauskommt. Denn bisher steht im
I2CDRB immer nur 00 drin.
Ich hoffe ihr könnt mir helfen.
Danke
Markus
Hallo,
ich kenne leider das I2C-Handling vom MSP430 nicht.
Aber, du musst 2 Bytes auslesen. Das erste Byte ist bei ~25°C immer
0x00.
Du musst 2 Bytes innerhalb einer I2C-Transmission auslesen.
Ich kann leider nicht erkennen welche Baudrate du eingestellt hast. 2m
sind schon relativ weit für I2C bei hohen Baudraten.
Hi MichiB,
erst mal Danke für deine Antwort. Ich habe in meinem Programm die Bytes
auf 2 gesetzt, mit:
U0CTL |= I2C + SYNC; // Switch USART0 to I2C mode
U0CTL &= ~I2CEN; // Recommended I2C init procedure
I2CTCTL = I2CSSEL_2; // SMCLK
I2CSCLH = 0x03; // High period of SCL
I2CSCLL = 0x03; // Low period of SCL
I2CNDAT = 0x02; // Transmit two byte
I2CSA = 0x4c; // Slave address 1001100
U0CTL |= I2CEN; // Enable I2C, 7 bit addr,
leider ist das Ergebnis das Gleiche.
Werden beide übertragene Bytes im I2CDRB gespeichert oder gibt es für
jedes Byte ein extra Register?
Die Baudrate weiss ich leider auch nicht. Das habe ich einfach aus dem
Beispiel von TI Übernommen und gehofft dass es passt. Denn ich habe
gelesen, dass es bei der Baudrate nicht so genau drauf ankommt.n Ich
hoffe das war kein Fehler.
Markus
Markus S. schrieb:> Werden beide übertragene Bytes im I2CDRB gespeichert oder gibt es für> jedes Byte ein extra Register?
Die landen nacheinander in diesem Register.
Du solltest Dir mal die Codebeispiele von TI ansehen, da sind auch
mehrere dabei, die die I2C-Schnittstelle des 'F1611 betreffen.
@Joachim
weil die Temperaturauslesung in einer Enlosschleife läuft, und ich
gelesen habe das der LM75 nur ca. 10 Messungen pro Sekunde schafft,
dachte ich, ich gebe ihm etwas Zeit. Zumal ich es mit dem Messen nicht
eilig habe.
:o)
Markus
Hallo
Ich dachte mir, daß das eine Wartezeit sein soll. Aaaaaber: Viele
Compiler denken sich, was soll denn das werden? Da passiert ja nichts
außer das eine Variable hochgezählt wird, und dann wirdse garnicht
mehr gebraucht. Also weg mit der ganzen for-Schleife.
Es kann also sein, wenn dein Compiler dazugehört, das die komplette
Schleife einfach rausgeschmissen wird.
Hast du für deinen Compiler keine delay-Funktion? Ist irgendwie
sicherer und man weiß dann auch exakt, wie lange gewartet wird.
Gruß
Joachim
Hi,
leider verstehe ich das TI Beispiel nicht ohne das Datenblatt im Detail
gelesen zu haben.
Allerdings habe ich im Beispiel gelesen:
// ACLK = n/a, MCLK = SMCLK = TACLK = I2CCLOCK = DCO~ 800k
800k sind meiner Erfahrung nach viel zu viel für 2m.
Mach die Leitung mal so kurz wie möglich.
man ihr ja der Wahnsinn,
ich komme mit dem schreiben gar nicht so schnell nach. :o))
@Rufus
vielen Dank für die Beispiele. Ich habe mal kurz reingschaut und ein
paar überflogen. Es wird dort natürlich auch sehr viel mit Interrupts
gearbeitet (was ich ja noch vermeiden will). Aber ich habe auch ein paar
Beispiele gefunden wo drei Bytes übertragen werde. Aber den Ablauf der
da verwendet wird den muß ich erst mal verdauen und verstehen.
Aber trozdem vielen Dank für deine Hilfe.
@Joachim
bislang habe die for Schleifen sehr gut funktioniert und wurden nie
rausgeschmissen.
Das mit der delay-Funktion muß ich mir mal ansehen ob ich da was finde.
Vielen Dank für den Tip
Markus
@MichiB
ok, das mit der kürzeren Leitung werde ich ausprobieren. Aber wenn ich
dich richtig verstehe, kann ich auch die Frequenz runter setzen oder?
Ich weiß noch nicht genau wie das geht aber so viel ich weiß kann man ja
einen Vorteiler setzten. Denn ich möchte irgendwann mal längere Kabel
einsetzen (wenn das geht).
Gibt es eine Berechnung, Regel oder Fausformel wie man die Kabellänge
mit der Übertragungsfrequenz abstimmt?
Markus
XXX schrieb:> Ich dachte mir, daß das eine Wartezeit sein soll. Aaaaaber: Viele> Compiler denken sich, was soll denn das werden? Da passiert ja nichts> außer das eine Variable hochgezählt wird, und dann wirdse garnicht> mehr gebraucht. Also weg mit der ganzen for-Schleife.
Der IAR steht von Hause aus auf "Optimization" "None". D.h. er optimiert
überhaupt nichts weg. Von daher geht das mit der Schleife problemlos.
Ich hoffe du machts auch noch ein wenig an der Temperatur
und das ist nur ein vereinfachtes Beispiel.
1
unsignedintZahl=I2CDRB;//Temperaturwert an Variable Übergeben
denn soweit ich das im Datenblatt sehe sind die 5 niederwertigsten bits
immer 0, die solltest du also durch shiften oder ähnliches los werden
außerdem ist deine Zahl unsigned soweit ich das sehe ist MSB high ein
Hinweis das die Temp negativ ist und du ein 2 Kompliment bilden musst.
was du in denn Beispiel mist sind Mond Zahlen und keine Temperatur.
das du 2 Bit lesen musst haben dir schon andere gesagt. leider hatte ich
mit dein Prozessor noch nicht zu tun so das ich dir da keine Hinweise
geben kann wie das geht.
Hi ich habe das ganze noch um die Temperatur Berechnug ergänzt
lmreg ist ein unsignend short , temp ein double oder float in denn
folgenden Beispiel. gegebenfalls wäre es sinnvol das double gegen ein
int auszutauschen, in tausensdel grad zu rechnen und bei deiner ausgabe
den Dezimal Punkt manuell zu setzen.
1
I2CNDAT=0x02;// Transmit 2 bytes
2
3
for(;;)
4
{
5
U0CTL|=MST;// Master
6
I2CTCTL=I2CSTT+I2CSTP;// Initiate transfer
7
while((I2CIFG&RXRDYIFG)==0);// Wait for Receiver to be ready
8
i1=I2CDRB;// Receive MSByte from DAC
9
while((I2CIFG&RXRDYIFG)==0);// Wait for Receiver to be ready
10
i2=I2CDRB;// Receive ControlByte from DAC
11
while((I2CTCTL&I2CSTP)==0x02);// Wait for Stop Condition
12
13
lmreg=((i1&0xFFUL)<<8)|(i2&0xFFUL);// build ushort value
14
lmreg>>=5;// Remove unneeded 0 Bytes
15
16
if(lmreg&(1<<10)){
17
// Temp less 0°C
18
lmreg=~lmreg&0x01FFUL;// 1 compliment of 9 bit value
Imon schrieb:> gegebenfalls wäre es sinnvol [...] in tausensdel grad zu rechnen
Definitiv nicht. Es ist bereits ein nur selten erreichtes Kunststück,
die Temperatur auf 0.1° genau zu messen, wirklich sinnvoll ist bei den
meisten elektronischen Messverfahren eine Rundung auf ganze 0.5°- oder
gar ganze 1°-Schritte.
Die 0.1°-Anzeige der meisten elektronischen Thermometer ist schlichtweg
gelogen.
@Imon,
ich hatte ja oben schon geschrieben dass ich den Wert von dem
Temperaturfühler noch umwandeln muß. Dass du das jetzt schon gemacht
hast, ist super klasse!! Vielen Dank dafür.
@MichiB
Danke für das Beispiel. Genau das hatte ich mir auch schon rausgesucht,
aber ich hatte bislang noch keine Zeit es auszuprobieren.
@Rufus
das mit der Nachkommastelle bei der Temperatur ist für mich kein
Problem. Ich brauche nur die Stellen vor dem Komma das reicht mir völlig
aus
Vielen Dank noch mal für Eure Hilfe
Markus
Hi zusammen,
ich habe mal den Programvorschlag von MichiB und Imon getestet. Hat
leider nicht funktioniert.
Das lange Kabel zu meinem Temeraturfühler habe ich auf 10cm gekürzt.
Um zu testen wie weit das Programm überhaupt kommt, habe ich mal an
verschiedenen Stellen einen Ausgang (an denen je eine LED angeschlossen
ist) Programmiert.
POUT1=0x01; //LED 1
for (;;)
{
U0CTL |= MST; // Master
POUT1=0x02; //LED 2
I2CTCTL = I2CSTT+I2CSTP; // Initiate transfer
while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be ready
POUT1=0x04; //LED 3
i1 = I2CDRB; // Receive MSByte from DAC
while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be ready
i2 = I2CDRB; // Receive ControlByte from DAC
while ((I2CTCTL & I2CSTP) == 0x02); // Wait for Stop Condition
}
LED3 leuchtet leider nicht. Das heißt das Programm kommt nicht aus der
while Schleife (while ((I2CIFG & RXRDYIFG) == 0);) heraus.
Ich habe daraufhin noch mal die Anschlüsse an meinem LM75 überprüft.
Ich habe die Adresse Überprüft d.h. ich habe an den A0 bis A2 gemessen
ob die Anschlüsse richtig angelötet sind. Aber das ist alles ok.
Dann habe ich versucht das SCL Signal mit einem Oscilloscope zu messen.
Das Ergebnis ist schwer zu beschreiben. Es war ein high Signal von 1.5V
mit schmalen Impulsen zu low. Die Pulsabstände waren 10ms. Dieses Signal
hatte ich auf SCL und SDA.
Kann jemand damit etwas anfangen?
Markus
Hallo Leute,
verzeiht mir meine Dämlichkeit.
Ich habe meinen Fehler gefunden. Ich habe bei der Adresse des LM75 die
Reihenfolge A0 bis A2 vertauscht. Die Adresse von meinem Fühler ist
1001001 und nicht 1001100. Und siehe da es kommt was zurück. Jetzt
versuche ich das Ergebnis zu wandeln und auf meine 7-Segment Anzeige
auszugeben.
Sollte ich damit noch Probleme haben, dann melde ich mich noch mal.
Markus
>Es ist bereits ein nur selten erreichtes Kunststück,>die Temperatur auf 0.1° genau zu messen, wirklich sinnvoll ist bei den>meisten elektronischen Messverfahren eine Rundung auf ganze 0.5°- oder>gar ganze 1°-Schritte.
Da hast Du schon Recht. Man muss immer den Messwert beurteilen, wie viel
Stellen nach oder auch vor dem Komma brauchbar sind.
Aber um einen Trend erkennen zu können, kann man auch die 0,1° Stelle
gut verwenden. Deshalb alle Stellen anzeigen, und danach beurteilen.
MfG
Hallo zusammen,
ich habe gestern verzweifelt versucht meinen LM75 auszulesen und den
Messwert über die UART Schnittstelle auf dem PC auszugeben.
Hat natürlich nicht geklappt.
Nach stundenlangen versuchen bin ich zu dem Entschluss gekommen das mit
dem Auslesen des LM75 irgend was nicht stimmt.
for (;;)
{
U0CTL |= MST; // Master
POUT1=0x02; //LED 2
I2CTCTL = I2CSTT+I2CSTP; // Initiate transfer
while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be ready
i = I2CDRB; // Receive MSByte from LM75
i = i << 8;
highbyte = I2CDRB;
while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be ready
i = i + I2CDRB; // Receive ControlByte from LM75
lowbyte = I2CDRB;
while ((I2CTCTL & I2CSTP) == 0x02); // Wait for Stop Condition
i= i/2;
i per UART auf PC schicken
}
Zahlen auf dem PC schicken funktioniert super. Habe ich ausreichend
getestet.
Ich habe die einzelnen Bytes (low und high) zum Testen einzeln
ausgelesen und auf dem PC ausgegeben, aber leider machen die Zahlen die
da rauskommen überhaut keinen Sinn. Teilweise kommen auch nur
Hieroglyphen.
nach dem Datenblatt von dem LM75 wird eine 9 Bit breite Zahl ausgegeben.
Teilt der LM75 diese automatisch in zwei 8 Bit Signale auf und schickt
die? Dann müsste das eine Bit (high) ja immer Null anzeigen solange ich
einen positiven Temperaturwert messe. Ist das so? oder habe ich das
System total falsch verstanden?
@Imon,
ich habe versucht deine Auswertung zu verstehen. Leider ist es mir nicht
gelungen.
Was heißt 0xFFUL?
Das verschieben der Stellen um 8 Positionen nach links verstehe ich auch
noch, aber wieso schiebst du um 5 Stellen nach rechts?
Und warum multipizierst du dem Messwert mit 0.125?
Ich hätte den Wert durch 2 geteilt.
lmreg= ( (i1 & 0xFFUL) << 8 ) | ( i2 & 0xFFUL) ; // build ushort value
lmreg >>= 5; // Remove unneeded 0 Bytes
if ( lmreg & ( 1 << 10 ) ) {
// Temp less 0°C
lmreg = ~lmreg & 0x01FFUL ; // 1 compliment of 9 bit value
lmreg++; // 2 compliment
temp = lmreg * -0.125; // calculate Temp in degree
}
else {
temp = lmreg * 0.125; // calculate Temp in degree
Markus
Markus S. schrieb:> nach dem Datenblatt von dem LM75 wird eine 9 Bit breite Zahl ausgegeben.> Teilt der LM75 diese automatisch in zwei 8 Bit Signale auf und schickt> die?
Ja
> Dann müsste das eine Bit (high) ja immer Null anzeigen solange ich> einen positiven Temperaturwert messe. Ist das so?
Wenn du das MSB meinst, ja.
>Und warum multipizierst du dem Messwert mit 0.125?
Imon scheint einem LM75A zu haben, der hat eine größere Auflösung wie
der "normale" LM75. Bei dem ist im Low Byte noch Bit 6 und 5 definiert.
Hallo Jörg,
>> Dann müsste das eine Bit (high) ja immer Null anzeigen solange ich>> einen positiven Temperaturwert messe. Ist das so?>Wenn du das MSB meinst, ja.
Was heißt MSB?
Leider habe ich bei dem highbyte nicht Null als Ergebnis sondern,
Zahlenwerte. Das verstehe ich leider nicht.
Danke
Markus
Hallo,
ich war in letzter Zeit sehr mit anderen Dingen beschäftigt. Aber jetzt
soll es wieder mit Hochdruck weiter gehen.
Leider hat sich mein Problem nicht geändert. Hat noch jemand einen Tip
für mich?
Danke
Markus
Markus S. schrieb:> @Imon,> ich habe versucht deine Auswertung zu verstehen. Leider ist es mir nicht> gelungen.> Was heißt 0xFFUL?
das beutetet ich will die Konstante 0xFF als unsigned long (UL) haben,
damit gebe ich den Kompiler einen Hinweiss wie breit die Konstante ist
um nicht ggf mit Schmutz effekten zu rechen ist also wie
0x00000000000000FF nur leichter zu schreiben.
> Das verschieben der Stellen um 8 Positionen nach links verstehe ich auch> noch, aber wieso schiebst du um 5 Stellen nach rechts?
weil das Datenblatt sagt die unteren 5 Bits sind 0 die brauche ich also
nicht und will sie los werden sonst muss ich sie in der Rechnung
berücksichtigen.
> Und warum multipizierst du dem Messwert mit 0.125?> Ich hätte den Wert durch 2 geteilt.
weil das so in denn Datenblatt steht das ich hatte. Ich habe das ganze
nach den NXP Datenblatt für den LM75B entwickelt dort steht die Formel
drin
www.nxp.com/documents/data_sheet/LM75B.pdf
wobei wenn ich den LM75B mit den Ausschnitt vergleiche den Jörg S.
gepostet hat, musst du Tatsächlich um 6 Bits schieben (statt der 5) und
durch 2 Teilen.Der LM75B scheint eine gering höhere Auflösung zu haben
als der LM75.
>>> lmreg= ( (i1 & 0xFFUL) << 8 ) | ( i2 & 0xFFUL) ; // build ushort value> lmreg >>= 5; // Remove unneeded 0 Bytes>> if ( lmreg & ( 1 << 10 ) ) {> // Temp less 0°C> lmreg = ~lmreg & 0x01FFUL ; // 1 compliment of 9 bit value> lmreg++; // 2 compliment> temp = lmreg * -0.125; // calculate Temp in degree> }> else {> temp = lmreg * 0.125; // calculate Temp in degree>>> Markus
Herlichen Dank euch beiden,
das hilft mir erst mal wieder weiter. Zumindest kann ich jetzt erst mal
weiter probieren.
@Jörg,
da ich die Nachkommastelle sowieso nicht brauche, müsste es doch
reichen, wenn ich das High-Byte auslese. Oder ist das Falsch?
@Imon,
>das beutetet ich will die Konstante 0xFF als unsigned long (UL) haben,>damit gebe ich den Kompiler einen Hinweiss wie breit die Konstante ist>um nicht ggf mit Schmutz effekten zu rechen ist also wie>0x00000000000000FF nur leichter zu schreiben.
Das ist sehr interessant. Wo kann man so etwas nachlesen? Sind das
Grundkenndnisse der C-Programmierung? Oder ist das speziell beim MSP
(oder auch bei anderen µC) so?
Danke
Markus
Nur das High Byte auslesen geht meines wissens nicht. Wenn du eine
anfrage schickst, dann werden über den i2c bus aufjedenfall das High und
low Byte verwendet.
Du kannst auf der µC Seite aber nur das High Byte auswerten.
(Ich hab jetzt nicht alles durchgelesen, aber ich habe oben irgendwas
von 0,1°C gelesen. Das LSB hat meines wissens nur die Wertigkeit x,0
oder x,5)
Wahrscheinlich ist das aber schon gelöst, weil ich hab beim
runterscrollen iwo das Datenblatt gesehen ;)
Grüße Tom
Tom A. schrieb:> Nur das High Byte auslesen geht meines wissens nicht. Wenn du eine> anfrage schickst, dann werden über den i2c bus aufjedenfall das High und> low Byte verwendet.
Der LM75 ist ja nur Slave. Wenn der Master nach dem ersten Byte ein
Stop/NAK sendet kann der LM ja nichts weiter senden :)
ja gut, das ist richtig. Ist halt die Frage ob das der aufwand wert ist
oder ob man die Daten halt verwirft ;)
Kommt halt immer auf die Anforderungen drauf an. In meinem Fall hat es
ausgereicht die Daten zu verwerfen :D
Tom A. schrieb:> Kommt halt immer auf die Anforderungen drauf an. In meinem Fall hat es> ausgereicht die Daten zu verwerfen :D
Wenn man sich überlegt, dass der LM75 in allen seiner Ausführungen nur
auf 2 bis 3 Kelvin genau ist, macht es nur Sinn, das Lowbyte
auszuwerten, wenn man das Quantisierungsrauschen klein halten will (z.B.
für eine Temperaturregelung). Für ne einfache Temperaturmessung mit
Anzeige, ist das Highbyte mehr als ausreichend.
Gruß Skriptkiddy
Markus S. schrieb:> Das ist sehr interessant. Wo kann man so etwas nachlesen? Sind das> Grundkenndnisse der C-Programmierung? Oder ist das speziell beim MSP> (oder auch bei anderen µC) so?
das sind grundlagen der Sprache C sollte irgendwo im ISO9899:1990
aufgeführt sein (Hoffe ich ), denn um ehrlich zu sein weiss ich garnicht
mehr genau wo ich mir das abgeschaut habe, aber es ist allgemein
gültiges C und Grade bei Bitopertationen habe ich mir schon ein paar mal
ins Knie geschossen weil die
Konstanten zu klein gewählt habe.
Hallo zusammen,
ich denke das mit dem Auslesen von den Bits habe ich dank eurer Hilfe
jetzt im Griff bekommen. Durch Bitverschiebung habe ich auch
herausgefunden wie ich das Bit für die Nachkommastelle wegbekomme. Dann
habe ich auch mal nur das Highbyte ausgewertet. Das Ergebnis war das
gleiche. Nämlich das die Zahlenwerte nicht stimmen können.
Denn wenn ich das ausgelesene Highbit durch 2 teile, dann schwankt die
Temperatur zwischen 9 und 7 Grad C. Bei einer Raumtemperatur um die 23
Grad (gemessen mit einem anderen Thermometer).
Muss man den LM75 vorher doch noch irgendwie programmieren (abgleichen)?
Ist das normal das die Ausgegebene Temperatur dauernd um 3 Grad schwankt
(ich lese jede Sekunden einen Wert aus)
Danke für eure Hilfe
Markus
>Denn wenn ich das ausgelesene Highbit durch 2 teile
Wozu das? Das brauchst du nur wenn du die 0,5° noch in das Ergebnis
"hineingeschoben" hast. Das high-Byte für sich allein ist genau der
Temperaturwert den du haben willst.
Hallo zusammen,
da ich nach langem herumprobieren nicht herausbekommen habe, warum der
LM75 eine zur niedriegere Temparatur ausgibt habe ich den Wert einfach
mit 1,25 multipliziert und damit funktioniert es ganz gut. wenn jemand
noch einen besseren Tip hat, würde ich mich sehr darüber freuen.
Das schwanker der Temperatur konnte ich etwas reduzieren in dem ich 10
Werte ermittelt habe und daraus den Mittelwert gebildet habe.
Nochmal danke für eure Hilfe
Markus
Warum schwankt sie den so. Also mein LM ist auch etwas launisch und gibt
je nach Tagesverfassung ein wenig einen unterschiedlichen Wert aus.
Wie oben schon von jmd. gesagt und wie es auch aufm Datenblatt auf der
ersten Seite steht ist der Fehler des Sensors max. +-3 bzw +-2 Grad.
Ich weiß nicht ob man dann von einem Offset reden kann und denn einfach
mit einem Faktor ausgleichen kann.
Bei mir ist der Fehler ehr gleichverteilt und schwankt um die
Raumtemperatur.
Grüße Tom
Mein LM75 schwankt nicht. Da springt höchtens das letzte Bit mal.
Bist du sicher das kein NAK zurück kommt?
Wie sehen die Werte denn jetzt aus (in HEX)?
Was sendest du genau zum Sensor?
Hallo Tom und Jörg,
ich bin immer noch am verzweifeln. Ich kriege das Problem mit dem
Temperaturauslesen einfach nicht in den Griff.
Ich hatte zwischendurch mal gedacht es funktioniert, aber das war ein
Fehler.
Ich lese bei den LM75 nur noch das Highbyte aus. Die Zahlenwerte waren
zu tief. Dashalb habe ich sie mit dem Faktor 1,25 multipliziert. Das war
dann so weit in Ordung aber die Werte habe immer noch geschwankt. Ich
habe die Werte in einer for Schleife 32 mal ausgelesen und das mit Hilfe
von >> 5 durch 32 dividiert.
Die ganze Messung und die Ausgabe läuft in einer Enlosschleife. Am Ende
der Schleife habe ich noch eine Wartezeit von ca. einer Sekunde
eingebaut so das ich jede Sekunde einen neuen Messwert bekommen. Aber
der Wert wechselt bei Raumtemperatur pro Sekunde zwischen 14 und 19 Grad
und das sehr regelmäßig.
Dann habe ich versucht dass der LM75 dauernd Werte misst aber ich nur
ca. jede Sekunde den Wert anzeigen lasse. Da war der angezeigte Wert
stabil bei 18 Grad aber er hat sich auch nicht geändert wenn ich den
Fühler an meiner Heizung erhitzt habe.
Dann habe ich einen zweiten LM75 an die Busleitung geklemmt. Der
schwankt noch schlimmer (zwischen -13 und 11 Grad) und das sehr
unregelmäßig, obwohl er über die selbe Funktion ausgelesen wird wie der
erste Fühler.
Ich habe schon so viel probiert und umgeklemmt, aber leider kein
positives Ergebnis erhalten.
Denn ich nehme an, wenn ich einen Hardware Fehler hätte, dann dürften
doch eigenlich gar keine Werte aus dem LM75 kommen oder?
Jörg schrieb:
>Bist du sicher das kein NAK zurück kommt?>Wie sehen die Werte denn jetzt aus (in HEX)?>Was sendest du genau zum Sensor?
wie kann ich rausfinden ob ein NAK zurückkommt?
Wie die Werte in HEX aussehen weiss ich nicht ich pflücke sie mit einer
Funktion auseinander, addiere 30 HEX dazu und schicke sieh dann auf dem
PC und Hyperterminal zeigt mir nur die richtigen Zahlenwerte an.
Die Funktion um den Sensor auszulesen sieht zur Zeit so aus:
diese zwei Zeilen stehen im Main Programm
I2CSA = 0x49; // Slave address 1001001
int Zahl = fAuslesen();
int fAuslesen()
{
int Mitteltemp = 0;
int Zahlx = 0;
int highbyte = 0;
for(int l=0; l<32;l++)
{
U0CTL |= MST; // Master
I2CTCTL = I2CSTT+I2CSTP; // Initiate transfer
while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be
ready
highbyte = I2CDRB; // Receive MSByte from LM75
while ((I2CTCTL & I2CSTP) == 0x02); // Wait for Stop Condition
Mitteltemp += highbyte; //Werte addieren
for(int p=0;p<100;p++); //kleine Pause
}
Zahlx = Mitteltemp >> 5; //alle addierten Werte durch 32
teilen
return Zahlx;
}
Ich hoffe jemand kann mir noch einen Tip geben.
Danke
Markus
mh... also hast du dir mal den Datenstrom auf dem Oszi angeschaut?
Ich würde mal damit starten. Dann kannst du auch gleich mal ausrechnen,
ob die Daten die gesendet werden mit deinen Empfangenen übereinstimmen.
Also Oszi auf SDA und SCL hängen.
Im Datenblatt vom LM75 ist eigentlich für jeden Fall das passende
Diagramm.
Dann siehst du mal ob der LM75 die richtige Temperatur liefert. So
kannst du mal Software und Hardware Fehler separieren.
Grüße
Thomas
>wie kann ich rausfinden ob ein NAK zurückkommt?
Was passiert denn wenn du die falsche Adresse ansprichst (z.B. anstatt
0x49 mal 0x50)?
>Wie die Werte in HEX aussehen weiss ich nicht ich pflücke sie mit einer>Funktion auseinander, addiere 30 HEX dazu und schicke sieh dann auf dem>PC und Hyperterminal zeigt mir nur die richtigen Zahlenwerte an.
Dann bau das mal um das du die empfangen Werte mal direkt sehen kannst.
>I2CTCTL = I2CSTT+I2CSTP; // Initiate transfer
Ich hab jetzt nicht im Manual nachgesehen, aber das sieht irgendwie
falsch aus Start und Stop gleichzeitig zu setzen.
Wo wird in deinem Code I2CEN auf 1 gesetzt?
Wo ist der Rest der initialisierung vom I2C-Bus?
@Thomas,
nein das mit dem Oszi habe ich noch nicht versucht. Mal sehen ob ich was
damit rauskriege.
Ich versuche auch noch die Zahlen direkt auf eine Siebensegmentanzeigen
auszugeben aber leider habe ich da noch einen Hardware Fehler.
Danke für den Tip.
@Jörg,
>>wie kann ich rausfinden ob ein NAK zurückkommt?>Was passiert denn wenn du die falsche Adresse ansprichst (z.B. anstatt>0x49 mal 0x50)?
Dann bleibt das Programm in dieser Zeile stehen:
while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be ready
>>Wie die Werte in HEX aussehen weiss ich nicht ich pflücke sie mit einer>>Funktion auseinander, addiere 30 HEX dazu und schicke sieh dann auf dem>>PC und Hyperterminal zeigt mir nur die richtigen Zahlenwerte an.>Dann bau das mal um das du die empfangen Werte mal direkt sehen kannst.
Ich habe keine Ahnung wie ich das machen soll. Denn Hyperterminal
scheint die Daten immer als Hexwert auszulesen. (ich schicke ja Ziffer
für Ziffer). Und damit der richtige Zifferwert auf dem Bildschirm
erschient muß man immer 30HEX zu jeder Ziffer dazu addieren.
Aber das mit dem Übertragen auf dem PC Funktioniert gut denn wenn ich
eine Feste Zahl z.B. 1234 übertragen lasse, erscheint die genaus so auf
dem PC.
>>I2CTCTL = I2CSTT+I2CSTP; // Initiate transfer>Ich hab jetzt nicht im Manual nachgesehen, aber das sieht irgendwie>falsch aus Start und Stop gleichzeitig zu setzen.
Ich habe das so verstanden, dass bei dieser Schreibweise nur gesagt
wird, dass Startbit und Stopbit verwendet werden sollen. Und wann sie
gesendet werden, dass macht das Protokoll automatisch (hoffentlich). Ich
habe es auch so aus einem Beispiel von TI übernommen und Imon hat es
weiter oben in seinem Beispiel auch so angegeben.
>Wo wird in deinem Code I2CEN auf 1 gesetzt?>Wo ist der Rest der initialisierung vom I2C-Bus?
Main Programm
Deklaration vom UART
P2SEL|=0x00; // Port2 als input output benutzten
P1DIR|=0xFF; // Port1 sind die 8 LEDs
P2DIR|=0xFF; //Port2 sind die Latschsignale für 7-Segment decoder
P3SEL |= 0x0a; // Assign I2C pins to module
P3OUT |= 0x05; //am Port3 Pin 1+3 auf High setzen (Latch Pins)
P1OUT = 0x00;
U0CTL |= I2C + SYNC; // Switch USART0 to I2C mode
U0CTL &= ~I2CEN; // Recommended I2C init procedure
I2CTCTL = I2CSSEL_2; // SMCLK
I2CPSC = 0x02; // Vorteiler
I2CSCLH = 0x03; // High period of SCL
I2CSCLL = 0x03; // Low period of SCL
I2CNDAT = 0x01; // Transmit two byte
U0CTL |= I2CEN; // Enable I2C, 7 bit addr,
for (;;)
{
I2CSA = 0x49; // Slave address 1001001
int Zahl = fAuslesen();
TempSenden(Zahl);
.
.
.
Gruß
Markus
>Ich habe keine Ahnung wie ich das machen soll. Denn Hyperterminal>scheint die Daten immer als Hexwert auszulesen.
Du hast doch ein JTAG Debugger, oder? Dann kannst dir die Werte doch mal
in ein Array schreiben lassen und im Debugger ansehen.
>I2CTCTL = I2CSTT+I2CSTP;
Das Start, Stop scheint richtig zu sein. Allerdings ist das = Zeichen
denke ich falsch. Damit überscheibst du dir die Werte die du vorher in
I2CTCTL geschrieben hast. Besser wäre also |=
Auf welchen TI Beispiel basiert dein Code?
Kannst du mal einen Schaltplan von deinem Aufbau posten?
Hi Jörg,
>Du hast doch ein JTAG Debugger, oder? Dann kannst dir die Werte doch mal>in ein Array schreiben lassen und im Debugger ansehen.
Jetzt bringst du mich ein bisschen in Verlegenheit, denn ich habe so ein
paar Verständnissprobleme bzgl. Debugger und Compiler (was, was
bedeutet).
Also, ich verwende als Compiler das IAR Programm von TI. Die Daten
übertrage ich mit dem JTAG Kabel auf eine OLMEX Platine. Ich kann,
nachdem ich das Programm kompiliert habe, mit der Taste F11 die einzelen
Programmschritte durchlaufen. Ich kann dabei auch die einzelnen
Variablen anzeigen lassen. Aber wenn ich zu der Zeile komme wo der LM75
ausgelesen wird (while ((I2CIFG & RXRDYIFG) == 0); ), dann kann ich
nicht weiterspringen. Ich denke in dem Einzelschrittmodus funktioniert
die Kommunikation mit dem LM75 nicht.
>Das Start, Stop scheint richtig zu sein. Allerdings ist das = Zeichen>denke ich falsch. Damit überscheibst du dir die Werte die du vorher in>I2CTCTL geschrieben hast. Besser wäre also |=
habe ich ausprobiert, aber es macht keinen Unterschied
>Auf welchen TI Beispiel basiert dein Code?
fet140_i2c_13.c
>Kannst du mal einen Schaltplan von deinem Aufbau posten?
Mein Aufbau ist provisorisch auf einer Lochrasterplatine gebastelt mit
Tastern am Port1 LEDs am Port2 und I2C und UART1 am Port3. Ich weiss
nicht genau was du sehen willst. Ich bin leider noch kein großer Experte
von eagle o.ä. Programme. Am liebsten hätte schnell ich eine Skizze
gemacht aber ich kann im Moment nicht scannen. Also habe ich mal was in
PowerPoint aufgemalt.
Ich hoffe du hast das gemeint (siehe Anhang).
Gruß
Markus
>Also habe ich mal was in PowerPoint aufgemalt.>Ich hoffe du hast das gemeint (siehe Anhang).
Ja, das hatte ich gemeint.
>Aber wenn ich zu der Zeile komme wo der LM75>ausgelesen wird (while ((I2CIFG & RXRDYIFG) == 0); ), dann kann ich>nicht weiterspringen. Ich denke in dem Einzelschrittmodus funktioniert>die Kommunikation mit dem LM75 nicht.
Doch, die funktioniert schon, nur sind die Unterbrechungen vom
Einzelschrittmodus nicht so günstig und können zum abbruch der I2C
Kommuniktion führen, dann bleibt der µC in der Schleife hängen.
Du könntest aber z.B. einen Breakpoint an die Stelle
Mitteltemp += highbyte;
setzen und dir anschauen was für ein Byte tatsächlich empfangen wurde.
>>Auf welchen TI Beispiel basiert dein Code?>fet140_i2c_13.c
Schau dir auch mal fet140_i2c_1.c an, das ist eine Kommunikation mit
einem LM75 (TMP100 ist die Version von Ti).
Bei der fet140_i2c_13.c könntest du auch mal die TXBytes() Funktion
nutzen um ein Byte (0x00) zu senden. Dann steht der LM75 sicher auf dem
Temperaturregister wenn du die Bytes abrufst.
Vielleicht wäre es auch besser beide (low und high) Bytes abzurufen.
Nicht das es doch Probleme macht wenn nur immer das high-Byte gelesen
wird.
Hi Jörg,
>Doch, die funktioniert schon, nur sind die Unterbrechungen vom>Einzelschrittmodus nicht so günstig und können zum abbruch der I2C>Kommuniktion führen, dann bleibt der µC in der Schleife hängen.
Danke jetzt weis ich endlich wofür der Breakpoint da ist und wie man ihn
benutzt :o)
Leider brachte er keine neuen Erkenntnisse. Denn die empfangenen Bytes
beinhalten genau das was der PC anzeigt ich habe ca. 20 mal das Programm
gestartet, aber die ausgelesenen Bytes schwanken genauso wie es der PC
anzeigt. Ich habe das Highbyte ausgelesen und auch den über 32 Werte
gemittelten Wert. Es passt mit dem zusammen was der PC anzeigt.
Was ich überhaupt nicht verstehe das gemittelte Werte so gleichmäsig
schwanken können zB. 27, 19, 27, 19, 27, 19, 26, 19, 26, 18, 26, 18,
usw.
Die Werte erscheinen so ca. im Sekunden Abstand.
Ich habe versucht aus nur 2 Werten den Mittelwert zu ermitteln und habe
auch versucht aus 64 Werten den Mittelwert zu ermitteln. Du kannst es
glauben oder nicht, das Ergebnis ist immer fast das Gleiche. Ich drehe
noch durch.
Hier ist meine Funktion:
int fAuslesen()
{
int Mitteltemp = 0;
int Zahlx = 0;
int highbyte = 0;
int lowbyte = 0;
for(int l=0; l<64;l++)
{
U0CTL |= MST; // Master
I2CTCTL |= I2CSTT+I2CSTP; // Initiate transfer
while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be ready
highbyte = I2CDRB; // Receive MSByte from LM75
while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be ready
lowbyte = I2CDRB; // Receive ControlByte from LM75
while ((I2CTCTL & I2CSTP) == 0x02); // Wait for Stop Condition
Mitteltemp += highbyte;
for(int p=0;p<1000;p++);
}
Zahlx = Mitteltemp >> 6;
lowbyte >>=7;
return Zahlx;
}
>Schau dir auch mal fet140_i2c_1.c an, das ist eine Kommunikation mit>einem LM75 (TMP100 ist die Version von Ti).
Habe ich schon gemacht, aber da ich mit den Interrupts noch meine
Schwierigkeiten habe, habe ich mir das anderes Beispiel rausgesucht.
Aber wenn ich das richtig sehe wird da nichts anderes gemacht als in
meinen Programm. Ausser das dort ein Interrupt genutzt wird.
Ich habe auch schon versucht diesel Zeile:
while ((I2CIFG & RXRDYIFG) == 0);
duch duch eine Warteschleife zu ersetzten. Leider mit dem selben
Ergebnis
>Bei der fet140_i2c_13.c könntest du auch mal die TXBytes() Funktion>nutzen um ein Byte (0x00) zu senden. Dann steht der LM75 sicher auf dem>Temperaturregister wenn du die Bytes abrufst.
Habe ich versucht. Kein Unterschied.
>Vielleicht wäre es auch besser beide (low und high) Bytes abzurufen.>Nicht das es doch Probleme macht wenn nur immer das high-Byte gelesen
Wie du oben in meiner Funktion siehst habe ich das wieder gemacht, aber
mit dem selben Ergebnis.
Danke bis hierhin für deinen Geduld und deine Tips.
Markus
>Denn die empfangenen Bytes beinhalten genau das was der PC anzeigt..
Am PC kommen doch aber nur die gemittelten Werte an.
Wenn wir dem Problem auf den Grund gehen wollen brauchen wir die
Rohdaten! Also nichts mehr mitteln sondern low und high-Byte getrennt an
den PC senden oder halt im Debugger ansehen und aufschreiben.
>Am PC kommen doch aber nur die gemittelten Werte an.>Wenn wir dem Problem auf den Grund gehen wollen brauchen wir die>Rohdaten! Also nichts mehr mitteln sondern low und high-Byte getrennt an>den PC senden oder halt im Debugger ansehen und aufschreiben.
Das hatte ich ja gemeint, dass ich das Programm 20 mal gestartet habe.
Da habe ich sowohl nur das Highbyte und danach auch die gemittelten
Werte mehrer Male ausgelesen. mit dem Ergebnis dass sie geschwank haben.
Sorry hatte ich oben vielleicht ein bisschen blöd formuliert.
jetzt habe ich es noch mal versucht und das Highbyte und das Lowbyte
mehrer
Male ausgelesen. Das Lowbyte schwankt zwischen 127 und 255 aber das ist
ja auch so in Ordnung da ja nur Bit 8 zählt. Und das Highbyte schwankt
zwischen 15 und 17 bei ca. 1 Messwert alle 2 Sekunden. Aber das erklärt
nicht warum das bei den gemittelten Werten aus so ist. Ich habe das
Gefühl als ob meinen Mittelwert Berechnung nicht stimmt. Als ob er nur
einen gemmessen Wert übergibt und nicht den Durchschnittswert.
Markus
ich habe jetzt noch mal ein bisschen mit dem IAR herumprobiert und habe
rausgefunden wie man das Programm bis zu Breakpoimt viel schneller
hintereinander starten kann und dabei habei ich gemerkt das die Rohdaten
vom Highbyte doch relativ stabil sind. Es schwankt zwar leicht wie oben
angegeben, aber das ist lange nicht so schlimm wie die gemittelten
Werte.
Ich habe auch mal wieder einen zweiten LM75 angeschlossen weil der noch
schlimmer geschwankt hat, aber hier war die Schwankungen bei den
Rohdaten auch wesentlich weniger als bei den gemittelten Werten. Leider
sind die gemessenen Werte immer noch viel zu tief. Bei Raumtemperatur
misst der eine Fühler zwischen 15 und 18°C und der Zweite zwischen 7 und
9°C.
Markus
Oder wie gesagt schau dir die Daten einfach mal mit dem Oszi an, dann
siehst du auch gleich viel mehr ... und kannst das einfach mal
anschauen.
Dann weißt du ob die Sensoren defekt sind oder nicht.
Im angehängten Bild wird der Sensor mit der Adresse 0x4E ausgelesen. Die
Temperatur dürfte der Raumtemperatur hier entsprechen 18-24°C je nach
dem was hier alles an ist ;)
Bitte beachte nur die ersten 3 "Bursts" weiter hinten kommt bei mir der
nächste Temperatursensor.
Grüße tom
@Jörg,
ich muß erst mal meine Daten erst mal aufräumen denn da sind noch sehr
viele Versuche drinn die ich mit // ausgeblendet habe. Sobald ich das
fertig habe poste ich es.
@Tom,
ich habe leider nicht so einen schönen Oszi wie du der mir die Signale
so sauber darstellt wie deiner. Ich habe noch einen alten HAMEG 30MHz
bei dem ist es sehr schwierig die SDA Signale sauber zu erkennen. Ich
hab leider nichts genaues erkennen können. Ich habe aber meine SCL
Frequenz einstellen können. Sie liegt jetzt bei 10.74 KHz (wenn ich mich
nicht verrechnet habe). Ich bin mit der Frequenz so weit runtergegangen,
weil ich gelesen haben, dass man dadurch längere Leitungen verwenden
kann, und mehrere Fühler an einer Leitung hängen kann. Das Ergebnis der
ausgelesen Fühler hat sich dadurch aber nicht verändert.
Gruß
Markus
Hi Jörg,
hier ist mein (Experimentier) Programm.
Ich habe bei Untersuchungen mit Hilfe des Breackpoint herausgefunden das
auch Messwerte von über 200 dabei waren. Deshalb habe ich einen Funktion
Programmiert die alle Werte über 150 übergeht. Und deshalb lese ich nur
noch das Highbyte aus, weil ich mir einbilde, dass das weniger Fehler
gibt.
Übrigens habe ich hier in der Artikelsammlung über Temperaturfühler
gelesen das sich der LM75 kalibrieren läst. Kann mir jemand erklären wie
das Funktionieren soll. Kann man (muß man) den LM75 vor dem Einsatz
programmieren?
Gruß
Markus
Markus S. schrieb:> Ich habe bei Untersuchungen mit Hilfe des Breackpoint herausgefunden das> auch Messwerte von über 200 dabei waren. Deshalb habe ich einen Funktion> Programmiert die alle Werte über 150 übergeht.
Wozu soll das gut sein?
>muß man) den LM75 vor dem Einsatz programmieren?
Nein.
>Und deshalb lese ich nur noch das Highbyte aus, weil ich mir einbilde,>dass das weniger Fehler gibt.
Irgendwo hast du einen grundsätzlichen Fehler drin. Es bringt überhaupt
nichts zu versuchen etwas weniger Fehler zu bekommen oder die Messwerte
durch irgenwelche erfundenen Faktoren und Offsets zurech zu biegen.
Damit löst du nicht das Problem! Der LM75 MUSS IMMER ordentliche
Messwerte liefern. Solange das noch nicht der Fall ist solltest du nicht
die Symptome bekämpfen sondern die Ursache finden.
Wie lang ist denn jetzt noch das Kabel zum Sensor? Wenn das immer noch
so lang ist würde ich erst mal ein ganz kurzes dran machen um die
Fehlerquelle erst mal auszuschliessen.
Wie schaut es mit einer Liste der Rohdaten aus?
Falls alle Stricke reissen würde ich dir empfehlen erst mal mit einem
PCA9554 I²C I/O Baustein weiter zu machen. Da sieht man wenigstens
direkt ob die Daten die man sendet und empfängt genau dem entsprechen
die am Baustein anliegen. Wäre noch eine Fehlerquelle weniger. Wenn das
dann alles läuft kann man zurück zum LM75.
Hi Jörg,
>Irgendwo hast du einen grundsätzlichen Fehler drin. Es bringt überhaupt>nichts zu versuchen etwas weniger Fehler zu bekommen oder die Messwerte>durch irgenwelche erfundenen Faktoren und Offsets zurech zu biegen.>Damit löst du nicht das Problem! Der LM75 MUSS IMMER ordentliche>Messwerte liefern. Solange das noch nicht der Fall ist solltest du nicht>die Symptome bekämpfen sondern die Ursache finden.
ich gebe dir voll und ganz recht. Aber durch meine ganzen Fehlversuche
habe ich gedacht es wäre normal das manche Fühler nicht die richtigen
Werte ausgeben.
>Wie lang ist denn jetzt noch das Kabel zum Sensor? Wenn das immer noch>so lang ist würde ich erst mal ein ganz kurzes dran machen um die>Fehlerquelle erst mal auszuschliessen.
im Moment ist mein Kabel wieder ca. 2.5m lang um auch mal
Aussentemperaturen messen zu können. Ich habe es aber schon mit einem
kurzem Kabel (ca. 15cm) Versucht. Aber die Messwerte waren die Gleichen.
Ausserdem hat der zweite Fühler nur eine 10cm Leitung aber wie oben
schon erwähnt gibt der noch schlechtere Werte aus.
>Wie schaut es mit einer Liste der Rohdaten aus?
sobald ich aufgeschrieben habe, poste ich sie.
>Falls alle Stricke reissen würde ich dir empfehlen erst mal mit einem>PCA9554 I²C I/O Baustein weiter zu machen. Da sieht man wenigstens>direkt ob die Daten die man sendet und empfängt genau dem entsprechen>die am Baustein anliegen. Wäre noch eine Fehlerquelle weniger. Wenn das>dann alles läuft kann man zurück zum LM75.
Au backe, das wir aber ein harte Brett. Ich habe mir gerade mal das
Datenblatt angesehen bis ich das alles verstanden habe, werden einige
Tage (Wochen) ins Land gehen. Aber ich versuche es mal
Danke
Markus
Markus S. schrieb:> Au backe, das wir aber ein harte Brett. Ich habe mir gerade mal das> Datenblatt angesehen bis ich das alles verstanden habe, werden einige> Tage (Wochen) ins Land gehen.
Alternativ den PCF8574, der ist einfacher aufgebaut, aber der 9554 kommt
mit seiner Register Struktur näher an das ran was du beim LM75 brauchst.
Siehe:
http://www.mikrocontroller.net/articles/Port-Expander_PCF8574
Jörg schrieb:
>Wie schaut es mit einer Liste der Rohdaten aus?
So, ich habe mal die Rohwerte gesammelt. Ich habe das Programm mit einem
Breakboint unterbrochen und jedes mal den Wert, so wie er im Highbyte
angezeigt wird, mitgeschrieben.
18, 15, 18, 14, 18, 15, 18, 14, 19, 16, 18, 14, 18, 14, 19, 16, 18, 14,
18, 15, 18, 14, 19, 17, 20, 15, 18, 14, 18, 14, 19, 17, 19, 17, 20, 14,
18, 14
Das erstaunliche ist, ob ich die Werte schnell auslese (ca im
Sekundenabstand) oder ob ich mir Zeit lasse (ca 5 Sekunden), das
Ergebnis ist das Gleiche. Es wechseln sich immer ein höherer Wert und
ein niedriger Wert ab. Ganz selten kommt zwei mal der gleiche Wert.
In letzter Zeit hatte ich das Problem, dass das Programm oft an einer
der for Schleifen (Warteschleife) hängen geblieben ist. Sind for
Schleifen ungünstig?
>Alternativ den PCF8574, der ist einfacher aufgebaut, aber der 9554 kommt>mit seiner Register Struktur näher an das ran was du beim LM75 brauchst.
Das sehe ich mir mal an.
Zwischendurch mal wieder ein Dankeschön für deine Geduld und Tips.
Gruß
Markus
Markus S. schrieb:> So, ich habe mal die Rohwerte gesammelt. Ich habe das Programm mit einem> Breakboint unterbrochen und jedes mal den Wert, so wie er im Highbyte> angezeigt wird, mitgeschrieben.> 18, 15, 18, 14, 18, 15, 18, 14, 19, 16, 18, 14, 18, 14, 19, 16, 18, 14,> 18, 15, 18, 14, 19, 17, 20, 15, 18, 14, 18, 14, 19, 17, 19, 17, 20, 14,> 18, 14> Es wechseln sich immer ein höherer Wert und ein niedriger Wert ab.
Was mich glauben lässt das es sich bei hohen Werten um das high-Byte
handelt.
Irgendwie hatte ich es schon ganz verdrängt, aber der LM75 hat ja auch
noch andere Register. Das Configuration, Hystherese usw. Wenn du z.B.
das Hystherese Register liest, müssen die Werte ja auch IMMER gleich
sein. Und wenn du was in das Register schreibst, musst du auch immer das
lesen was geschrieben wurde.
Wenn die Daten immer gleich sind kannst du auch vernünftig mit dem Oszi
schauen was übertragen wird.
Harald schrieb:
>int highbyte = 0;> int lowbyte = 0;>>zu>unsigned char highbyte = 0;>unsigned char lowbyte = 0;
Danke werde ich mal versuchen, aber was bringt das?
Jörg schrieb:
>Was mich glauben lässt das es sich bei hohen Werten um das high-Byte>handelt.
aber ich lese doch sowieso nur das high-Byte aus. Ich verstehe nicht so
ganz was du meinst. Und wo kommen den die kleineren Werte her?
>Irgendwie hatte ich es schon ganz verdrängt, aber der LM75 hat ja auch>noch andere Register. Das Configuration, Hystherese usw. Wenn du z.B.>das Hystherese Register liest, müssen die Werte ja auch IMMER gleich>sein.
Wieso? Was steht in dem Hystherese Register? Was kann man oder muß mit
dem Configurations Register machen?
>Und wenn du was in das Register schreibst, musst du auch immer das>lesen was geschrieben wurde.
Und was heisst das? Ich schreibe doch gar nichts in ein Register.
Gruß
Markus
Markus S. schrieb:> Harald schrieb:>>int highbyte = 0;>> int lowbyte = 0;>>>>zu>>unsigned char highbyte = 0;>>unsigned char lowbyte = 0;> Danke werde ich mal versuchen, aber was bringt das?>
Du hast ja eine Schleife die immer wieder das Highbyte überschreibt.
Wenn keine neuer Wert vom LM75 reinkommt bleibt der Wert bestehen und du
denkst du hast den Wert 18 bekommen. Es könnte also sein, das der LM75
nicht jedesmal mit 18 geantwortet hat sondern nur beim ersten mal.
> Jörg schrieb:>>Was mich glauben lässt das es sich bei hohen Werten um das high-Byte>>handelt.> aber ich lese doch sowieso nur das high-Byte aus. Ich verstehe nicht so> ganz was du meinst. Und wo kommen den die kleineren Werte her?>>>>Irgendwie hatte ich es schon ganz verdrängt, aber der LM75 hat ja auch>>noch andere Register. Das Configuration, Hystherese usw. Wenn du z.B.>>das Hystherese Register liest, müssen die Werte ja auch IMMER gleich>>sein.> Wieso? Was steht in dem Hystherese Register? Was kann man oder muß mit> dem Configurations Register machen?>>>Und wenn du was in das Register schreibst, musst du auch immer das>>lesen was geschrieben wurde.> Und was heisst das? Ich schreibe doch gar nichts in ein Register.>
mh... also schau dir doch bitte mal das Datenblatt an. Da steht so
einiges drin. Wie man dan LM75 konfiguriert und wie man ihn richtig
ausliest. Wenn man ihn auslesen möchte muss man z.b. erst einen 0x00
Pointer an den LM75 schicken, damit dieser aus dem richtigen Register
(Temp) die Werte ließt und "dir" zuschicken.
Ließ dir das ganze mal durch und schau die mal die Abbildung b an, das
ist was du machen musst.
Gruß
Tom
> Gruß> Markus
Markus S. schrieb:> Jörg schrieb:>>Was mich glauben lässt das es sich bei hohen Werten um das high-Byte>>handelt.> aber ich lese doch sowieso nur das high-Byte aus.
Richtig. Du willst nur das high-Byte lesen, bekommst aber evt. immer
einmal das high-Byte und beim nächsten mal das low-Byte. Was erklären
würde warum die Werte einmal hoch und einmal niedrig sind.
>>Irgendwie hatte ich es schon ganz verdrängt, aber der LM75 hat ja auch>>noch andere Register. Das Configuration, Hystherese usw. Wenn du z.B.>>das Hystherese Register liest, müssen die Werte ja auch IMMER gleich>>sein.> Wieso? Was steht in dem Hystherese Register? Was kann man oder muß mit> dem Configurations Register machen?
Wie Tom schon gesagt hat: Steht im Datenblatt.
Mir gegt es nur darum das es Register sind die du schreiben und lesen
kannst und nicht von der Temperatur abhängig sind. D.h. die Daten müssen
immer gleich sein. Falls es beim schreiben oder lesen von diesem
Register Fehler gibt, ist die Fehlersuche einfacher weil nicht die
variable Temperatur stört und immer andere Werte liefert.
>>Und wenn du was in das Register schreibst, musst du auch immer das>>lesen was geschrieben wurde.> Und was heisst das? Ich schreibe doch gar nichts in ein Register.
Sollst du dann aber um zu schauen ob deine Kommunikation/Software/I²C OK
ist.
Tom schrieb:
>Du hast ja eine Schleife die immer wieder das Highbyte überschreibt.>Wenn keine neuer Wert vom LM75 reinkommt bleibt der Wert bestehen und du>denkst du hast den Wert 18 bekommen. Es könnte also sein, das der LM75>nicht jedesmal mit 18 geantwortet hat sondern nur beim ersten mal.
ich dachte, mit der folgenden Zeile wird verhindert, dass mal keine
Daten ausgegeben werden.
while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be ready
Ich habe aber auch schon die Werte ohne diese Schleife, die das Highbyte
überschreibt, ausgelesen. Das heisst also jeden Wert (siehe oben meine
Rohdatenliste). Mit dem gleichen Ergebnis wie immer.
>Wenn man ihn auslesen möchte muss man z.b. erst einen 0x00>Pointer an den LM75 schicken, damit dieser aus dem richtigen Register>(Temp) die Werte ließt und "dir" zuschicken.
hab ich auch schon mal versucht. Ich probiere es aber noch mal.
Jörg schrieb:
>Richtig. Du willst nur das high-Byte lesen, bekommst aber evt. immer>einmal das high-Byte und beim nächsten mal das low-Byte. Was erklären>würde warum die Werte einmal hoch und einmal niedrig sind.
nein das glaube ich nicht denn ich habe auch schon die Rohdaten von dem
Lowbyte ausgelesen das schwankt nur zwischen 255 und 127 (das letzte Bit
für die 0,5 Nachkommastelle) und das ist ja in Ordnung.
>Wie Tom schon gesagt hat: Steht im Datenblatt.>Mir gegt es nur darum das es Register sind die du schreiben und lesen>kannst und nicht von der Temperatur abhängig sind. D.h. die Daten müssen>immer gleich sein. Falls es beim schreiben oder lesen von diesem>Register Fehler gibt, ist die Fehlersuche einfacher weil nicht die>variable Temperatur stört und immer andere Werte liefert.
ich habe mir das Datenblatt noch mal angesehen und ich denke ich habe
den größten Teil verstanden. Ich werde mal mit den Registern ein paar
Versuche machen mal sehen was dabei rauskommt.
Danke
Markus
Hallo zusammen,
ich habe mal wieder ein bisschen rumexperimentiert. Leider erfolglos.
Ich wollte sichergehen, dass das Pointer Register auch wirklich auf Null
steht. Dashalb habe ich mit:
U0CTL |= MST; // Master mode
I2CTCTL |= I2CSTT+I2CSTP+I2CTRX; // Initiate transfer
while ((I2CIFG & TXRDYIFG) == 0); // Wait for transmitter to be
ready
I2CDRB = 0x00;
while ((I2CTCTL & I2CSTP) == 0x02); // To prevent Arbitration Lost
eine Null gesendet.
Leider bleibt die das Programm dann beim Datenauslesen in dieser Zeile
hängen:
while ((I2CTCTL & I2CSTP) == 0x02); // Wait for Stop Condition
das heisst es wir kein Stopsignal erzeugt.
Und mit dem Breakpoint habe ich herausgefunden, das immer nur eine Null
ausgelesen wird.
Ich habe mal versucht den LM75 zu Konfigurieren. Als erstes habe ich
0x01 gesendet und danach eine 0X24. Aber geändert hat das Ganze nichts.
Wenn ich die oben genannte Sendefunktion aus dem Programm nehme,
schwanken die Messwerte wie immer und wenn ich es mit rein nehmen,
bleibt das Programm an der genannten Stelle hängen.
Ich glaube so ganz habe ich das Datenblat vom LM75 doch noch nicht
verstanden. Kann mir jemand sagen ob und wie ich den LM75 konfigurieren
muß, damit ich einfach nur die Temperatur aus lesen kann? Muß ich
vieleicht noch etwas anderes Senden bevor ich 0x00 sende um das Pointer
Register auf Null zu setzten?
Markus
>Kann mir jemand sagen ob und wie ich den LM75 konfigurieren muß, damit>ich einfach nur die Temperatur aus lesen kann?
Du musst nix konfigurieren.
>Muß ich vieleicht noch etwas anderes Senden bevor ich 0x00 sende um das>Pointer Register auf Null zu setzten?
Nur die I²C Adresse.
Hallo zusammen,
ihr werdet es nicht glauben, aber ich habe meinen Fehler gefunden.
Es ist eingentlich ein bisschen peinlich und ich wollte es euch nicht
berichten, aber ich finde, nachdem ich so viel Hilfe und Tipps von euch
bekommen habe, habt ihr es verdient zu wissen woran es lag.
Kurz gesagt, es war die Versorgungsspannung.
Ich habe mir eine Tesplatine gebastel mit Taster, LEDs, 7-Segmentanzeige
und einer eigenen Stromversorgung (3,3V). Der Prozessor sitzt auf einer
auf einer kleinen OLIMEX Platine mit fertigen JTAG Anschluss. Diese
Platine wird auf meine Testplatine gesteckt. Über den JTAG Anschluss
läuft die Programmierung. Bei meinen ersten programmier Versuchen habe
ich gemerkt dass man gar keine Versorgungspannung braucht denn die
Versorgungsspannung von PC reicht, damit der Prozessor arbeitet. Somit
habe ich nur noch ganz selten eigene Versorgungsspannung genutzt.
Als ich angefangen habe mit den Temperaturfühlern zu experimentieren
habe ich nicht eine Sekunde darüber nachgedacht, dass die Spannung, die
vom PC kommt, niedrieger ist und dass das den Fühler beeinflussen
könnte. Aber die Spannung beträgt nur ca. 2,5V und das bringt den LM75
durcheinander. Wenn ich die Externe Spannung von 3,3V anschließe, dann
funktioniert alles ganz normal.
Also noch mals vielen Dank für eure Hilfe und Geduld und ich hoffe, dass
ihr auch meine nächsten Fragen (die bestimmt kommen werden) noch
beantwortet.
Gruß
Markus