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.

MSP430FR5994: Internal temperature sensor not giving correct values.

Part Number: MSP430FR5994


Hi,

We enabled internal temperature by seeing an example, but we are not getting expected readings.

To enable this TS, we have used TLV calibration points of 2.5V ref. ADC init section is attached for reference.

void AdcInit(void){

    ADC12_B_initParam FsiAdc;
    ADC12_B_configureMemoryParam CMOLG;
    ADC12_B_configureMemoryParam VDO;
    ADC12_B_configureMemoryParam TempSensor;
    DMA_initParam AdcDMA;

    FsiAdc.clockSourceDivider           = ADC12_B_CLOCKDIVIDER_1;
    FsiAdc.clockSourcePredivider        = ADC12_B_CLOCKPREDIVIDER__1;
    FsiAdc.clockSourceSelect            = ADC12_B_CLOCKSOURCE_ADC12OSC;
    FsiAdc.internalChannelMap           = ADC12_B_TEMPSENSEMAP;//ADC12_B_NOINTCH;
    FsiAdc.sampleHoldSignalSourceSelect = ADC12_B_SAMPLEHOLDSOURCE_SC;

    ADC12_B_init(ADC12_B_BASE,&FsiAdc);

    ADC12_B_enable(ADC12_B_BASE);

    ADC12_B_setupSamplingTimer(ADC12_B_BASE,
                               ADC12_B_CYCLEHOLD_64_CYCLES,
                               ADC12_B_CYCLEHOLD_4_CYCLES,
                               ADC12_B_MULTIPLESAMPLESENABLE);

    ADC12_B_setResolution(ADC12_B_BASE,
                          ADC12_B_RESOLUTION_12BIT);

    CMOLG.differentialModeSelect        = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    CMOLG.endOfSequence                 = ADC12_B_NOTENDOFSEQUENCE;
    CMOLG.inputSourceSelect             = ADC12_B_INPUT_A13;
    CMOLG.memoryBufferControlIndex      = ADC12_B_MEMORY_0;
    CMOLG.refVoltageSourceSelect        = ADC12_B_VREFPOS_EXTPOS_VREFNEG_EXTNEG;
    CMOLG.windowComparatorSelect        = ADC12_B_WINDOW_COMPARATOR_DISABLE;

    ADC12_B_configureMemory(ADC12_B_BASE,
                            &CMOLG);

    VDO.differentialModeSelect      = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    VDO.endOfSequence               = ADC12_B_NOTENDOFSEQUENCE;//ADC12_B_ENDOFSEQUENCE;
    VDO.inputSourceSelect           = ADC12_B_INPUT_A14;
    VDO.memoryBufferControlIndex    = ADC12_B_MEMORY_1;
    VDO.refVoltageSourceSelect      = ADC12_B_VREFPOS_EXTPOS_VREFNEG_EXTNEG;
    VDO.windowComparatorSelect      = ADC12_B_WINDOW_COMPARATOR_DISABLE;

    ADC12_B_configureMemory(ADC12_B_BASE,
                            &VDO);


    TempSensor.differentialModeSelect      = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    TempSensor.endOfSequence               = ADC12_B_ENDOFSEQUENCE;
    TempSensor.inputSourceSelect           = ADC12_B_INPUT_TCMAP;
    TempSensor.memoryBufferControlIndex    = ADC12_B_MEMORY_2;
    TempSensor.refVoltageSourceSelect      = ADC12_B_VREFPOS_EXTPOS_VREFNEG_EXTNEG;
    TempSensor.windowComparatorSelect      = ADC12_B_WINDOW_COMPARATOR_DISABLE;

    ADC12_B_configureMemory(ADC12_B_BASE,
                            &TempSensor);

 //   while(REFCTL0 & REFGENBUSY);            // If ref generator busy, WAIT
 //   REFCTL0 |= REFVSEL_2 + REFON;           // Enable i nternal 1.2V reference
 //   while(!(REFCTL0 & REFGENRDY));
   // while(Ref_A_isRefGenBusy (REF_A_BASE));
    Ref_A_enableReferenceVoltage (REF_A_BASE);
 //   Ref_A_setReferenceVoltage (REF_A_BASE,REFVSEL_2);
    Ref_A_enableTempSensor(REF_A_BASE);
//    Ref_A_disableTempSensor(REF_A_BASE);
  //  Ref_A_disableReferenceVoltage(REF_A_BASE);

    AdcDMA.channelSelect        = DMA_CHANNEL_2;
    AdcDMA.transferModeSelect   = DMA_TRANSFER_REPEATED_BLOCK;
    AdcDMA.transferSize         = 3;
    AdcDMA.transferUnitSelect   = DMA_SIZE_SRCWORD_DSTWORD;
    AdcDMA.triggerSourceSelect  = DMA_TRIGGERSOURCE_26;
    AdcDMA.triggerTypeSelect    = DMA_TRIGGER_RISINGEDGE;

    DMA_init(&AdcDMA);

    DMA_setSrcAddress(DMA_CHANNEL_2,
                      (uint32_t) &ADC12MEM0,
                      DMA_DIRECTION_INCREMENT);

    DMA_setDstAddress(DMA_CHANNEL_2,
                      (uint32_t) AdcRawCounts,
                      DMA_DIRECTION_INCREMENT);

    DMA_disableTransferDuringReadModifyWrite();
    DMA_enableRoundRobinPriority();
    DMA_enableInterrupt(DMA_CHANNEL_2);
    DMA_enableTransfers(DMA_CHANNEL_2);
    DMA_startTransfer(DMA_CHANNEL_2);

}
Our object is to achieve correct reading in -10 to -40 C. 

Reading taken in chamber on 5 devices.

Temperature Device1 Device2 Device3 Device4 Device5
-10 0.95 -4.1 -3.97 -2.36 -3
-20 -9.53 -15.3 -15.37 -13.06 -13
-25 -14.29 -20.28 -20.7 -18.04 -18
-30 -18.58 -25 -25 -22.52 -23
-35 -22.62 -29.24 -29.82 -26.75 -27
-40 -26.2 -33.47 -33.88 -30.98 -31
  • >   TempSensor.refVoltageSourceSelect      = ADC12_B_VREFPOS_EXTPOS_VREFNEG_EXTNEG;

    I expect you need to use the internal reference for the temperature sensor (to match the calibration constants), something like:

    >   TempSensor.refVoltageSourceSelect      = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS; // VRSEL=1

  • MSP430 Internal Temperature sensor test results.xlsx

    Hi,

    As suggested, we had taken result by enabling internal reference of 2.5V. Results are attached.

    Regards,

    Pradeep Lokhande

  • Hi Pradeep,

    have you performed the recommended one-point calibration of the temperature sensor offset? According to the data sheet, the offset of the temperature sensor can be up to ±30°C. Without the calibration step, your temperature readings look pretty good.

    Have a look at MSP430FR599x, MSP430FR596x Mixed-Signal Microcontrollers datasheet (Rev. D), page 60.

  • Also, can you post the code you're using to do the arithmetic? I recall doing the formula in integer, and observing that it was important that the operations (the "usual arithmetic conversions") be done in the correct order. I suggest you start with the arithmetic  from Example msp430fr599x_adc12_10.c here:

    https://dev.ti.com/tirex/explore/node?node=ABD7vflrIvcltwOC16GGBw__IOGqZri__LATEST

    The Example does it in float, but that will help you distinguish (a) something in the ADC from (b) something in the arithmetic.

  • Hi,

    We have not performed one-point calibration as it will increase additional stage in manufacturing. To overcome this we have used calibration provided in TLV structure. If we go with one-point calibration, we need new setup for MF. Our temperature range is -20C to -40C, for that we required environment chamber to calibrate it.

    Our assumption was that offset will remains same in all parts, and there will no part to part or slight variation will be there. So, we will use common offset for every unit.

    Now, for arithmetic point we have used same computation as given in example. Source code is attached for your reference.

    Regards,

    Pradeep Lokhande

    #define FSI_MODE_NORMAL             ( 0U )  /* Normal Mode */
    #define FSI_MODE_LOW_TEMP           ( 1U )  /* Low Temperature Mode */
    
    #define TEMPERATURE_CUTOFF          ( -35 ) /* Shutdown/Cutoff tempearture */
    #define TEMPERATURE_HYSTERESIS      ( 5 )   /* Temperature Hysteresis */
    
    #define TEMPERATURE_OFFSET          ( 60 ) /* Offset to shift temperature at positive side */
    #define TEMPERATURE_THRESHOLD_LOW   ( TEMPERATURE_OFFSET + TEMPERATURE_CUTOFF ) /* Lower cutoff threshold */
    #define TEMPERATURE_THRESHOLD_HIGH  ( TEMPERATURE_THRESHOLD_LOW + TEMPERATURE_HYSTERESIS ) /* Upper threshold */
    
    #define TLV_CALADC12_12V_30C  *((unsigned int *)0x1A22)   /* Temperature Sensor Calibration-30 C */
    #define TLV_CALADC12_12V_85C  *((unsigned int *)0x1A24)   /* Temperature Sensor Calibration-85 C */
    
    extern uint16_t AmbTemp;
    static uint8_t FSI_Mode = FSI_MODE_NORMAL;
    /*---------------------------------------------------------------------------*/
    static uint16_t GetTemperatureValue( const uint16_t ADC_Value_p )
    {
        float TempInDegC;
    
        /* Covert ADC value in temperature in Centigrade */
        TempInDegC = (float)(((float)ADC_Value_p - TLV_CALADC12_12V_30C) * (85 - 30)) /
                (TLV_CALADC12_12V_85C - TLV_CALADC12_12V_30C) + 30.0f;
        /* Add temperature offset */
        TempInDegC += TEMPERATURE_OFFSET;
    
        return (uint16_t)TempInDegC;
    }
    /*---------------------------------------------------------------------------*/
    void MeasureTemperature( void )
    {
        uint16_t TempInDegC;
        /* Get current temperature value */
        TempInDegC = GetTemperatureValue( AmbTemp );
        /* Is FSI in Low temperature mode? */
        if( FSI_Mode == FSI_MODE_LOW_TEMP )
        {   /* Is temperature reached to upper threshold limit? */
            if( TempInDegC >= (uint16_t)TEMPERATURE_THRESHOLD_HIGH )
            {   /* Switch to Normal mode */
                FSI_Mode = FSI_MODE_NORMAL;
            }
        }
        else
        {   /* Is temperature reached below cutoff value? */
            if( TempInDegC < (uint16_t)TEMPERATURE_THRESHOLD_LOW )
            {   /* Switch to Low temperature mode */
                FSI_Mode = FSI_MODE_LOW_TEMP;
            }
        }
    }
    

  • Hello Pradeep,

    There is also an Errata on this device family, ADC67, which invalidates the temperature TLV data on any device with lot trace codes <= 87xxxxx.  Page 3 of the errata document shows you how to read the lot trace codes from the package markings.  

    Can you check this? 

    Thanks,

    JD

  • Hi,

    In this testing we have used devices 771xxxx, 841xxxxx and 991xxxx. Images are attached of all devices on which we had performed test. Device numbers also marked in images and its results already shared earlier with you.

    Regards,

    Pradeep Lokhande

  • Hi,

    Can you please confirm, can we use constant offset across all devices if we use same 991 lot of MCU.

    All results already shared with you already.

    Regards,

    Pradeep Lokhande

  • Hello Pradeep,

    I don't see any photos in your latest post, but as mentioned the 77xxx and 84xxx devices would require external calibration.

    For 991xxx lot, you can just use the calibration value.  

    What do you mean constant offset?  By offset, do you mean voltage or ADC counts from the calibration value?  Linearity of the temp sensor is fairly good, so I you should see approximated deltas from the calibration data.  It really depends on how accurate you are trying to be. 

    The most accurate way would be to use both the data points to find the "slope" of the temp sensors voltage, and use that, but I know that method is more math intensive.   

    Thanks,

    JD

  • Hi JD,

    Here offset my mean is with delta in degrees. Like at -40*C, MCU is reading 32*C so here we are getting 8*C delta. If you 991 lot, will we get same delta in all of the devices? If yes, then we can use this as a constant in degree centigrade.

    For rest of the devices <87xxx, could you suggest any reliable temperature sensor device which we can use for one point calibration. 

    Regards,

    Pradeep Lokhande

  • Hi,

    Could you please provide your input on my previous mail.

    Also, let us know how to interpret lot trace code available in TLV structure. We would like to put check in MF on this lot trace code.

    Regards,

    Pradeep Lokhande

**Attention** This is a public forum