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):
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”)
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:
Gleichung 1.1
Der ADC-Wert (also die Spannung am Eingang umgewandlet in einen digitalen Wert) berechnet sich aus:
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:
Gleichung 2.1
Es gilt:
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 °C | ADC_int | ADC_int/2 |
15 | 708 | 354 |
16 | 710 | 355 |
17 | 713 | 356 |
18 | 715 | 357 |
19 | 717 | 358 |
20 | 720 | 360 |
21 | 722 | 361 |
22 | 724 | 362 |
23 | 727 | 363 |
24 | 729 | 364 |
25 | 732 | 366 |
26 | 734 | 367 |
27 | 736 | 368 |
28 | 739 | 369 |
29 | 741 | 370 |
30 | 744 | 372 |
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:
- ADC-Wert einlesen (z.B. 742)
- Wertebereichsüberprüfung
- ADC-Wert normalisieren: 742/2=371
- Feldelement berechnen: Der Anfangswert, also 15°C, hat einen ADC-Wert von 354, dieser Wert wird nun den 371 subtrahiert: 371-354=17
- 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;
}
}
Hi, mein Dozent meinte ich solle IQMathlib benutzen. Hat jemand eine Ahnung was das ist?
http://www.ti.com/tool/msp-iqmathlib
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