30.3.2.6 Temperature Measurement

The temperature measurement is based on an on-chip temperature sensor. For a temperature measurement, follow these steps:
  1. Configure the internal voltage reference to 1.1V: in VREF.CTRLA, write ADC0REFSEL=0x1 for ADC0. For ADC1, write ADC1REFSEL=0x1 in VREF.CTRLC.
  2. Select the internal voltage reference by writing the REFSEL bits in ADC.CTRLC to 0x0.
  3. Select the ADC Temperature sensor channel by writing the MUXPOS bits in the MUXPOS register (ADC.MUXPOS) to 0x1E. This enables the temperature sensor.
  4. In ADC.CTRLD Select INITDLY 32 µs × f CLK_ADC
  5. In ADC.SAMPCTRL Select SAMPLEN 32 µs × f CLK_ADC
  6. In ADC.CTRLC Select SAMPCAP = 5 pF
  7. Acquire the temperature sensor output voltage by starting a conversion.
  8. Process the measurement result as described below.

The measured voltage has a linear relationship to the temperature. Due to process variations, the temperature sensor output voltage varies between individual devices at the same temperature. The individual compensation factors are determined during the production test and saved in the Signature Row:
  • SIGROW.TEMPSENSE0 is an gain/slope correction
  • SIGROW.TEMPSENSE1 is a offset correction

In order to achieve accurate results, the result of the temperature sensor measurement must be processed in the application software using factory calibration values. The temperature (in Kelvin) is calculated by this rule:

Temp = (((RESH << 8) | RESL) - TEMPSENSE1) * TEMPSENSE0) >> 8

RESH and RESL are the high and low byte of the Result register (ADC.RES), and TEMPSENSEn are the respective values from the Signature row.

It is recommended to follow these steps in user code:

int8_t sigrow_offset = SIGROW.TEMPSENSE1;  // Read signed value from signature row
uint8_t sigrow_gain = SIGROW.TEMPSENSE0;    // Read unsigned value from signature row
uint16_t adc_reading = 0;   // ADC conversion result with 1.1 V internal reference 

uint32_t temp = adc_reading - sigrow_offset;
temp *= sigrow_gain;  // Result might overflow 16 bit variable (10bit+8bit)
temp += 0x80;               // Add 1/2 to get correct rounding on division below
temp >>= 8;                 // Divide result to get Kelvin 
uint16_t temperature_in_K = temp;