Topics

► Games

► Sound & Music

► Watches & Clocks

► GPS

► Power Supplies

► Computers

► Graphics

► Thermometers

► Wearables

► Test Equipment

► Tutorials

► Libraries

► PCB-Based Projects

By processor

AVR ATtiny

► ATtiny10

► ATtiny2313

► ATtiny84

► ATtiny841

► ATtiny85

► ATtiny861

► ATtiny88

AVR ATmega

► ATmega328

► ATmega1284

AVR 0-series and 1-series

► ATmega4809

► ATtiny1604

► ATtiny1614

► ATtiny3216

► ATtiny3227

► ATtiny402

► ATtiny404

► ATtiny414

► ATtiny814

AVR DA/DB-series

► AVR128DA28

► AVR128DA32

► AVR128DA48

► AVR128DB28

ARM

► ATSAMD21

► RP2040

► RA4M1

About me

  • About me
  • Twitter
  • Mastodon

Feeds

RSS feed

Measuring Your Own Supply Voltage 2

This appendix to the original article Measuring Your Own Supply Voltage shows an alternative way of measuring the supply voltage on an AVR DA-Series microcontroller, using the 'backwards' technique used on older ATtiny and ATmega chips.

Measuring VDD on an AVR128DA28 - alternative method

The 'backwards' technique is to make VDD the voltage reference for the ADC, and then measure a fixed voltage reference of 1.024V from the VREF peripheral, via the Analog Comparator's DACREF voltage divider.

Setting up the ADC

First set up the ADC as follows:

  • Set the ADC's voltage reference to VDD.
  • Set the Analog Comparator's shared voltage reference to 1.024V.
  • Set Analog Comparator 0's DACREF value to 255 (not strictly necessary as it's the default).
  • Set the ADC MUXPOS so the ADC measures DACREF0.

Here's the code to implement this:

void ADCSetup () {
  VREF.ADC0REF = VREF_REFSEL_VDD_gc;
  VREF.ACREF = VREF_REFSEL_1V024_gc;
  AC0.DACREF = 255;                                    // Maximum DACREF0 voltage
  ADC0.MUXPOS = ADC_MUXPOS_DACREF0_gc;                 // Measure DACREF0
ADC0.CTRLC = ADC_PRESC_DIV64_gc; // 375kHz clock ADC0.CTRLA = ADC_ENABLE_bm; // Single, 12-bit }

Reading the voltage

Here's the routine to measure the supply voltage:

void MeasureVoltage () {
  ADC0.COMMAND = ADC_STCONV_bm;                        // Start conversion
  while (ADC0.COMMAND & ADC_STCONV_bm);                // Wait for completion
  uint16_t adc_reading = ADC0.RES;                     // ADC conversion result
  uint16_t voltage = 41779/adc_reading;
  Buffer[0] = voltage/10; Buffer[1]= voltage%10;
}

DACREF0 is 255/256 times the Analog Comparator reference, which we've set to 1.024V. So suppose we have a 12-bit reading of R. Then:

R4096
× VDD = 1.024 ×
255256

which gives:

VDD = 1.024 ×
255256
×
4096R
 = 
4177.9R
volts

To get VDD in tenths of a volt we therefore need to divide 41779 by the ADC reading.

The minimum voltage we can measure this way is 4177.9/4095 or 1.02V, which is below the minimum supply voltage of 1.8V.


blog comments powered by Disqus