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.

MSP430FR6972 internal temperature readings problems

Other Parts Discussed in Thread: MSP430FR6979

Hi,

I am using the following code to read the internal temps and I get erratic readings, 83, 79, 80, 78, 92, 79...

What would cause this, and how to mitigate?

Thanks, Tom

								  while(REFCTL0 & REFGENBUSY);              // If ref generator busy, WAIT
								  REFCTL0 |= REFVSEL_0 + REFON;             // Enable internal 1.2V reference

								  ADC12CTL0 &= ~ADC12ENC;                   // Disable ADC12
								  ADC12CTL0 = ADC12SHT0_8 + ADC12ON;        // Set sample time
								  ADC12CTL1 = ADC12SHP;                     // Enable sample timer
								  ADC12CTL3 = ADC12TCMAP;                   // Enable internal temperature sensor
								  ADC12MCTL0 = ADC12VRSEL_1 + ADC12INCH_30; // ADC input ch A30 => temp sense
								  while(!(REFCTL0 & REFGENRDY));            // Wait for reference generator to settle
								  ADC12CTL0 |= ADC12ENC | ADC12SC;   		// Start sampling/conversion
								  while (!(ADC12IFGR0 & BIT0));				// Is the sample ready?
								  temp = ADC12MEM0;               			// Read conversion result

  • Hi Tom,

    I debugged the code you provided and didn't experience the issue you're seeing. Are you calibrating the temp sensor before reading value from it and would you mind posting the rest of your code?

    Best regards,
    Caleb Overbay
  • Hi Caleb,

    Here is the entire function I call, how do I calibrate prior to reading??

    #define CALADC12_12V_30C *((unsigned int *)0x1A1A) // Temperature Sensor Calibration-30 C See device datasheet for TLV table memory mapping
    #define CALADC12_12V_85C *((unsigned int *)0x1A1C) // Temperature Sensor Calibration-85 C
    unsigned int temp;
    volatile float temperatureDegC, temperatureDegF;

    while(REFCTL0 & REFGENBUSY); // If ref generator busy, WAIT
    REFCTL0 |= REFVSEL_0 + REFON; // Enable internal 1.2V reference

    ADC12CTL0 &= ~ADC12ENC; // Disable ADC12
    ADC12CTL0 = ADC12SHT0_8 + ADC12ON; // Set sample time
    ADC12CTL1 = ADC12SHP; // Enable sample timer
    ADC12CTL3 = ADC12TCMAP; // Enable internal temperature sensor
    ADC12MCTL0 = ADC12VRSEL_1 + ADC12INCH_30; // ADC input ch A30 => temp sense
    while(!(REFCTL0 & REFGENRDY)); // Wait for reference generator to settle
    ADC12CTL0 |= ADC12ENC | ADC12SC; // Start sampling/conversion
    while (!(ADC12IFGR0 & BIT0)); // Is the sample ready?
    temp = ADC12MEM0; // Read conversion result
    ADC12CTL0 = 0;
    temperatureDegC = (float)(((long)temp - CALADC12_12V_30C) * (85 - 30)) /
    (CALADC12_12V_85C - CALADC12_12V_30C) + 30.0f;
    temperatureDegF = temperatureDegC * 9.0f / 5.0f + 32.0f;
  • Hi Tom,

    I worded my previous response incorrectly. I just wanted to make sure you were using the calibration values defined at the beginning of the example and it looks like you are. I apologize for the misunderstanding. However, I'm not seeing anything wrong with the code you've posted and I'm not experiencing the issue myself. When I saw that you were setting ADC12CTL0 = 0, my first thought was that you were overwriting the sample and hold time, but these can't be changed unless ADC12ENC = 0. I would still be careful setting the entire register to 0 and instead do something like ADC12CTL0 &= ~ADC12ENC  to stop conversions.

    As far as next steps, do you have another MSP430FR6979 you can test the code on to see if the results are consistent across devices? This way we could focus on whether the issue is the software or hardware.

    Also, you may want to try switching to a different reference voltage. Instead of using the 1.2V internal reference, let's try the 2.0V internal reference. This can be done by changing to following: 

      REFCTL0 |= REFVSEL_1 + REFON;             // Enable internal 2.0V reference

    and: 

    #define CALADC12_20V_30C *((unsigned int *)0x1A1E) // Temperature Sensor Calibration-30 C
    #define CALADC12_20V_85C *((unsigned int *)0x1A20) // Temperature Sensor Calibration-85 C

    Also, dont forget to to change the name of the calibration values you use when performing calculations to the ones above. Try these out and see if you get the same results.

    Best regards, 
    Caleb Overbay

  • Caleb,
    Good idea, I tried the 2.0v ref and used the corrected calib vals and same exact issue.

    It's not easy to swap the chip out. Not sure what else to try.

    Thanks, Tom
  • Hi Tom, 

    It might help to implement ADC offset and gain calibration as well. ADC offset and gain calibration are stored at 01A6h and 01A8h of the TLV, respectively. They are used to further correct the ADC value using the equation ADC(final) = ADC(VREF_calibrated)*(CAL_ADC_GAIN_FACTOR/32768)+CAL_ADC_OFFSET.

    However, even when using calibration on the temp sensor and the ADC, you should expect up to +/- 3 degrees Celsius error because of the nature of the sensor. 

    Finally, further error can be introduced from noise on the internal ADC caused by fluctuations in the AVcc supply. You may want to check that this supply is steady.

    Other than that, the values you're seeing are still within the +/-3 degree Celsius range with the possible exception of the 92F value. Unforturnately, If you'd like highly accurate temperature readings, an external temp sensor is more appropriate.

    Best regards, 

    Caleb Overbay

**Attention** This is a public forum