This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430G2553 internal temperature sensor

Other Parts Discussed in Thread: MSP430G2553

Hello,

I'm working with the TI example code for the MSP430G2553 internal temperature sensor. I'm not sure how to read the temperature. I have created a IAR project with the following example code. But when I have launched and run it, the code hangs and the IntDegF and IntDeg are 0 or unavailable. I have read that other people had also problem with this code http://e2e.ti.com/support/microcontrollers/msp430/f/166/t/199435.aspx. Can someone please tell me how to read the temperature values? Further, in the example code, long is used for the variables. Due to application specific requirements I can only use one byte to store the temperature value. Do I have to change the code? Thanks a lot!

#include <msp430.h>

long temp;
long IntDegF;
long IntDegC;

int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
__enable_interrupt(); // Enable interrupts.
TACCR0 = 30; // Delay to allow Ref to settle
TACCTL0 |= CCIE; // Compare-mode interrupt.
TACTL = TASSEL_2 | MC_1; // TACLK = SMCLK, Up mode.
LPM0; // Wait for delay.
TACCTL0 &= ~CCIE; // Disable timer Interrupt                 <- code hangs here
__disable_interrupt();

while(1)
{
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled

// oF = ((A10/1024)*1500mV)-923mV)*1/1.97mV = A10*761/1024 - 468
temp = ADC10MEM;
IntDegF = ((temp - 630) * 761) / 1024;

// oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
temp = ADC10MEM;
IntDegC = ((temp - 673) * 423) / 1024;

__no_operation(); // SET BREAKPOINT HERE
}
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void ta0_isr(void)
{
TACTL = 0;
LPM0_EXIT; // Exit LPM0 on return
}

  • Hi Yue,

    I think you are running IAR in simulator mode.  If you go to Project -> Options -> Debugger, you can switch the Driver away from Simulator to use a FET Debugger.

    Regarding the one byte for data, you can write the code to behave this way.  Just make sure your math doesn't overflow any of the variables you use.

    Mike

  • Yue Zhang said:
    Due to application specific requirements I can only use one byte to store the temperature value.

    Ok.... you state that you have to store the temperature as one byte. What is the encoding of the temperature? Is it just the degrees? If so, then you need a signed byte (+127 to -128).

    Going along with the letter of what you wrote, you said store as a byte. So, you can calculate the value as a long and then store that value into a byte variable (with appropriate casting and overflow/underflow checks.)

  • Hi thanks for your replies. I have changed now the simulator mode to debug mode. But I still don't see temperature values if I watch the IntDegC value. How and where exactly do I see the temperature? Sorry I'm new to the MCU.

    Mike Pridgen said:

    Just make sure your math doesn't overflow any of the variables you use.

    Could you please tell me how to change the code to avoid overflow?  I have only changed long to uint8. 

    Thanks!

     

  • Brian Boorman said:

    What is the encoding of the temperature? Is it just the degrees? If so, then you need a signed byte (+127 to -128).

    Yes all I want to see is the temperature in degrees. But how do I see the value?? Could you please give me an example? Thanks!

     

  • Yue Zhang said:
    But how do I see the value??

    I'm not sure what you mean by "see the value".... Can't you just stop the debugger and inspect the variable?

    Or are you interested in how to send the value out to something else (like an LCD or computer)?

    You have to be specific about what you need help with.

  • Yue Zhang said:
    LPM0; // Wait for delay.
    TACCTL0 &= ~CCIE; // Disable timer Interrupt                 <- code hangs here

    No, it hangs on the line above (the debugger stops on this line because while the previous one is executed, this one is fetched and triggers the breakpoint (or if you manually break, PC points to this).

    LPMo basicalls stop the CPU clock. THe CPU halts, It doesn't idle around, it simple freezes. Until an interrupt happens. The interrupt funciton (if ever called) doesn an LPM0_EXIT, so the CPU doesn't freeze again when the ISR exits. THis is doen to synchronize the main code with the delay needed to do the conversion.

    Yue Zhang said:
    Due to application specific requirements I can only use one byte to store the temperature value. Do I have to change the code?

    Well, depends on what this byte shall mean. Signed decigrades above/below 25°C? Absolute temperature in Kelvin? Signed temperature in °C or °F? Difference in 1/10° to the previous value?

  • Hi, thanks for your replies. My mistake was that I have changed long to uint8 in der varible definition. Do I need to calibrate the temperature sensor manually?

    Unfortunately I couldn't find so much information about the temperature sensor in the datasheets and users' manuals. Thanks!

  • Yue Zhang said:
    Do I need to calibrate the temperature sensor manually?

    Soem MSPs contain factory-provided calibration values for e.g. 30°C and 80°C, giving you gain and offset with some simple math.

    The users guide contains a chapter about the temperature sensor. Bascially, its offset and gain varies widely across even same MSP type. So calibration is necessary. I think, the 2553 doesn't have factory-provided calibraton values (whcih makes the vlaue line so cheap - calibraiton takes time and effort, and time is money, especially in mass production).

    For calibration, you may take room temperatur and an simple hot-air oven (set to 50 or 70°C). It is not important to calibrate at a certain temperature, as long as you know the exact temperature at which you were calibrating. And the more the two temperatures are apart, the more precise your calibration results.

    For later work, keep in mind that the temperatur eis the internal die temperature and may differ a little bit form ambient, dependign on current power dissipation.

  • Jens-Michael Gross said:

    Soem MSPs contain factory-provided calibration values for e.g. 30°C and 80°C, giving you gain and offset with some simple math.

    [...]

    I think, the 2553 doesn't have factory-provided calibraton values

    I think that might have been the case when the 2553 was originally released, but ones produced later do have the calibration. The 2553 I got with my launchpad has calibration values for 30°C and 85°C at both 1.5V and 2.5V reference voltages.

    The TLV structure tag for the ADC10 calibration on 2553 is 0x10 as specified on the datasheet, not 0x08 as listed in the MSP430x2xx Family family user guide.

  • Robert Cowsill said:
    I think that might have been the case when the 2553 was originally released, but ones produced later do have the calibration. The 2553 I got with my launchpad has calibration values for 30°C and 85°C at both 1.5V and 2.5V reference voltages.

    AFAIK, one of the reasons why the G series devices are so cheap is that they don't have the (time-consuming) calibration values.

    The first devices of the G series didn't even have DCO calibration values available. I'm surprised to hear that the G2553 now even has ADC values available. This actually nullifies the purpose of the G devices as a separate series.

    But well, if htey have, they have. Don't worry, be happy. :)

**Attention** This is a public forum