Topics

Games
Sound & Music
Watches & Clocks
Wireless
GPS
Power Supplies
Computers
Graphics
Lighting
Thermometers
Educational
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, 1, and 2-series

ATmega1608
ATmega4808
ATmega4809
ATtiny1604
ATtiny1614
ATtiny202
ATtiny3216
ATtiny3224
ATtiny3227
ATtiny402
ATtiny404
ATtiny414
ATtiny814

AVR DA/DB/DD/EB-series

AVR128DA28
AVR128DA32
AVR128DA48
AVR128DB28
AVR128DB48
AVR64DD14
AVR16DD20
AVR32DD28
AVR16EB28

ARM

ATSAMD21
RP2040
RA4M1

RISC-V

ESP32-P4

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