EFR32 ADC Internal Temperature Sensor

by <a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero Employee</font></font> </a> PhillipB on ‎12-28-2016 04:29 PM

Question

How can I measure temperature using the internal ADC temperature sensor?

Answer

The "Temperature Measurement" subsection of the ADC chapter in the reference manual contains an expression for this temperature result (TCELSIUS) in terms of the following parameters:

 

  • CAL_TEMP - available in the Device Information (DI) Page, see "DI Page Entry Map" section in Reference Manual for more information
  • ADC0CAL3_TEMPREAD1V25 - also available in DI page
  • V_TS_SLOPE - available in the device Datasheet
  • VFS - specified as 1.25V (1250mV) in the provided expression
  • ADC_result - ADC measurement at 1.25V VFS option and 12-bit resolution

The "inttemp" example for the EFM32 Pearl Gecko (available in-full within Simplicity Studio) demonstrates in ConvertToCelsius() how this technique is implemented using the DI contents on the Pearl Gecko and the formula provided in section 22.3.8.9 "Temperature Measurement" of the Pearl Gecko Reference Manual. Though the variable names are slightly different, this is an identical procedure to that given in section 23.3.4.1 "Temperature Measurement" of the EFR32BG1 Reference Manual.

 

 

/**************************************************************************//**
 * @brief Convert ADC sample values to celsius.
 * @detail See section 25.3.4.1 in the reference manual for detail on
 *   temperature measurement and conversion.
 * @param adcSample Raw value from ADC to be converted to celsius
 * @return The temperature in degrees celsius.
 *****************************************************************************/
static float ConvertToCelsius(int32_t adcSample)
{
  uint32_t calTemp0;
  uint32_t calValue0;
  int32_t readDiff;
  float temp;

  /* Factory calibration temperature from device information page. */
  calTemp0 = ((DEVINFO->CAL & _DEVINFO_CAL_TEMP_MASK)
              >> _DEVINFO_CAL_TEMP_SHIFT);

  calValue0 = ((DEVINFO->ADC0CAL3
                /* _DEVINFO_ADC0CAL3_TEMPREAD1V25_MASK is not correct in
                    current CMSIS. This is a 12-bit value, not 16-bit. */
                & 0xFFF0)
               >> _DEVINFO_ADC0CAL3_TEMPREAD1V25_SHIFT);

  if ((calTemp0 == 0xFF) || (calValue0 == 0xFFF))
  {
    /* The temperature sensor is not calibrated */
    return -100.0;
  }

  /* Vref = 1250mV
     TGRAD_ADCTH = 1.835 mV/degC (from datasheet)
  */
  readDiff = calValue0 - adcSample;
  temp     = ((float)readDiff * 1250);
  temp    /= (4096 * -1.835);

  /* Calculate offset from calibration temperature */
  temp     = (float)calTemp0 - temp;
  return temp;
}