Part Number: MSP430L092
Hello,
We are using the MSP430L092 in a project that requires the temperature of the device to be measured frequently so that other sensor values can be adjusted appropriately. While performing some testing with the temperature sensor, I have come up with a couple of issues. The first is that the value seems to drift, either up or down depending on the ADC configuration. The second is that when using the formula for converting the ADC value to temperature, my values are not even close to the ambient temperature of the device. Below is the test program that I am using:
#include "msp430.h" ; #define controlled include file NAME main ; module name PUBLIC main ; make the main label vissible ; outside this module #define TRUE 1 #define FALSE 0 ; ; Interrupt Vectors ; ORG 0FFE0h DC16 INVINT ; invalid interrupt -- just return DC16 INVINT ; invalid interrupt -- just return DC16 INVINT ; invalid interrupt -- just return DC16 INVINT ; invalid interrupt -- just return DC16 INVINT ; invalid interrupt -- just return DC16 INVINT ; I?O Port P2 (P2IFG.0 to P2FIG.3) DC16 INVINT ; Timer0_A3 (TA0CCR1 CCIFG1) - Sample Interrupt DC16 INVINT ; Timer0_A3 (TA0CCR0 CCIFG0) - Transmit Interrupt DC16 INVINT ; I/O Port P1 (P1IFG.0 to P1IFG.6) DC16 APOOLINT ; A-Pool (CxIFG) DC16 WDTIRQ ; WDTIFG DC16 INVINT ; Timer1_A3 (TA1CCR1 CCIFG1) DC16 INVINT ; Timer1_A3 (TA1CCR0 CCIFG0) - Transmit Interrupt DC16 USERNMI ; User NMI (NMIFLG) DC16 SYSTEMNMI ; System NMI (SVMIFG, VMAIFG) DC16 init ; reset vector address RSEG CSTACK ; pre-declaration of segment RSEG DATA16_Z TempLog DS8 50 ; temperature storage area RSEG CODE ; place program in 'CODE' segment init: MOV #SFE(CSTACK), SP ; set up stack main: NOP ; main program MOV.W #WDTPW+WDTHOLD,&WDTCTL ; Stop watchdog timer ; clear log MOV.W #50,R13 MOV.W #TempLog,R14 Clear1 MOV.B #0,0(R14) INC.W R14 DEC.W R13 JNZ Clear1 ; ; Setup Clocks ; MOV.W #CCSKEY,&CCSCTL0 ; Unlock CCS Clock1 MOV.W #0,&CCSCTL7 ; Clear HF and LF OSC startup fault conditions MOV.W #0,&SFRIFG1 ; Clear OFIFG BIT.W #OFIFG,&SFRIFG1 ; Oscillator flags? JNZ Clock1 MOV.W #0000h,&CCSCTL4 ; set ACLK, SMCLK, and MCLK back to HFCLK MOV.W #DIVA_0+DIVS_0+DIVM_0,&CCSCTL5 ; ACLK/1 (1000 KHz), SMCLK /1 (1000 KHz (default), and MCLK /1 (1000 KHz) MOV.B #0FFh,&CCSCTL0_H ; Lock CCS MOV.W #50,R13 ; count of number of conversions to make and store MOV.W #TempLog,R14 ; pointer to start of log storage area TESTRX0 ; Begin Configuration of the A-POOL registers MOV.W #0,&APCTL MOV.W #REFTSEL,&APTRIM MOV.W #TMPSEN,&APVDIV ; Enable Temperature Sensor MOV.W #CMPON+DBON+CONVON+APREFON+CLKSEL_MCLK,&APCNF ; Enable DAC buffer, conversion, and reference ; Loop doing temperature measurements TESTRX1 #if TRUE MOV.W #OSEL+ODEN+OSWP+APPSEL_4+APNSEL_5,&APCTL ; Set Channels and Start Conversion #else MOV.W #OSEL+ODEN+APPSEL_5+APNSEL_4,&APCTL ; Set Channels and Start Conversion #endif MOV.W #0,&APIFG MOV.W #0,&APINT BIS.W #RUNSTOP+CBSTP+SBSTP,&APCTL ; start conversion #if FALSE ; poll for conversion completion TESTRX2 BIT.W #EOCIFG,&APIFG ; wait for conversion complete flag JZ TESTRX2 #else ; use completion interrupt BIS.W #LPM0+GIE,SR ; enter LMP0 with interrupts enabled #endif MOV.W &APINT,R10 MOV.B R10,0(R14) ; get sensor data and record it INC.W R14 ; bump log pointer DEC.W R13 ; see if done JZ TESTRX3 MOV.W #10000,R12 CALL #Delay ; provide a little delay to mimic normal sampling #if TRUE JMP TESTRX1 #else JMP TESTRX0 #endif TESTRX3 JMP $ ; lock up here when done ;***************************************************************************** ; ; Delay ; ; Used for software delays ; On Entry: ; R12 = count (1 = 100.0 usec) ; ;***************************************************************************** Delay PUSH.W R10 PUSH.W R12 Delay2 MOV.W #8,R10 Delay3 NOP NOP DEC.W R10 JNE Delay3 NOP NOP NOP NOP NOP DEC.W R12 JNE Delay2 POP.W R12 POP.W R10 RET ;**************************************************************************** ; ; System Interrupt Functions ; ;***************************************************************************** ;***************************************************************************** ;* ;* unused/invalid interrupt processing ;* ;***************************************************************************** INVINT NOP RETI ;***************************************************************************** ;* ;* Watchdog Timer interrupt processing ;* ;***************************************************************************** WDTIRQ NOP RETI ;***************************************************************************** ;* ;* USER NMI interrupt processing ;* ;***************************************************************************** USERNMI NOP RETI ;***************************************************************************** ;* ;* SYSTEM NMI interrupt processing ;* ;***************************************************************************** SYSTEMNMI NOP RETI ;***************************************************************************** ;* ;* APOOL interrupt processing ;* ;***************************************************************************** APOOLINT NOP MOV.W #0,&APIFG ; clear interrupt flag BIC.W #LPM0,0(SP) ; modify SP so it enters active mode RETI END
During the test, I delay about 1 second between samples to help mimic the actual temperature sampling rate that will be used in the application (which will be 1 sample per minute, but gets similar results to my testing here). If I use APPSEL_5+APNSEL_4, the temperature drifts upward. Typical ADC values are shown below:
00 a4 a3 a4 a4 a5 a5 a4 a5 a5 a5 a5 a5 a6 a6 a6
a7 a7 a7 a7 a8 a8 a8 a9 a8 aa a9 aa a9 aa a9 aa
ab aa ab ab ab ac ac ac ad ad ad ae ad ad ae ad
ae ae
If I use the OSWP+APPSEL_4+APNSEL_5 configuration, the values drift downward as shown below:
00 a7 a8 a8 a7 a8 a7 a7 a7 a6 a6 a6 a6 a6 a6 a6
a5 a5 a4 a4 a5 a2 a3 a3 a3 a3 a3 a2 a3 a2 a3 a2
a2 a2 a1 a2 a1 a2 a2 a0 a1 a0 a0 a1 9f a0 a1 9f
a0 9f
It doesn't seem to make any difference whether I poll for the ADC conversion or use the conversion completion interrupt. It also doesn't seem to make a difference whether I reset all of the configuration parameters or the subset shown in the code above. What would cause this drift and what would some possible solutions be?
On the second issue, using the formula in the MSPL092 example code:
DegC = (((ADCValue - 179) * 125)/58) + 30
With a value of 0xA7, this would provide a resulting temperature of -.2 degC, which is not the device's temperature. I know this formula is derived from
Vsensor = Voffset25 + TCsensor*(Ta - 30)
which is from page 30 of the MSP430L092 datasheet. First of all, am I doing the calculation correctly? Secondly, assuming I am, then the values of Voffset25 and/or TCsensor must be different for my system. How can I find these values? Lastly, if that formula that I am using is correct and I am using it correctly, that would mean that each step in the ADC value would correspond to ~2.1 degC step, which is no where sensitive enough for our purpose. So I am hoping that I am doing something wrong, or there is a way of adjusting the sensitivity of this sensor.
Looking forward to any assistance you can provide.
Regards,
Robert Buchanan