6 Measuring VDDIO2

The internal ADC has VDDIO2 divided by 10 as an input, making it possible to measure the voltage of the VDDIO2 domain even with the internal 1.024V reference.

First, we select the 1.024V reference for ADC0 in the ADC0REF register, as shown below. Note that this register is located in the Voltage Reference Section(VREF), not the ADC section.

Figure 6-1. VREF.ADC0REF - Select 1V024 as Reference for ADC0
/*Select the 1.024V referance for ADC0*/
VREF.ADC0REF = VREF_REFSEL_1V024_gc;

Select the VDDIO2DIV10 as input for ADC0 on the positive input pin.

Figure 6-2. ADC0.MUXPOS - Select VDDIO2DIV10 as Input for ADC0
/*Select VDDIO2DIV10 as input for ADC0*/
ADC0.MUXPOS = ADC_MUXPOS_VDDIO2DIV10_gc;

The ADC has built-in support for oversampling. This is especially useful when measuring a DC voltage, as it mitigates a lot of the periodic noise.

Figure 6-3. ADC0.CTRLB - Enabling Oversampling with 16 Samples
/* Enable 16 oversamples*/
ADC0.CTRLB = ADC_SAMPNUM_ACC16_gc; 

Enable ADC0.

Figure 6-4. ADC0.CTRLA - Enable ADC0
/*Enable ADC0*/
ADC0.CTRLA = ADC_ENABLE_bm;

It is now possible to start measurement by writing a ‘1’ to the STCON (Start Conversion) bit in the Command (ADC0.COMMAND) register.

Figure 6-5. ADC0.COMMAND - Start a Measurement
/*Start an ADC conversion*/
 ADC0.COMMAND = ADC_STCONV_bm;

After a conversion is started, it is necessary to wait for it to be done before reading the result. The RESRDY (Result Ready) interrupt flag in the Interrupt Flags (ADC0.INTFLAGS) register will be triggered when a result is ready in the Result (ADC0.RES) register.

Figure 6-6. ADC0.INTFLAGS - Check RESRDY Interrupt Flag
/*Wait for the ADC conversion to be done*/
while(!(ADC0.INTFLAGS & ADC_RESRDY_bm));

The result can be read in the Result (ADC0.RES) register. The result must be divided by 16 due to the oversampling. This is easily done by right shifting the value in ADC0.RES 4 bits. The RESRDY interrupt flag will be automatically cleared when ADC0.RES is read.

Figure 6-7. ADC0.RES - Read the Result
/*Read the RES register and shift the result 4 bits to compensate for the 16 oversamples*/
uint16_t result = (ADC0.RES>>4);