LMT84 Temperatursensor mit TI MSP430G

Gast #4391121
Hallo Leute,

ich brauche hilfe beim auslesen der analogen Werte des LMT84 Sensors.

Ich bekomme leider nur Mist raus (irgendwas zwischen 400 bis 600).


Hat jemand schonmal damit gearbeitet ?
1
ADC10CTL0 &= ~ENC; // disable ADC
2
ADC10CTL1 |= CONSEQ_0+ADC10SSEL_3+ADC10DIV_4; 
3
ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON | ADC10IE;
4
ADC10AE0 = BIT0;
5
ADC10CTL0 &= ~ENC; //disable ADC
6
ADC10CTL1 |= INCH_5; //Select channel 0
7
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
8
while (ADC10CTL1 & BUSY); // wait
9
j = (unsigned int)ADC10MEM;
10
ADC10CTL0 &= ~ENC;
Gast
Ja das Datenblatt habe ich vor mir.

Zum Aufbau

Vom Launchpad zum Steckbrett gehen die Leitungen raus, wo der Sensor 
sitzt.

Es liegt wie es aussieht am ADC Wandler. Mit einem Multimeter gemessen 
am OUT Pin habe ich  898mV was  25°C ist.

Danke+ Gruß
Jörg
Gast
Hallo Jörhg

das ist ein etwas spartanischer Code zum Testen. Hier wird der ADC 
initialisiert, macht genau eine Messung, schaltet dann den ADC ab und 
beendet das Programm.

- hängt der Sensor am P1.5?
- was steht denn in ADC10MEM nach Programmende?

Die Initialisierung schau ich mir gleich nochmal an, die muß ich erstmal 
auseinderdröseln. Spontan fällt mir auf, daß Du den ADC-Interrupt 
aktiviert hast aber offensichtlich keine ISR vorhanden ist.

Als nächste würde ich mir an Deiner Stelle 2 Funktionen basteln:

1. Initialisierung
2. Messung

und den Interrupt erstmal raus.

Die Messung würde ich mir zum Testen timergesteuert alle 0.5 Sec 
wiederholen lassen, dann kann man besser sehen ob man Mist mißt. Man 
kann dann auch mal statt des Sensors zur Kontrolle ein Poti dranhängen.

Gruß wv
Gast
Hallo wv

erst einmal Danke für deine Hilfe.

Du hast recht nen Interrupt will ich erst einmal nicht aufrufen. Er soll 
nur den Wert mir anzeigen.
Was mir auffällt ist das sich die Werte stark ändern.  Ich habe hier mal 
nen LM35DZ. Dort
existieren ebenfalls Abweichungen mit dem was ich hier am Multimeter 
raus habe und mit dem am ADC Eingang. Mit was kann das auf sich haben?
Persönliche Seite
Lass' mal den Sensor weg und ersetze ihn durch ein simples Poti (ein 
paar kΩ, kommt nicht auf den genauen Wert an), das Du zwischen VCC und 
GND schaltest, und den Schleifer an Deinen ADC-Eingang.

Solange Du mit dem Aufbau kein stabiles und reproduzierbares Ergebnis 
erzielst, ist es müßig, sich weiter mit Sensoren zu beschäftigen.

Deinen Code zum Ansteuern des ADC hast Du den TI-Beispielen für Deinen 
Controller entnommen? Du schreibst praktischerweise nur "MSP430G", ist 
das der 'F2553, der dem Launchpad beiliegt, oder ein anderer?
Gast
ich hab jetzt mal die Initialisierung angeschaut,

sollte für die ersten Test mal ok sein, aber ADC10IE sollte raus, oder 
Du schreibst eine ISR dazu.

Referenzspannung ist auf intern 1.5V d. h. in ADC10MEM sollte etwas in 
der Gegend von 612(dez) stehen. Es kann aber sein, daß die erste Messung 
sowieso für'n Eimer ist, da das Programm endet, bevor die 
Sample-and-Hold-Time abgelaufen ist. Ob er dann noch das Ergebnis 
korrekt reinschreibt, weiß ich nicht. Also umbauen auf mehrere Messungen 
hintereinander. Dann mal mit 'nem Poti testen.

Gruß wv
Gast
Hallo Rufus

Rufus Τ. F. schrieb:
> Du schreibst praktischerweise nur "MSP430G", ist
> das der 'F2553, der dem Launchpad beiliegt, oder ein anderer?

Ich habe den G2553. Leider suche ich grade wie verrückt nach einem Poti.
1
int j=0;
2

3

4

5
void main(void)
6
{
7
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
8
  ADC10CTL0 &= ~ENC; // disable ADC
9
  ADC10CTL1 |= CONSEQ_0+ADC10SSEL_3+ADC10DIV_4;
10
  ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON ;
11
  ADC10AE0 = BIT5;
12
  ADC10CTL0 &= ~ENC; //disable ADC
13
  ADC10CTL1 |= INCH_5; //Select channel 0
14

15

16
  while(1){
17
  ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
18
  while (ADC10CTL1 & BUSY); // wait
19
  j = (unsigned int)ADC10MEM;
20
  j= (1.5*(int)j);
21
  j= j* 100;
22
  j= j/1024;
23
  ADC10CTL0 &= ~ENC;
24
}
25

26
}
Gast
Also die Zeilen
1
j= (1.5*(int)j);
2
  j= j* 100;
3
  j= j/1024;

können auskommentiert werden ( Wandlung auf °C ).

Aber ich habe leider keinen Poti gefunden :(.

Den Code wollte ich nun auf den LMT84 adaptieren.
Gast
wv schrieb:
> Referenzspannung ist auf intern 1.5V d. h. in ADC10MEM sollte etwas in
> der Gegend von 612(dez) stehen. Es kann aber sein, daß die erste Messung
> sowieso für'n Eimer ist, da das Programm endet, bevor die
> Sample-and-Hold-Time abgelaufen ist. Ob er dann noch das Ergebnis
> korrekt reinschreibt, weiß ich nicht. Also umbauen auf mehrere Messungen
> hintereinander. Dann mal mit 'nem Poti testen.

Ja ich habe im ADC10MEM  eine 600 stehen. Im multimeter wird mir 885 
angezeigt.
Gast
Hallo Jörg

da läut ein bißchen was schief:

>j = (unsigned int)ADC10MEM;
warum nicht gleich als unsigned int definieren?
>j= (1.5*(int)j);
die rechte Seite wird zum float, der dann einem unsigned int zugewiesen 
wird. Die Nachkommastellen werden abgeschnitten. Rechne doch besser mit 
1500mV Referenzspannung
>j= j* 100;
statt der  abgeschnittenen Nachkommastellen werden 2 Nullen angehängt
>j= j/1024;
und das wird dann ganzzahlig durch 1024 geteilt......
>ADC10CTL0 &= ~ENC;
hier schaltest Du wieder die Messung aus.
Mach doch lieber mit ADC10CTL0 |= ADC10SC; eine neue Messung und setz 
mit dem Debugger einen Breakpoint drauf. Dann kann man sich mehrere 
Ergebnisse ansehen und die Werte vergleichen.

Gruß wv

P.S.: Wenn Du kein Poti findest, dann setz doch mal den P1.5 auf GND.
Gast
>Ja ich habe im ADC10MEM  eine 600 stehen. Im multimeter wird mir 885
>angezeigt.

das sieht doch gut aus, rechnerisch ergäbe sich 603.

Trotzdem würde ich das erstmal mit mehreren Messungen verifizieren, 
sowas kann auch mal Zufall sein.

Bau Dir doch erstmal eine Umrechnung in mV ein, dann kann man mit dem 
Multimeter vergleichen.

Gruß wv
Gast
Hallo wv,

also irgendwie verstehe ich nicht wieso der Multimeter mir 885 und mein 
Chip hier  600 ausliest.
Wenn ich aufs Datenblatt ein Blick werfe, dann wären 602 mV 78°C.

wv schrieb:
>>j = (unsigned int)ADC10MEM;
> warum nicht gleich als unsigned int definieren?
>>j= (1.5*(int)j);
> die rechte Seite wird zum float, der dann einem unsigned int zugewiesen
> wird. Die Nachkommastellen werden abgeschnitten. Rechne doch besser mit
> 1500mV Referenzspannung
>>j= j* 100;
> statt der  abgeschnittenen Nachkommastellen werden 2 Nullen angehängt
>>j= j/1024;
> und das wird dann ganzzahlig durch 1024 geteilt......
>>ADC10CTL0 &= ~ENC;

Super danke für die Tipps die nehme ich an mich :D.

Aber woran könnte das liegen das ich da so ein Wert raus habe?
Gast
Also  ein Beispiel :

600 Habe ich ja im ADC. Vref sind  1,5V. Und es handelt sich ja hier um 
einen 10BIT ADC.

Also

V = 1,5V * 600/1024 ergibt 0,879.

ist die Rechnung korrekt ?
Gast
>V = 1,5V * 600/1024 ergibt 0,879.

>ist die Rechnung korrekt ?

fast, Du muß durch 1023 teilen, denn das ist der höchste Wert, den ein 
10-Bit Wandler ausgibt.

Gruß wv
Persönliche Seite
Jörhg schrieb:
> Gibt es da nen geschickten Trick ?

Ja. Ganzzahlen verwenden, indem Du mit dem hundertfachen rechnest, und 
bei der Ausgabe ein Dezimalkomma einschmuggelst.

Andererseits: Der 'G2553 hat 16 kiB Flash, so daß Du auch problemlos 
floating-point-Arithmetik nutzen kannst. Solange Du keine gesteigerten 
Anforderungen an Rechenzeit hast (d.h. Deine Umwandlung besonders 
schnell werden muss) und Du keine Platzprobleme im Flash hast, spricht 
nichts dagegen. Du kannst schließlich unbenutztes Flash im µC nicht 
zurückgeben ...
Gast
Also
1
volatile  unsigned long  int tempextern;
2

3

4
void main(void)
5
{
6
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
7

8

9
  ADC10CTL0 &= ~ENC; // disable ADC
10
  ADC10CTL1 |= CONSEQ_0+ADC10SSEL_3+ADC10DIV_4;
11
  ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON ;
12
  ADC10AE0 = BIT5;
13
  ADC10CTL0 &= ~ENC; //disable ADC
14
  ADC10CTL1 |= INCH_5; //Select channel 0
15

16

17
  while(1){
18
  ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
19
  __delay_cycles(50);
20
  while (ADC10CTL1 & BUSY); // wait
21
  tempextern = (unsigned int)ADC10MEM;
22

23
  tempextern = (1500*tempextern);
24
       //   tempextern= tempextern * 100;
25
_no_operation();
26
  tempextern= tempextern/1023;
27
  ADC10CTL0 &= ~ENC;
28
}
29

30
}

Ich komme leider immernocht nicht auf die mV wie auf dem Multimeter.

Abweichung von teilweise 10 bis 30 mV.
Gast
>Abweichung von teilweise 10 bis 30 mV.

über den ganzen Bereich getestet? Dann bist Du doch schon dicht dran. 1 
Bit bei einem 10Bit ADC und 1.5V Referenz entsprechen etwa 2mV, also 
etwas genauer sollte es noch gehen. Die Ganzzahlrechnung kann man noch 
verbessern in dem man vor der Division noch mit 10 multipliziert, 5 
addiert, und wieder durch 10 dividiert. Dann hast Du kaufmännische 
Rundung auf der letzten Stelle.

Dann hat der MSP2553 noch Kalibrierungswerte für den ADC im InfoMEMA 
stehen. Die kann man dann auch noch in die Rechnung mit einbeziehen 
(Datenblatt Table 10+11 und FamilyUserGuide Chapter24 TLV-structure).

Gruß Wolfgang
Gast
noch etwas:

>ADC10CTL0 &= ~ENC;

ersetz doch die letzte Zeile durch

ADC10CTL0 |= ADC10SC;

und setz einen Breakpoint drauf. Dann hast Du eine Endlosschleife, wo er 
nur Messungen macht. In Deiner jetzigen Version wird unmittelbar nach 
der Initialisierung gemessen, es könnte sein daß da die Referenzspannung 
noch nicht auf dem richtigen Wert steht.

Gruß wv

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.