5.1 Setup Tempsense

Todo:
  • Edit adc_init() to configure ADC in Single mode for temperature measurement
  • Find the results by debugging the code and adding breakpoints at the temperature variables
  1. Configure the reference voltage to the one recommended in the data sheet for the internal temperature sensor:
    ADC0.CTRLC = ADC_REFSEL_1024MV_gc | (TIMEBASE_VALUE << ADC_TIMEBASE_gp);
    Info: The measured voltage has an almost linear relationship with the temperature. Due to process variations, the temperature sensor output voltage varies between individual devices at the same temperature. The compensation factors determined during the production test are stored in the Signature Row. These compensations factors are generated for the internal 1.024V reference.
  2. Configure the ADC to use the internal temperature sensor by writing to the MUXPOS register:
    ADC0.MUXPOS = ADC_MUXPOS_TEMPSENSE_gc;
  3. Configure sample duration using the variable TEMPSENSE_SAMPDUR:
    ADC0.CTRLE = TEMPSENSE_SAMPDUR;
    Info: The variable calculates the sample duration for the temperature sensor. As per the data sheet, Sample Duration should be greater than or equal to 32 μs × fCLK_ADC, expressed in the code below:
    #define TEMPSENSE_SAMPDUR ((uint8_t) ceil(F_CPU*0.000032/2))
    The division by two is because fCLK_ADC = fCLK_CPU/2.
  4. Configure the ADC prescaler to produce the desired CLK_PER/2 ADC clock by writing the CTRLB register:
    ADC0.CTRLB = ADC_PRESC_DIV2_gc;
    Result: Code for initializing the ADC is complete, and the expected result is listed below:
    void adc_init()
    {
    	ADC0.CTRLA = ADC_ENABLE_bm;
    	ADC0.CTRLB = ADC_PRESC_DIV2_gc;
    	ADC0.CTRLC = ADC_REFSEL_1024MV_gc | (TIMEBASE_VALUE << ADC_TIMEBASE_gp);
    	
    	ADC0.CTRLE = TEMPSENSE_SAMPDUR;
    	ADC0.MUXPOS = ADC_MUXPOS_TEMPSENSE_gc; /* ADC Internal Temperature Sensor */
    	ADC0.COMMAND = ADC_MODE_SINGLE_12BIT_gc; /* Single 12-bit mode */ 
    }
  5. Add calibration variables for the measurement. Place the variables before the while(1) loop:
    int8_t sigrow_offset = SIGROW.TEMPSENSE1;
    uint8_t sigrow_gain = SIGROW.TEMPSENSE0; 
    Info:

    The content of the Signature Row fuses (SIGROW) is preprogrammed and cannot be altered. SIGROW holds information such as device ID, serial number, and calibration values.

    The Temperature Sensor Calibration registers contain correction factors for temperature measurements from the on-chip sensor. SIGROW.TEMPSENSE0 is a correction factor for the gain/slope (unsigned) and SIGROW.TEMPSENSE1 is a correction factor for the offset (signed).

  6. Add the code below to the main while loop to measure temperature in Kelvin and Celcius:
    		adc_reading = ADC0.RESULT >> 2; /* 10-bit MSb of ADC result with 1.024V internal reference */
    		uint32_t temp = adc_reading - sigrow_offset;
    		temp *= sigrow_gain; /* Result might overflow 16-bit variable (10-bit + 8-bit) */
    		temp += 0x80; /* Add 256/2 to get correct integer rounding on division below */
    		temp >>= 8; /* Divide result by 256 to get processed temperature in Kelvin */
    		temperature_in_K = temp;
    		temperature_in_degC = temperature_in_K - 273;
    
    		
    Info: The temperature measurement uses the following formula:
    T = ( ADC Result Offset Correction  ) × Gain Correction 256
  7. Verify that the solution builds with no errors by selecting Build → Build Solution from the top menu bar in Microchip Studio or pressing the F7 key.
  8. Set a breakpoint on the _delay_ms to be able to watch temperature_in_K and temperature_in_K. Figure 5-1 shows the breakpoint as red dots on the left pane of the window.
    Tip: Breakpoints can be added by clicking on the left pane to the left of where the line of code is.
  9. Flash the device by selecting Debug → Continue for the top menu bar in Microchip Studio or pressing the F5 key.
  10. Select and right-click temperature_in_K and temperature_in_degC, and choose Add watch.
  11. Go through the code by pressing the F5 key and watch as the values of the variables change.
    Result: Code for initializing the ADC is complete and the expected result is shown in Figure 5-1:
    Figure 5-1. Assignment 4: Temperature Sensor Debugging
    Tip: To toggle the displayed value between decimal and hexadecimal, right-click a variable and press Hexadecimal Display.