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.
Hallo
Was soll das denn werden:
> for(int i=0; i<20000; i++);
Sowas sollte jeder gute Compiler wegoptimieren!
Gruß
Joachim
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 | unsigned int Zahl = 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 denke du benötigst folgendes. I2CNDAT = 0x02; // Transmit 2 bytes for (;;) { U0CTL |= MST; // Master I2CTCTL = I2CSTT+I2CSTP; // Initiate transfer while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be ready 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 }
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 |
19 | lmreg++; // 2 compliment |
20 | temp = lmreg * -0.125; // calculate Temp in degree |
21 | }
|
22 | else { |
23 | temp = lmreg * 0.125; // calculate Temp in degree |
24 | }
|
25 | |
26 | }
|
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: > Was heißt MSB? http://de.wikipedia.org/wiki/Bitwertigkeit > Leider habe ich bei dem highbyte nicht Null als Ergebnis sondern, > Zahlenwerte. Das verstehe ich leider nicht. Das High-Byte ist ja auch deine Vorkommastelle.
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.
Stimmt du hast recht. Aber dann schwanke die Werte von 15 bis 18 Grad und nicht um 23 Grad
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
Mach mal: int highbyte = 0; int lowbyte = 0; zu unsigned char highbyte = 0; unsigned char lowbyte = 0;
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.
Jörg schrieb:
>Nur die I²C Adresse.
das ist klar, aber das macht das System ja automatisch wenn ich die
Adresse vorher angebe.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.