MSP430 Temperatursensor

Texas Instruments hat bei einigen MSPs einen Temperatursensor integriert (wie z.B. MSP430G2231, MSP430G2452, MSP430G2553 etc.). Dieser kann ziemlich einfach benutzt werden und reicht für viele Anwendungen (z.B. Raumtemperatur messen, eine hohe Genauigkeit darf man aber hier nicht erwarten). In diesem Artikel soll es um die Initialisierung und die Temperatur-Auswertung gehen. Es gibt verschiedene Möglichkeiten aus dem eingelesenen ADC-Wert die Temperatur zu berechnen/ermitteln.

Der Temperatursensor wird durch folgende Geradengleichung beschrieben (siehe User-Guide S. 556):

V_{temp}=0.00355V/^{\circ}C*(Temp_C)+0.986V

Gleichung 1.0

  • V_temp = eine bestimmte Spannung, die der Sensor bei einer bestimmten Temperatur liefert
  • Temp_c = die Temperatur in Grad-Celsius
  • Faktor “0.00355” = 3,55mV pro °C (die Steigung “m”)
  • Faktor “0.986” = bei 0°C gibt der Sensor eine Spannung von 0,986V raus, gewisser Offset (Verschiebung auf der Y-Achse, oder auch “b”)

msp430_temperatur

Der Ausgang von dem Sensor ist an Kanal 10 von dem 10bit-ADC angeschlossen, die Spannung wird digitalisiert. Also muss die Geradengleichung umgestellt werden. Die Gleichung wird nach “Temp_c” umgestellt:

Temp_C=\frac{V_{temp}-0.986V}{0.00355V/^{\circ}C}

Gleichung 1.1

Der ADC-Wert (also die Spannung am Eingang umgewandlet in einen digitalen Wert) berechnet sich aus:

ADC_{int}=\frac{V_{port}}{V_{ref}}*1023

Gleichung 2.0

  • ADC_int = digitaler Spannungswert vom 10bit-ADC als Integer-Wert
  • V_port = analoge EIngangs-Spannung am Port
  • V_ref = Referenzspannung (V_ref liegt bei 1,5V, wird automatisch bei der ADC-Initialisierung ausgewählt und sollte auch gewählt werden!)

Diese Gleichung umgestellt nach V_port ergbit:

V_{port}=\frac{V_{ref}}{1023}*ADC_{int}

Gleichung 2.1

Es gilt:

V_{port}=V_{temp}

Somit kann Gleichung 2.1 in Gleichung 1.1 eingesetzt werden:

 

Gleichung 3.0

Gleichung 3.0 könnte jetzt schon direkt in C programmiert werden, da der MSP430 Float-Berechnungen unterstützt. Float-Berechnungen werden aber nur “emuliert” und fressen somit einiges an Speicher und Zyklen, ist also nicht unbedingt zu empfehlen. Um eine Ganzzahlige-Berechnung durchzuführen muss Gleichung 3.0 noch vereinfacht werden. Dazu wird der Zähler durch 3.55mV/°C geteilt:

Gleichung 3.1

Gleichung 3.2

C-Programm

Ganzahlige-Berechnung

In dem ersten Programm wird die Gleichung 3.2 in C umgesetzt.

/*************************************************
 *     ___       _             _     
 *    |   |_ _ _| |___ ___   _| |___
 *    | | |_'_| . | -_|  _|_| . | -_|
 *    |___|_,_|___|___|___|_|___|___|
 *
 * FILE:     main_int.c
 * Author:   declis (xdec.de)
 ************************************************/

#include <msp430g2452.h>
#define time 500

void main(void)
{
	volatile int m_sec=time;
	volatile long temp_c=0;			//important! reserve 4bytes

	WDTCTL=WDTPW+WDTHOLD;			//stop WDT

	//Channel 10 (Temp. Sensor); ADC10 CLK divider /4; CLK=ADC10OSC
  	ADC10CTL1=INCH_10+ADC10DIV_3;
  	//Vref+=Vr+ and Vss=Vr- ; reference ON (1,5V); S&H time 16x; ADC10 on
  	ADC10CTL0=SREF_1+REFON+ADC10SHT_3+ADC10ON;

  	for(;;)
  	{
  		ADC10CTL0|=ENC+ADC10SC;		//start & enable conversion
  		while(ADC10CTL1&ADC10BUSY);	//ADC busy?

  		//calculate temperature
  		temp_c=(((long)ADC10MEM*422)/1023)-277;

  		while(m_sec--)			//wait 500ms
			__delay_cycles(1000);
		m_sec=time;
  	}
}

Gleitkommazahl-Berechnung

Dieses Programm ist identisch zur ganzzahligen Berechnung, nur die Berechnung der Temperatur wird per Float-Wert berechnet (nicht unbedingt sinnvoll, aber sowas ist mit dem MSP430 möglich und in manchen Fällen kann es brauchbar sein).

/*************************************************
 *     ___       _             _     
 *    |   |_ _ _| |___ ___   _| |___
 *    | | |_'_| . | -_|  _|_| . | -_|
 *    |___|_,_|___|___|___|_|___|___|
 *
 * FILE:     main_float.c
 * Author:   declis (xdec.de)
 ************************************************/

#include <msp430g2452.h>
#define time 500

void main(void)
{
	volatile int m_sec=time;
	volatile float temp_c=0;

	WDTCTL=WDTPW+WDTHOLD;			//stop WDT

	//Channel 10 (Temp. Sensor); ADC10 CLK divider /4; CLK=ADC10OSC
  	ADC10CTL1=INCH_10+ADC10DIV_3;
  	//Vref+=Vr+ and Vss=Vr- ; reference ON (1,5V); S&H time 16x; ADC10 on
  	ADC10CTL0=SREF_1+REFON+ADC10SHT_3+ADC10ON;

  	for(;;)
  	{
  		ADC10CTL0|=ENC+ADC10SC;		//start & enable conversion
  		while(ADC10CTL1&ADC10BUSY);	//ADC busy?

  		//calculate temperature
  		temp_c=(((1.5*(float)ADC10MEM)/1023)-0.986)/0.00355;

  		while(m_sec--)			//wait 500ms
			__delay_cycles(1000);
		m_sec=time;
  	}
}

Zum Vergleich die Größen beider Programme:

Ganzzahl: Code Size – Text: 370 bytes Data: 2 bytes
Gleitkomma:
Code Size – Text: 894 bytes Data: 2 bytes

Berechnung über vordefiniertes Array

Wie im Beispiel-Programm Segmentanzeige über ein Potentiometer steuern (10bit ADC), kann ein Array mit vordefinierten Werten erstellt werden. Es muss nur noch das Feldelement aus dem ADC-Wert berechnet werden (Feldindex).

Nachteil: Es kann nur ein bestimmter Bereich definiert werden und kostet Speicher, je nachdem wie groß der Bereich ausfällt. Nicht mehr dynamisch, da vorher eine Tabelle angefertigt werden muss.

Vorteil: Schnelle Berechnung, möglicherweise niedriger Speicherverbrauch

Zunächst muss Gleichung 3.0 oder 3.2 nach “ADC_int” umgestellt werden:

Daraus kann nun der Integer-Wert berechnet werden (hier in einem Bereich von 15-30°C):

Temp in °CADC_intADC_int/2
15708354
16710355
17713356
18715357
19717358
20720360
21722361
22724362
23727363
24729364
25732366
26734367
27736368
28739369
29741370
30744372

Der berechnete ADC-Wert wird in der 3. Spalte durch 2 geteilt, somit wird der Abstand für das linear interpolierte Feld verringert (weniger Werte, das Feld soll so klein wie möglich bleiben).

Das linear interpolierte Feld lautet folgendermaßen:

15,16,17,18,19,19,20,21,22,23,24,24,25,26,27,28,29,29,30 (19 Werte)

Nun muss bei einem eingelesenen ADC-Wert das zugehörige Feldelement (also die Temperatur) berechnet bzw. ermittelt werden. Der Ablauf:

  1. ADC-Wert einlesen (z.B. 742)
  2. Wertebereichsüberprüfung
  3. ADC-Wert normalisieren: 742/2=371
  4. Feldelement berechnen: Der Anfangswert, also 15°C, hat einen ADC-Wert von 354, dieser Wert wird nun den 371 subtrahiert: 371-354=17
  5. Das 17. Element aus dem Feld lautet: 29°C

Das zugehörige C-Programm:

/*************************************************
 *     ___       _             _     
 *    |   |_ _ _| |___ ___   _| |___
 *    | | |_'_| . | -_|  _|_| . | -_|
 *    |___|_,_|___|___|___|_|___|___|
 *
 * FILE:     main_array.c
 * Author:   declis (xdec.de)
 ************************************************/

#include <msp430g2452.h>
#define time 		500
#define start_temp	354			//15°C (708/2) is first value

const char temp_c_array[]={15,16,17,18,19,19,20,21,22,23,
							24,24,25,26,27,28,29,29,30};

void main(void)
{
	volatile int m_sec=time;
	volatile int temp_c=0;

	WDTCTL=WDTPW+WDTHOLD;					//stop WDT

	//Channel 10 (Temp. Sensor); ADC10 CLK divider /4; CLK=ADC10OSC
  	ADC10CTL1=INCH_10+ADC10DIV_3;
  	//Vref+=Vr+ and Vss=Vr- ; reference ON (1,5V); S&H time 16x; ADC10 on
  	ADC10CTL0=SREF_1+REFON+ADC10SHT_3+ADC10ON;

  	for(;;)
  	{
  		ADC10CTL0|=ENC+ADC10SC;				//start & enable conversion
  		while(ADC10CTL1&ADC10BUSY);			//ADC busy?
  		temp_c=ADC10MEM/2;					//normalize index
  		temp_c-=start_temp;

  		//range test
  		if(temp_c>=temp_c_array[0]||temp_c<=temp_c_array[sizeof(temp_c_array)-1])
  			temp_c=temp_c_array[temp_c];	//get temperature
  		else
  			_NOP(); 						//error or something else

  		while(m_sec--)						//wait 500ms
			__delay_cycles(1000);
		m_sec=time;
  	}
}

3 thoughts on “MSP430 Temperatursensor

  1. hannes

    Hi, mein Dozent meinte ich solle IQMathlib benutzen. Hat jemand eine Ahnung was das ist?

    Reply
  2. Jörg

    Hey, ich soll in meinem Studienprojekt, welches auch den Temp. Sensor beinhaltet, nun einige Testdaten erstellen. Hat wer eine Ahnung was damit gemeint ist?

    MfG

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

This site uses Akismet to reduce spam. Learn how your comment data is processed.