ADC programming. ATmega8 microcontroller ADC, digital voltmeter. Macro to start the conversion

Many AVR have on board ADC successive approximation.
ADC this is ten-bit, but with an accuracy of +/- 2 least significant digits, it can be safely considered eight-bit :) Since the lower two digits are always some kind of garbage, not similar to a useful signal. Nevertheless, this is a good tool for monitoring voltage, in eight-bit mode it has 256 counts and outputting the sampling frequency up to 15kHz(15 thousand samples per second).

Source Configuration
Signal in ADC supplied through a multiplexer, from one of eight (at best, often less) inputs. Input selection is carried out by register ADMUX, or rather its bits MUX3…MUX0. The number written there determines the selected input. For example, if MUX3..0 = 0100 , then the output is connected ADC4.

In addition, there are several service bit combinations MUX, used for calibration.
For example, 1110 connects to ADC internal 1.22 volt reference. And if we write in MUX3..0 all units, then ADC will be planted on the ground from the inside. This is useful for identifying various noises and interferences.

In the elders AVR families Mega(8535, 16, 32, 128) it is possible to enable ADC in mode differential input. This is when two inputs come different voltages. One is subtracted from the other, and can also be multiplied by the gain factor. Why is this necessary? And, for example, when you need to measure the voltage imbalance of the measuring bridge. With some strain gauge bridge, with an input voltage of five volts, the output signals will differ from each other by only 30 mV, so catch it. And so I applied the differential input, adjusted the required gain and beauty!

Table of values MUX3..0 I won’t list the differential switch here, it’s easily found in the datasheet, it’s called “ Input Channel and Gain Selections". I will explain only one subtle point. In the differential input selection mode, the following combinations occur: the first input is ADC0 and the second input is also ADC0 Well, and the gain factor too. How so? After all, for differential input you need two different entrance! At first I thought there was a typo, I pulled up the datasheet on another AVR - the same top. Then I looked at the text below and realized that this is for zero calibration. Those. Before we start collecting differential data, we need to short-circuit the inputs to understand that we have zero. So, the combination when two inputs are connected to one leg is the same calibration short circuit of the inputs. You do the first transformation on such garbage, you get zero offset. And then you subtract it from all the obtained values, which dramatically increases the accuracy.

Multiplexing of channels is carried out only after the conversion is completed, so you can safely start ADC to calculate the input values, write the parameters of another input into MUX3..0, and prepare to take data from there.

Reference signal selection
This is the maximum voltage that will be taken as the maximum during measurements. The reference voltage should be as stable as possible, without interference or fluctuations - the accuracy of operation depends dramatically on this ADC. It is specified in bits REFS1..0 register ADMUX.

  • By default it's there REFS1..0 = 00- external AND HE, connected to the input AREF. This can be the voltage from a special reference voltage microcircuit, or from some zener diode, if you need to measure a small voltage, noticeably less than the supply voltage, say from 0 to 1 volt, then to be more accurate and so that it does not get lost against the background of a five-volt power supply, then at AREF we set the reference voltage to 1 volt.
  • REFS1..0 = 01- here the supply voltage is simply taken. Almost everyone has Meg with ADC there is an entrance AVCC- this is the supply voltage for ADC and the port on which it is ADC hanged. It is advisable to serve plus food there through L.C. filter to avoid distortion.
  • REFS1..0 = 11- internal voltage reference at 2.56 volts. To be honest, I really didn’t like the quality of this source. Testimony with him ADC They swim like shit in an ice hole. But if it is impossible to ensure a smooth and stable voltage supply to AREF or AVCC then it'll go for a ride. By the way, internal AND HE connected to output AREF so you can hang the conder there and try to smooth it out a little. A little, but it helps.
Selecting the conversion start mode
In the register SFIOR under ADC as many as three bits are allocated. ADTS2..0 which control launch modes ADC.
  • By default ADTS2..0 = 000 and this means that the transformation is ongoing. Well, or by manual start.
  • ADTS2..0 = 001— launch ADC from an analog comparator. Damn convenient. For example, in order not to constantly measure the input value, but to program the comparator so that as soon as it gets something above the threshold, it will immediately seize this matter for ADC.
  • ADTS2..0 = 010— trigger from external interrupt INT0
  • ADTS2..0 = 011- by coincidence of the timer T0
  • ADTS2..0 = 100- on timer overflow T0
  • ADTS2..0 = 101- by coincidence with the timer T1
  • ADTS2..0 = 110— On timer overflow T1
  • ADTS2..0 = 111— By event “capture” of the timer T1
ADC operating speed
Sampling frequency ADC specified in prescaler bits ADPS2…0 register ADCSR. The table itself can be looked at in the datasheet for the corresponding MK; I will only say that the most optimal accuracy of the module’s operation is ADC is within 50…200 kHz, so the prescaler should be adjusted based on these considerations. As the frequency increases, the accuracy decreases.

Interrupts.
Naturally ADC there are interruptions. In this case, it is an interrupt at the end of the conversion. It can be enabled with a bit ADIE, and it brazenly manually fires at the flag ADIF(register ADCSRA). Flag ADIF automatically removed when going to the interrupt vector ADC.

Data from ADC collapse into a register pair ADCH:ADCL where can they be picked up from? And there is one cool moment here. Our register pair is 16-bit, but ADC has a bit depth 10bit. As a result, only one register is fully occupied, and the second occupies only the remaining two bits. So, the alignment can be either right-aligned - the most significant two bits in ADCH, and the younger ones in ADCL, or left - the most significant bits in ADCH, and the two least significant bits in ADCL.

[x][x][x][x][x][x] : or : [x][x][x][x][x][x]


Why was this done? And this bit depth sampling so uniquely organized. As I already said, in the lower ranks there is still garbage and noise (at least I could not get rid of them, no matter how hard I tried). So here it is. Align to the left. And we rake in the senior ranks only from the ADCH register, and we score on the younger one. In total, our number of samples becomes 256. The bit is responsible for alignment ADLAR in the register ADMUX 0 — alignment to the right border, 1 — to the left.

Start conversion manually or continuously.
To start the conversion you must first enable the work ADC, setting the bit ADEN in the register ADCSR and in the same register poke a bit ADSC. To start a continuous conversion (one after another), you also need to set the bit ADFR (ADATE In some AVR).

Increasing accuracy by going into hibernation.
To improve accuracy, so that internal circuits ADC don't make a mess with your noise, you can start ADC V sleep mode. Those. the process stops, everything freezes. Only works WatchDog and block ADC. As soon as the data is counted, an interrupt is generated that wakes up the processor, it goes to the interrupt handler from ADC and then everything takes its course.

Now I’ll give a couple of examples of simple initialization and working with ADC. Microcontroller ATMega16

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 < The input signal comes from the zero channel of the ADC.

; My favorite macro for writing to ports:)))) .MACRO outi LDI R16,@1 OUT @0,R16 .ENDM ; ADC Init - Initializes the ADC. This can be put somewhere at the beginning of the code OUTI ADCSRA,(1< The input signal comes from the zero channel of the ADC.

What to do next? Nothing! Sit and wait for interruption!
When it arrives, the processor will throw it on the vector and then you can either rewrite the data from ADCH:ADCL to another place, or some simple processing right there, without leaving the cash register. Like averaging.

Option two, with hibernation. In principle, everything is the same, you just need to turn off the automatic restart of conversion. Next in the register MCUCR in bits SM2..0 select mode ADC Noise Reduction SM2..0 = 001, and then, immediately after startup, send the processor into hibernation with the command SLEEP. As soon as he falls asleep it will work ADC, will do the conversion and wake up on the interrupt.

It looks like this:

; ADC Init - Initializes the ADC. This can be put somewhere at the beginning of the code OUTI ADMUX, 0b01000101 ; And here we choose where we will get the signal from; REFS -- 0b000101 the first two bits are the voltage from the AVCC input; ADLAR --0b0100101 the next bit is right aligned; MUX -- 0b010 The entry signal comes from the 5th leg. OUTI MCUCR,0b10010000 ; Set the sleep mode bits to Noise Reduction; And this is the body of the main program Main Prog: OUTI ADCSRA,(1<

Well, to increase accuracy, you should follow a number of rules for connecting power to ADC module, for example, supply voltage to the input AVCC through the choke, install capacitors and more ground around. Everything about this is in the datasheet. I will soon post an example of a working program - an example for ADC And UART.

ADC – analog-to-digital converter (ADC-Analog-to-Digital Converter). Converts an analog signal to a digital one. Bit depth ADC determines the accuracy of signal conversion. Conversion time is the corresponding ADC operating speed. The ADC is built into many microcontrollers of the family AVR and simplifies the use of the microcontroller in any control circuits where it is necessary to digitize a certain analog signal.

Let's consider the principle of operation ADC. For conversion, we need a reference voltage source and the actual voltage that we want to digitize (the voltage that is converted must be less than the reference). We also need a register where the converted value will be stored, let's call it Z. Input voltage = Reference voltage*Z/2^N, where N is the ADC bit size. Let's agree that this register, like the ATmega8, is 10-bit. The transformation in our case takes place in 10 stages. MSB Z9 is set to one. Next, voltage is generated (Reference voltage*Z/1024), this voltage is compared with the input using an analog comparator, if it is greater than the input, bit Z9 becomes equal to zero, and if less, remains one. Next we move on to the bit Z8 and using the method described above we obtain its values. After register calculation Z completed, a certain flag is set, which signals that the conversion is completed and the resulting value can be read. The accuracy of the conversion can be greatly influenced by interference and interference, as well as the conversion speed. The slower the transformation occurs, the more accurate it is. Noise and interference should be dealt with using inductance and capacitance, as the manufacturer advises in the datasheet:

In microcontrollers AVR the pin can be used as a reference voltage source AREF, or internal sources 2.56V or 1.23V. Also, the source of the reference voltage can be the supply voltage. Some cases and models of microcontrollers have separate pins for powering the ADC: AVCC And AGND. conclusions ADCn– channels ADC. From which channel the signal will be digitized can be selected using a multiplexer.
Now let's demonstrate with an example what was said above. Let's build a model that will work like a voltmeter with a digital scale. Let's agree that the maximum measured voltage will be 10V. Also let our layout display the contents of the register on the LCD ADC.

To enlarge, click on the diagram.

Connecting the microcontroller and LCD WH1602A standard. X1– 4 MHz quartz resonator, capacitors C1, C2– 18-20 pF. R1-C7 the circuit at the reset pin is 10 kOhm and 0.1 µF, respectively. Signal LED D1 and limiting resistor R2 200 Ohm and R3– 20 Ohm. LCD contrast adjustment – VR1 at 10 kOhm. We will use the built-in 2.56V reference voltage source. Using a divider R4-R5 we will achieve a maximum voltage of 2.5V at the input PC0, with a voltage on the probe of 10V. R4– 3 kOhm, R5– 1 kOhm, their rating needs to be taken carefully, but if it is not possible to select exactly the same, you can make any resistive divider 1:4 and programmatically correct the readings if necessary. A 10 µH inductor and a 0.1 µF capacitor to eliminate noise and interference ADC not shown on the diagram. Their presence is implied by itself if used ADC. Now it's up to the program:

(codecitation style="brush: xml;") #include

#define RS 2 //RS=PD2
#define E 3 //E=PD3

#define TIME 10 //Time delay constant for LCD
//MK clocking frequency - 4 MHz

#define R_division 3.837524 //=R4/R5 constant

Unsigned int u=0; //Global variable with the contents of the transformation

Void pause (unsigned int a)
{
unsigned int i;
for (i=a;i>0;i--);
}

Void lcd_com (unsigned char lcd) //Transmitting LCD command
{
unsigned char temp;

Temp=(lcd&~(1<PORTD=temp; //Output the most significant tetrad of the command, RS, E signals to portD
PORTD=temp&~(1<
temp=((lcd*16)&~(1<PORTD=temp; //Output the low order tetrad of the command, signals RS, E to portD
asm("nop"); //Small delay of 1 MK cycle, for stabilization
PORTD=temp&~(1<
pause(10*TIME); //Pause for command execution
}

Void lcd_dat (unsigned char lcd) //Write data to LCD
{
unsigned char temp;

Temp=(lcd|(1<PORTD=temp; //Output the most significant data tetrad, RS, E signals to portD
asm("nop"); //Small delay of 1 MK cycle, for stabilization
PORTD=temp&~(1<
temp=((lcd*16)|(1<PORTD=temp; //Output the low-order data tetrad, RS, E signals to portD
asm("nop"); //Small delay of 1 MK cycle, for stabilization
PORTD=temp&~(1<
pause(TIME); //Pause for data output
}

Void lcd_init (void) //Initialization of LCD
{
lcd_com(0x2c); //4-wire interface, 5x8 character size
pause(100*TIME);
lcd_com(0x0c); //Show the image, do not show the cursor
pause(100*TIME);
lcd_com(0x01); //Clear DDRAM and set the cursor to 0x00
pause(100*TIME);
}

Unsigned int getADC(void) //Reading the ADC
( unsigned int v;

ADCSRA|=(1<
while ((ADCSRA&_BV(ADIF))==0x00) //Wait until the conversion is completed
;

V=(ADCL|ADCH<<8); br="">return v;
}

Void write_data (unsigned int u)
( unsigned char i;
double voltage=0;

Lcd_com(0x84); //Output of the ADC register on the LCD
for (i=0;i<10;i++) br="">if ((u&_BV(9-i))==0x00) lcd_dat (0x30);
else lcd_dat(0x31);

Lcd_com(0xc2);
voltage= R_division*2.56*u*1.024; //Voltage calculation

I=voltage/10000; //Display voltage on LCD
voltage=voltage-i*10000;
if (i!=0) lcd_dat(0x30+i);

I=voltage/1000;
voltage=voltage-i*1000;
lcd_dat(0x30+i);

I=voltage/100;
voltage=voltage-i*100;
lcd_dat(0x30+i);

I=voltage/10;
voltage=voltage-i*10;
lcd_dat(0x30+i);

Lcd_dat("v");
}

Int main(void)
{
DDRD=0xfc;

Pause(3000); //Delay for turning on the LCD
lcd_init(); //Initialization of LCD

Lcd_dat("A"); //Write "ADC=" and "U=" on the LCD
lcd_dat("D");
lcd_dat("C");
lcd_dat("=");
lcd_com(0xc0);
lcd_dat("U");
lcd_dat("=");

ADCSRA=(1<//Turn on the ADC, converter clock frequency =/8 from the microcontroller clock
ADMUX=(1<//Internal reference voltage Vref=2.56, ADC input is PC0

While(1)
{
u=getADC(); //Read the data
write_data(u); //Display them on the LCD
pause(30000);
}

Return 1;
}

The program is simple. First we initialize the I/O ports. To serve as an entrance ADC, pin PC0 should work for the entrance. Next we carry out the initialization LCD And ADC. Initialization ADC is to turn it on with a bit ADEN in the register ADCSRA. And selecting the bit conversion frequency ADPS2, ADPS1, ADPS0 in the same register. We also select the reference voltage source, bits REFS1 REFS0 in the register ADMUX and entrance ADC: bits MUX0,MUX1,MUX2, MUX3(in our case, the entrance ADC is PC0, That's why MUX0.3=0). Next, in an eternal loop, we begin the transformation by setting the bit ADSC in the register ADCSRA. We wait for the end of the conversion (bit ADIF V ADCSRA becomes equal to 1). Next, we remove the data from the register ADC and bring them to LCD. Extract data from ADC need in this order: v=(ADCL+ADCH*256); if used v=(ADCH*256+ADCL);- doesn't work point blank. There is also a trick to avoid working with fractional numbers. When to calculate the input voltage in volts. We'll just store our voltage in millivolts. For example, the variable value voltage 4234 means we have 4.234 volts. In general, operations with fractional numbers eat up a lot of microcontroller memory (our voltmeter firmware weighs a little more than 4 kilobytes, this is half of the program memory ATmega8!), they are recommended to be used only when absolutely necessary. Calculating the input voltage in millivolts is simple: voltage=R_division*2.56*u*1.024;
Here R_division– resistive divider coefficient R4-R5. Since the real divider coefficient may differ from the calculated one, our voltmeter will lie. But it's easy to correct. Using a tester we measure a certain voltage, we get X volt, and let our voltmeter show Y volt. Then R_division = 4*X/Y, If Y is greater than X And 4*Y/X If X is greater than Y. This completes the setup of the voltmeter and you can use it.
Download the firmware as a project for AVR Studio 4.
You can see how a voltmeter works in the video:

You can also modify your power supply. By inserting into it a digital voltmeter-ammeter on the LCD and overload protection (to measure current we need a powerful shunt with a resistance of about 1 Ohm).

I also built in overload protection into my power supply; when the current exceeds 2A, the piezo tweeter starts beeping hard, signaling an overload:

The microcontroller communicates with the outside world through I/O ports. In general, it can only “perceive” digital signals – logical zero or logical one. For example, for the ATmega8535 microcontroller with a supply voltage of 5 V, logical zero is a voltage from 0 to 1.3 V, and logical one is from 1.8 to 5 V. Quite often there is a need to measure voltages that can take any value in the range from 0 to supply voltage. For these purposes, AVR microcontrollers contain an analog-to-digital converter (ADC).

Without going into details of the internal structure of the ADC, let's imagine it as a black box. A continuous analog signal is supplied to the input of the ADC, and a sequence of digital values ​​is obtained at the output. An ADC has many characteristics, but the main ones include resolution, absolute accuracy, maximum sampling frequency and input voltage range.

Resolution(resolution) is the ability of the ADC to distinguish between two input signal values. It is defined as the reciprocal of the maximum number of code combinations at the ADC output. AVR has a 10-bit ADC. The maximum number of code combinations will be equal to 2 10 = 1024. Resolution is equal to 1/1024 of the entire scale of permissible input voltages.

For the ADC to operate, a reference voltage source (VS) is required. For him, this is the standard against which he measures the input signals. AVR microcontrollers allow you to use the supply voltage, an internal 2.56 V reference source, and the voltage at the AREF pin (external reference) as a reference.

The supply voltage in our circuit is 5 V, then 1/1024 of the entire scale is 5 * 1/1024 = 0.0048 V or approximately 5 mV. With this step (this is called the quantization step), the ADC will measure the input voltage. If the two closest signal values ​​at the ADC input differ by the amount< 5 мВ, АЦП воспримет их как одинаковые. На практике разрешающая способность АЦП ограничена его шумами.

Absolute precision– deviation of the actual transformation from the ideal one. This is a composite result of several ADC errors. Expressed in the number of least significant bits (LSB) of the ADC. For AVR, the absolute error of the ADC = ±2LSB. For our example, the absolute accuracy will be 2 * 5 mV = ±10 mV.

Limit sampling rate determines the speed of the ADC and is measured in hertz or samples per second (SPS – samples per second). For AVR microcontrollers, this value is 15 kSPS (kilo samples per second). In practice, the AVR ADC works faster, but at the same time its accuracy deteriorates.

Kotelnikov's theorem (Nyquist-Shannon theorem, sampling theorem) states that an analog signal having a limited spectrum can be restored uniquely and without loss from its discrete samples if the sampling (sampling) frequency exceeds the maximum frequency of the signal spectrum by more than 2 times. To put it simply, if you need to digitize an analog signal with a spectrum band of 0 - 7 KHz, then ideally the sampling frequency should be > twice the maximum frequency of the spectrum of this signal, that is, > 14 KHz. In practice, everything is much more complicated. A low-pass filter is always placed before the ADC input to limit the signal spectrum, and the sampling frequency is chosen even higher.

Input voltage range– this is the minimum and maximum voltage value that can be supplied to the ADC input. For the AVR microcontroller it is 0 – Vcc (supply voltage)


If we compare an ADC with a ruler, then the minimum and maximum scale value is the input voltage range, the number of divisions of the ruler is the number of code combinations (the number of quantization levels), the distance between two adjacent divisions is the quantization step, and the quantization step divided by the input voltage range is the resolution .

Explanations for the diagram

To get acquainted with the ADC module of the AVR microcontroller, I chose a simple but interesting circuit. Take a look at the picture. Four buttons are connected to a voltage divider (resistors R8…R11). When pressed, they switch different voltages to the input of the zero channel of the ADC. By measuring these voltages in the ADC interrupt and determining what range they fall into, the microcontroller will recognize the number of the button pressed.

Resistor R7 is needed so that the ADC input does not “dangle in the air” when all buttons are released. If this is not done, the ADC will pick up interference. The value of resistor R7 is chosen to be large so as not to influence the voltage divider.

R6 and C7 - low-frequency filter to protect against button bounce and interference. (In general, low-pass filters in front of the ADC are usually used to protect against such phenomena as aliasing, but that is a different story). Additionally, resistor R6 plays a current-limiting function; without it, when pressing the S4 button, the microcontroller output would be directly connected to the power supply positive. And this is undesirable.

To indicate the number of the pressed button, the circuit uses 4 LEDs.
Microcontroller - ATMega8535. The description of the ADC registers below in the text is given specifically for it. There may be some differences for other microcontrollers.

Task

For the above diagram, write a program that determines the number of the pressed button.

The program algorithm is as follows:

Main program
Initializing ports
Initializing the ADC
Enable interrupts
Endless cycle
{
If the button is pressed, light the desired LED
If not, turn off all LEDs
}

ADC interrupt handler
Read the voltage at the ADC input
Determine what range it falls into
Write the button number to the buffer

Initial program code

//programming AVR microcontrollers in C - mastering the ADC

#include
#include

//macro to start the transformation
#define StartConvAdc() ADCSRA |= (1<

int main( void )
{

ADMUX = (0<

//on ADC, single converter mode, interrupt resolution, converter frequency. = FCPU/128

ADCSRA = (1<


__enable_interrupt
();
StartConvAdc();
while(1)
{

//some code

}
return 0;
}

//ADC interrupt handler
#pragma vector=ADC_vect
__interrupt void adc_my( void)
{
unsigned char AdcBuf = ADCH;

//some code

StartConvAdc();
}

Explanations for the code

Macro to start the conversion

StartConvAdc() is a macro to start an ADC conversion. It sets the ADSC bit in the ADCSRA control and status register.

Initializing the ADC

To run the ADC module, it must first be configured. Three registers are responsible for this:
Multiplexer control register - ADMUX
Control and status register - ADCSRA
Special Function Register - SFIOR

ADMUX register

The ADC module needs a reference voltage source (VR) to operate. The REFS1, REFS0 bits are responsible for selecting the ION. In our case, the reference voltage is the supply voltage (that’s why we set the AVcc pin to +5V) so REFS1 - 0, REFS0 - 1

The ADC of the AVR microcontroller is 10-bit, and the stone itself is 8-bit. Therefore, the result of the conversion is stored in two registers (ADCH, ADCL). The ADLAR bit specifies the alignment direction of the conversion result. 0 – right alignment (2 least significant bits in ADCH are occupied, ADCL is completely occupied), 1 – left alignment (ADCH is completely occupied, only 2 most significant bits in ADCL are occupied). Our example does not require high precision conversion, so it would be convenient to left-justify the result and work only with the ADCH register. Install ADLAR - 1

Purely physically, there is only one ADC in the AVR microcontroller. But in front of it there is a multiplexer that allows you to connect any of the 8 port pins to the ADC input. The number of the currently selected channel is specified by the ADMUX3, ADMUX2, ADMUX1, ADMUX0 bits. We are using the null channel, so all bits are 0.

//ion - supply voltage, left alignment, zero channel
ADMUX = (0<

ADCSRA Register

For the ADC to work, it must be turned on, that is, the ADEN bit must be set to 1

The conversion is started by setting the ADSC -1 bit. During initialization we will not run the ADC, so ADSC is 0

The ADC can operate in two modes: single conversion - when each conversion is started by software and continuous - when the conversion is started once by software and restarted automatically. In our example, the conversion is single, the ADATE bit is 0.

When the ADC has finished converting, it issues an interrupt request. To enable the interrupt, the ADIE bit must be set to 1.

The ADC module requires a clock signal to operate. It is generated from the microcontroller clock signal by dividing by fixed coefficients. Bits ADSP2, ADSP1, ADSP0 are used to set the prescaler coefficients. Since we will interrogate buttons using an ADC, and this is a very slow device, we select the largest coefficient (that is, the lowest frequency). All bits are 1.

//on ADC, single converter mode, interrupt enable, F converter = FCPU/128
ADCSRA = (1<

I talked about all the bits except ADIF. ADIF is an interrupt flag. It is installed by hardware when the conversion is complete.

SFIOR Register

Bits ADTS2, ADTS1, ADTS0 determine the source that starts the conversion procedure. These bits need to be set only in continuous conversion mode. We have a single mode, so we don’t touch the register.

ADC interrupt handler

#pragma vector=ADC_vect
__interrupt void adc_my( void)
{
unsigned char AdcBuf = ADCH;

//some code

ADC - Analog-to-digital converter. From the name you can guess that an analog signal is supplied to the input, which is converted into a number.

The first thing that needs to be said is that the ADC of the microcontroller can only measure voltage. To measure other physical quantities, they must first be converted to voltage. The signal is always measured relative to a point called the reference voltage, this same point is the maximum that can be measured. It is recommended to choose a highly stable voltage source as a reference voltage source (VS), otherwise all measurements will dance along with the reference.

One of the most important characteristics is resolution, which affects the measurement accuracy. The entire measuring range is divided into parts. Minimum zero, maximum voltage ION. For an 8-bit ADC this is 2^8=256 values, for a 10-bit ADC it is 2^10=1024 values. Thus, the higher the bit depth, the more accurately the signal can be measured.

Let's say you measure a signal from 0 to 10V. The microcontroller we use is Atmega8, with a 10-bit ADC. This means that the 10V range will be divided into 1024 values. 10V/1024=0.0097V - with this step we can measure voltage. But keep in mind that the microcontroller will consider the values ​​0.0097, 0.0098, 0.0099... the same.

Nevertheless, a step of 0.01 is quite good. However, there are several recommendations without which this accuracy will not be met, for example, for measurements with an accuracy of 10 bits, the frequency at which the ADC operates should be 50-200 kHz. The first transformation takes 25 cycles and 13 cycles thereafter. Thus, at a frequency of 200 kHz we can squeeze out the maximum
200,000/13 = 15,384 measurements.

An internal source or an external one can be used as a reference voltage source. The internal source voltage (2.3-2.7V) is not recommended to be used due to low stability. An external source is connected to the AVCC or Aref pin, depending on the program settings.

When using an ADC, the AVCC pin must be connected. The AVCC voltage should not differ from the microcontroller supply voltage by more than 0.3V. As was said, the maximum measured voltage is equal to the reference voltage (Vref), it is in the 2V-AVCC range. So the microcontroller cannot measure more than 5V.

To expand the measurement range, you need to measure the signal through a voltage divider. For example, the maximum measured voltage is 10V, the reference voltage is 5V. To expand the measurement range, you need to reduce the measured signal by 2 times.

The formula for calculating the divisor looks like this:

U out = U in R 2 /(R 1 + R 2)

Let's substitute our values ​​into the formula:

5 = 10*R2/(R1+R2)

those. you can take any two identical resistors and connect them according to the diagram

Therefore, when we measure the voltage through a divider, we need to multiply the resulting ADC value by the coefficient = Uout/Uin.

The complete formula for calculating the measured voltage will look like this:
U=(reference voltage*ADC value*divider coefficient)/number of ADC bits

Example: reference 5V, measured ADC value = 512, divider factor =2, ADC 10-bit.

(5*512*2)/1024=5V - actual measured voltage value.

Some programmers write a program so that the microcontroller automatically calculates the divisor coefficient; for this, the output signal is measured with a standard device and this value is entered into the program. The microcontroller itself correlates the true voltage to each ADC value; the process itself is one-time and is called calibration.

Let's move on to software implementation. Create a project with the specified parameters. We will also connect a display to port D to display information.

The measurement will be carried out in automatic mode, the code is processed in an interrupt, the reference voltage is connected to the AVCC pin. Essentially, we only need to process the received data. The measured data is stored in the adc_data variable. If you need to scan several channels, then select which channels to scan, and the data will be for pin 0 in adc_data, for pin 1 in adc_data, etc.

In the main loop, add the lines:

result=((5.00*adc_data)/1024.00); //convert the ADC value into volts
sprintf(lcd_buffer,"U=%.2fV",result); //put the result into a temporary variable
lcd_puts(lcd_buffer); //display

A small note: to use floating point numbers, you need to change (s)printf Features: int, width to float, width, precision in the project settings. If this is not done, we will not see tenths and hundredths.

Thus, we just converted the ADC value into volts and displayed it on the display. The result in Proteus looks like this:

The resistor can be used to change the voltage; the measured voltage is displayed on the display. When assembling on real hardware, you need to connect a 0.1 µF capacitor to the Aref leg. The lesson turned out to be a little difficult, but I think you will like it.

Proteus file and firmware:

Update:
Current measurement:

Distinctive features:

  • 10-bit resolution
  • Integral nonlinearity 0.5 ml. resolution
  • Absolute error ±2 ml. resolution
  • Conversion time 65 - 260 µs.
  • Conversion frequency up to 15 thousand conversions. per second at maximum resolution
  • 8 multiplexed single-pole inputs
  • 7 differential input channels
  • 2 differential input channels with optional gain of 10 and 200
  • Representation of the result with left or right alignment in 16-bit. word
  • ADC input voltage range 0…VCC
  • Selective internal reference at 2.56 V
  • Single conversion and auto restart modes
  • Interrupt upon completion of ADC conversion
  • Noise reduction mechanism in sleep mode

ATmega128 contains 10-bit. Successive approximation ADC. The ADC is connected to an 8-channel analog multiplexer, the 8 single-pole inputs of which are connected to the lines of port F. The common input signal must be at 0V potential (i.e., connected to GND). The ADC also supports 16 differential voltage inputs. Two differential inputs (ADC1, ADC0 and ADC3, ADC2) contain a stage with step programmable gain: 0 dB (1x), 20 dB (10x), or 46 dB (200x). The seven differential analog channels share a common inverting input (ADC1), and all other ADC inputs serve as non-inverting inputs. If 1x or 10x gain is selected, you can expect 8-bit. resolution, and if 200x, then 7-bit.

The ADC contains a sample-and-hold device that maintains a constant voltage at the ADC input during conversion. The functional diagram of the ADC is shown in Figure 108.

The ADC has a separate AVCC (analog power) power pin. AVCC should not differ by more than ±0.3V from VCC. See paragraph “ ” for recommendations on connecting this pin.

The internal reference voltage can be the voltage from the internal 2.56V ION or the AVCC voltage. If an external reference is required, it should be connected to the AREF pin with a blocking capacitor connected to this pin to improve noise performance.

Figure 108 - Functional diagram of an analog-to-digital converter

Operating principle

The ADC converts the input analog voltage to 10-bit. code using the method of successive approximations. The minimum value corresponds to the GND level, and the maximum AREF level minus 1 ml. resolution The AREF pin can optionally be connected to the AVCC voltage or an internal 1.22V ION by writing the corresponding values ​​to the REFSn bits in the ADMUX register. Despite the fact that the 2.56V ION is located inside the microcontroller, a blocking capacitor can be connected to its output to reduce sensitivity to noise, because it is associated with the AREF pin.

The analog input channel and differential gain stage are selected by writing the MUX bit to the ADMUX register. One of the ADC0...ADC7 inputs, as well as GND and the output of a fixed 1.22 V reference voltage source can be selected as a single-pole analog input of the ADC. In the differential input mode, it is possible to select inverting and non-inverting inputs to the differential amplifier.

If differential analog input mode is selected, the differential amplifier will amplify the voltage difference between the selected pair of inputs by the specified gain. The value amplified in this way is sent to the analog input of the ADC. If single-pole analog input mode is selected, the gain stage is skipped

ADC operation is enabled by setting the ADEN bit in ADCSRA. Reference source and conversion channel selection cannot be made until ADEN is set. If ADEN = 0, then the ADC does not consume current, therefore, when switching to economical sleep modes, it is recommended to first disable the ADC.

The ADC generates a 10-bit result that is placed in a pair of ADC data registers, ADCH and ADCL. By default, the conversion result is placed in the lower 10 bits of the 16-bit. words (right justified), but can optionally be placed in the high 10 bits (left justified) by setting the ADLAR bit in the ADMUX register.

The practical usefulness of presenting the result with left alignment exists when 8-bit resolution is sufficient, because in this case, only the ADCH register needs to be read. Otherwise, it is necessary to read the contents of the ADCL register first, and then the ADCH register, which ensures that both bytes are the result of the same conversion. As soon as the ADCL is read, access to the data registers from the ADC is blocked. This means that if ADCL is read and the conversion is completed before the ADCH register is read, then none of the registers can be modified and the result of the conversion is lost. After reading ADCH, access to the ADCH and ADCL registers by the ADC is allowed again.

The ADC generates its own interrupt request when the conversion is complete. If data access to the ADC is disabled between reading the ADCH and ADCL registers, an interrupt will occur even if the conversion result is lost.

Starting the conversion

A single conversion is started by writing log. 1 to ADSC ADC conversion start bit. This bit remains high during the conversion process and is cleared when the conversion is complete. If the analog input channel is switched during conversion, the ADC will automatically complete the current conversion before switching the channel.

In auto restart mode, the ADC continuously digitizes the analog signal and updates the ADC data register. This mode is set by writing log. 1 into the ADFR bit of the ADCSRA register. The first conversion is initiated by writing log. 1 into the ADSC bit of the ADCSRA register. In this mode, the ADC performs serial conversions, regardless of whether the ADC interrupt flag ADIF is cleared or not.

Prescaler and conversion timing diagram


Figure 109 – ADC prescaler

If maximum resolution (10 bits) is required, then the frequency at the input of the successive approximation circuit should be in the range of 50...200 kHz. If a resolution of less than 10 bits is sufficient, but a higher conversion frequency is required, then the ADC input frequency can be set above 200 kHz.

The ADC module contains a prescaler that generates derivative frequencies above 100 kHz with respect to the CPU clock frequency. The division ratio is set using the ADPS bit in the ADCSRA register. The prescaler starts counting from the moment the ADC is turned on by setting the ADEN bit in the ADCSRA register. The prescaler operates while the ADEN bit is 1 and is reset when ADEN = 0.

If unipolar conversion is initiated by setting the ADSC bit in the ADCSRA register, then conversion begins on the next rising edge of the ADC clock. Features of the differential conversion timing diagram are presented in “ ”.

Normal conversion requires 13 ADC clock cycles. The first conversion after turning on the ADC (setting ADEN to ADCSRA) requires 25 ADC clock cycles due to the need to initialize the analog circuit.

After the start of normal conversion, 1.5 ADC clock cycles are spent on sample-to-store, and after the start of the first conversion, 13.5 clock cycles are spent. Once the conversion is complete, the result is placed in the ADC data registers and the ADIF flag is set. In single conversion mode, the ADSC bit is cleared at the same time. By software, the ADSC bit can be set again and a new conversion will be initiated by the first rising edge of the ADC clock signal.

In auto restart mode, a new conversion begins as soon as the previous one completes, while ADSC remains in a high state. Conversion times for various conversion modes are presented in Table 95.


Figure 110 – Timing diagram of ADC operation during the first conversion in single conversion mode


Figure 111 – Timing diagram of ADC operation in single conversion mode


Figure 112 – Timing diagram of ADC operation in automatic restart mode

Table 95 – ADC conversion time

Differential Gain Channels

If differential gain channels are used, there are some considerations that need to be taken into account.

Differential conversions are synchronized with respect to the internal clock of SDADC2, the frequency of which is equal to half the clock frequency of the ADC. This synchronization is performed automatically by the ADC interface so that the sample-and-hold is triggered by a specific edge of the ADC2. If the conversion (all single conversions and the first conversion in auto restart mode) was initiated by the user while SDA/DC2 was in low log. state, then its duration will be equivalent to unipolar conversion (13 ADC clock cycles). If the conversion is user initiated, when SDADC2 is equal to log. 1, it will last 14 ADC clock cycles due to the operation of the synchronization mechanism. In automatic restart mode, a new transformation is initiated immediately upon completion of the previous one, and since at this moment SKADC2 is equal to log. 1, then all conversions that were automatically restarted (that is, all but the first one) will last 14 ADC clock cycles. The amplifier stage is optimized for a frequency range of up to 4 kHz for any gain. The amplification of higher frequency signals will be non-linear. Therefore, if the input signal contains frequency components above the frequency range of the amplifier stage, then it is necessary to install an external low-pass filter. Please note that the ADC clock frequency is not related to the frequency range limitation of the amplifier stage. For example, the ADC synchronization period can be 6 μs, at which the channel conversion frequency is equal to 12 thousand conversions. per second, regardless of the frequency range of this channel.

Changing channel or selecting reference source

The MUXn and REFS1:0 bits in the ADMUX register support single-stage buffering via a temporary register. This ensures that the new conversion channel and reference source settings take effect at a safe time for conversion. Before conversion begins, any changes to the channel and reference source take effect immediately after their modification. As soon as the conversion process begins, access to changing the channel and reference source is blocked, thereby ensuring that the ADC has sufficient conversion time. Modification continuity returns on the last ADC clock cycle before conversion is completed (before the ADIF flag is set in the ADCSRA register). Note that the conversion begins with the next rising edge of the ADC clock after the ADSC write. Therefore, it is recommended that the user does not write a new channel or reference value to ADMUX until the 1st ADC clock cycle after writing ADSC.

Special care must be taken when changing the differential channel. Once a differential channel is selected, the amplifier stage requires 125 µs to stabilize the new value. Therefore, during the first 125 µs after switching the differential channel, conversion should not start. If transformations were nevertheless carried out during this period, then their results must be ignored.

The same settling delay must be introduced during the first differential conversion after changing the ADC reference source (by changing the REFS1:0 bit in ADMUX).

If the JTAG interface is enabled, then the functions of the ADC channels on port F 7...4 pins are canceled. See table. 42 and “Alternative Port F Functions.”

ADC input channels

When switching an input channel, it is necessary to take into account some recommendations that will prevent incorrect switching.

In single conversion mode, channel switching must be performed before starting conversion. Channel switching can occur only during one ADC clock cycle after recording the log. 1 in ADSC. However, the simplest method is to wait for the conversion to complete before selecting a new channel.

In auto restart mode, a channel must be selected before starting the first conversion. Channel switching occurs in the same way - during one ADC synchronization cycle after recording the log. 1 in ADSC. But the simplest method is to wait for the pen conversion to complete and then switch the channel. Since the next transformation has already started automatically, the next result will correspond to the previous channel. Subsequent conversions reflect the result for the new channel.

When switching to a differential channel, the first conversion will have poor accuracy due to the transient process in the automatic bias control circuitry. Therefore, it is recommended to ignore the first result of such a conversion.

ADC reference voltage source

The reference voltage source (RPS) for the ADC (VRES) determines the conversion range of the ADC. If the level of the unipolar signal is above VION, then the result of the conversion will be 0x3FF. The VION can be AVCC, internal 2.56V ION or external ION connected to the pin. AREF. The AVCC is connected to the ADC via a passive switch. The internal reference voltage of 2.56V is generated by the internal VBG reference source, buffered by the internal amplifier. In either case, the external AREF pin is connected directly to the ADC and therefore the effect of noise on the reference source can be reduced by connecting a capacitor between the AREF pin and ground. Voltage VION can also be measured at the AREF pin with a high-impedance voltmeter. Please note that VION is a high-impedance source and, therefore, only a capacitive load can be connected to it externally.

If the user is using an external reference source connected to the pin. AREF, then using another reference source option is not allowed because this will shunt the external reference voltage. If to pin. AREF voltage is not applied, then the user can select AVCC and 2.56 as the reference source. The result of the first conversion after switching the reference source may have poor accuracy and the user is advised to ignore it.

If differential channels are used, the selected reference source must be less than the AVCC level, as shown in table. 136.

ADC noise suppressor

The ADC is characterized by the ability to suppress noise that is caused by the operation of the CPU core and peripheral I/O devices. The noise suppressor can be used in ADC noise reduction mode and in idle mode. When using this function, please follow the following procedure:

  1. Make sure the ADC is enabled and is not converting. Select single conversion mode and enable interrupt when conversion is complete.
  2. Enter ADC noise reduction mode (or idle mode). The ADC will start conversion as soon as the CPU stops.
  3. If no other interrupts occur before the conversion is complete, the ADC will cause a CPU interrupt and the program will jump to the interrupt vector when the ADC conversion is complete. If another interrupt wakes up the microcontroller before the conversion is complete, then that interrupt is processed and a corresponding interrupt request is generated when the conversion is complete. The ADC remains in active mode until the next sleep command is executed.

Please note that the ADC does not automatically turn off when put into all sleep modes except idle and ADC noise reduction. Therefore, the user must provide a log entry. 0 in the ADEN bit before entering such sleep modes to avoid excessive power consumption. If the ADC has been enabled in these sleep modes and the user wishes to perform differential conversion, the ADC must be turned on and then off upon awakening to initiate extended conversion to ensure a valid result is obtained.

The analog input circuit for unipolar channels is shown in Figure 113. Regardless of which channel is connected to the ADC, the analog signal connected to the pin. ADCn, loaded with output capacitance and input leakage resistance. Once the channel is connected to the ADC, the analog signal will be coupled to the sample-and-hold capacitor through a series resistor whose resistance is equivalent to the entire input circuit.

The ADC is optimized for analog signals with an output impedance of no more than 10 kOhm. If such a signal source is used, the sampling time is negligible. If a source with a higher input impedance is used, the sampling time will be determined by the time it takes for the analog source to charge the sample-and-hold capacitor. It is recommended to use only sources with low output impedance and slowly changing signals, because in this case, the charge of the sample-hold capacitor will be quite fast.

In relation to channels with differential amplification, it is recommended to use signals with internal resistance up to several hundred kOhms. It should be ensured that in the preliminary stages of analog signal formation, frequencies above fADC/2 are not introduced to the ADC input, otherwise the conversion result may be incorrect. If there is a possibility of high-frequency penetration, it is recommended to install a low-pass filter in front of the ADC.


Figure 113 – Analog input circuit

The operation of digital components inside and outside the microcontroller is associated with the generation of electromagnetic radiation, which can adversely affect the accuracy of analog signal measurements. If conversion accuracy is a critical parameter, noise levels can be reduced by following these guidelines:

  1. Keep the analog signal path as short as possible. Keep analog signals above the analog ground plane (shield) and away from conductors carrying high-frequency digital signals.
  2. The AVCC pin needs to be connected to the digital power supply VCC through an LC circuit as shown in Fig. 114.
  3. Use the function to suppress ADC noise introduced by the CPU core.
  4. If any of the ADC pins are used as a digital output, it is extremely important to prevent that output from switching during the conversion process.


Figure 114 – Connecting the ADC power supply

Offset compensation methods

The amplifier stage has a built-in offset compensation circuit that strives to keep the differential measurement offset as close to zero as possible. The remaining offset can be measured if the same microcontroller pin is selected as the differential inputs of the ADC. The residual offset measured in this way can be subtracted programmatically from the conversion result. Using a software bias correction algorithm can reduce the bias below one ml. resolution

A/D Conversion Error Definitions

An n-bit unipolar ADC converts the voltage linearly between GND and VION in steps of 2n (million digits). Minimum code = 0, maximum = 2n-1. The main transformation errors are the deviation of the actual transformation function from the ideal one. These include:

Bias– deviation of the first transition (from 0x000 to 0x001) compared to the ideal transition (i.e. at 0.5 ml resolution). Ideal value: 0 ml. resolution


Figure 115 – Offset error

After offset correction, the gain error is the deviation of the last transition (from 0x3FE to 0x3FF) from the ideal transition (ie the deviation at the maximum value minus 1.5 ml. res.). Ideal value: 0 ml. resolution


Figure 116 – Gain error

Integral nonlinearity (INL). After adjusting for offset and gain error, the INL represents the maximum deviation of the actual transform function from the ideal one for any code. Ideal INL value = 0 ml. resolution


Figure 117 - Integral nonlinearity (INL)

Differential nonlinearity (DNL). The maximum deviation between the width of the actual code (the interval between two adjacent transitions) from the width of the ideal code (1 ml. bit). Ideal value: 0 ml. resolution


Figure 118 - Differential nonlinearity (DNL)

Quantization error. Occurs due to the conversion of the input voltage into a finite number of codes. Quantization error - input voltage interval of 1 ml. resolution (voltage quantization step), which is characterized by the same code. Always equal to ±0.5 ml. resolution

Absolute error. The maximum deviation of the real (without adjustment) conversion function from the real one for any code. It is the result of several effects: offset, gain error, differential error, nonlinearity, and quantization error. Ideal value: ±0.5 ml. resolution

ADC conversion result

Once the conversion is complete (ADIF = 1), the result can be read from a pair of ADC conversion result registers (ADCL, ADCH).

For unipolar conversion:

where Vin is the voltage level at the input connected to the ADC;

Vion is the voltage of the selected reference voltage source (see Table 97 and Table 98). Code 0x000 corresponds to the analog ground level, and 0x3FF to the reference voltage level minus 1 voltage quantization step. When using a differential channel

V pos - voltage at the non-inverting (inverting) input; V neg - gain; V ref is the voltage of the selected ION.

The result is represented in two's complement code, starting from 0x200 (-512d) to 0x1FF (+511d). Please note that if you need to quickly determine the polarity of the result, it is enough to poll the most significant bit of the conversion result (ADC9 to ADCH). If this bit is equal to log. 1, then the result is negative, but if log. 0 is positive. Figure 119 shows the ADC conversion function in differential mode.

Table 96 presents the resulting output codes for a differential channel pair (ADCn - ADCm) with gain Ku and reference voltage VION.


Figure 119 – ADC conversion function when measuring a differential signal

Table 96 - Relationship between input voltage and output codes

V ADCn Readable code Corresponding decimal value
V ADCm + V ION /Ky 0x1FF 511
V ADCm + 0.999 V ION / Ky 0x1FF 511
V ADCn + 0.998 V ION / Ky 0x1FE 510
... ...
V ADCm + 0.001 V ION / Ky 0x001 1
V ADCm 0x000 0
V ADCm - 0.001 V ION / Ky 0x3FF -1
... ...
V ADCm - 0.999 V ION / Ky 0x201 -511
V ADCm – V ION / Ky 0x200 -512

Example: Let ADMUX = 0xED (input pair ADC3 - ADC2, Ku=1, Vion=2.56V, left-justified result), voltage at input ADC3 = 300 mV, and at input ADC2 = 500 mV, then:

ADC code = 512 * 10 * (300 - 500) / 2560 = -400 = 0x270

Taking into account the selected result placement format (left-handed), ADCL = 0x00 and ADCH = 0x9C. If the right-hand format is selected (ADLAR=0), then ADCL = 0x70, ADCH = 0x02.

ADC multiplexer control register – ADMUX

Discharge 7 6 5 4 3 2 1 0
REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0 ADMUX
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Ref. meaning 0 0 0 0 0 0 0 0

Bit 7:6 – REFS1:0: Reference Select Bits

These bits determine which voltage will be used as a reference for the ADC (see Table 97). If you change the values ​​of these bits during the conversion process, the new settings will take effect only after the current conversion is completed (that is, when the ADIF bit in the ADCSRA register is set). The internal reference can be omitted if an external reference source is connected to the AREF pin.

Table 97 – ADC reference source selection

Bit 5 – ADLAR: Conversion Result Presentation Control Bit

The ADLAR bit affects the representation of the conversion result in a pair of ADC conversion result registers. If ADLAR = 1, then the result of the conversion will be left-handed, otherwise it will be right-handed. The ADLAR bit takes effect immediately after the change, regardless of any conversion running in parallel. A full description of the operation of this bit is provided in “ADC Data Registers – ADCL and ADCH”.

Bit 4:0 – MUX4:0: Analog channel and gain selection bits

These bits determine which of the available analog inputs are connected to the ADC. In addition, they can be used to select the gain for differential channels (see Table 98). If the bit values ​​are changed during the conversion process, their action mechanism will take effect only after the current conversion is completed (after the ADIF bit is set in the ADCSRA register).

Table 98 – Input Channel and Gain Selection

MUX4..0 Unipolar input Non-inverting differential input Inverting differential input Gain, Ku
00000 ADC0 No
00001 ADC1
00010 ADC2
00011 ADC3
00100 ADC4
00101 ADC5
00110 ADC6
00111 ADC7
01000 No ADC0 ADC0 10
01001 ADC1 ADC0 10
01010 ADC0 ADC0 200
01011 ADC1 ADC0 200
01100 ADC2 ADC2 10
01101 ADC3 ADC2 10
01110 ADC2 ADC2 200
01111 ADC3 ADC2 200
10000 ADC0 ADC1 1
10001 ADC1 ADC1 1
10010 ADC2 ADC1 1
10011 ADC3 ADC1 1
10100 ADC4 ADC1 1
10101 ADC5 ADC1 1
10110 ADC6 ADC1 1
10111 ADC7 ADC1 1
11000 ADC0 ADC2 1
11001 ADC1 ADC2 1
11010 ADC2 ADC2 1
11011 ADC3 ADC2 1
11100 ADC4 ADC2 1
11101 ADC5ADC21
No111110V(GND)
11110 1.23V (VBG)

ADC Control and Status Register A – ADCSRA

Discharge 7 6 5 4 3 2 1 0
ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0 ADCSRA
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Ref. meaning 0 0 0 0 0 0 0 0

Bit 7 – ADEN: ADC operation enable

Write to this bit log. 1 enables the ADC. If you write a log in this bit. 0, the ADC is disabled, even if it was in the process of conversion.

Bit 6 – ADSC: Start ADC conversion

In single conversion mode, setting this bit initiates the start of each conversion. In auto restart mode, setting this bit initiates only the first conversion and all others are performed automatically. The first conversion after enabling the ADC, initiated by the ADSC bit, is performed using an extended algorithm and lasts 25 ADC clock cycles, instead of the usual 13 clock cycles. This is due to the need to initialize the ADC.

During the conversion process, when polling the ADSC bit, a log is returned. 1, and upon completion of the conversion - log. 0. Write log. 0 is not included in this bit and has no effect.

Bit 5 – ADFR: ADC automatic restart mode selection

If you write a log in this bit. 1, the ADC will go into automatic restart mode. In this mode, the ADC automatically performs conversions and modifies the conversion result registers at fixed intervals. Record log. A 0 to this bit stops operation in this mode.

Bit 4 – ADIF: ADC Interrupt Flag

This flag is set after the ADC conversion is completed and the data registers are updated. If the ADIE and I bits (SREG register) are set, an interrupt occurs when the conversion is completed. The ADIF flag is reset by hardware when moving to the corresponding interrupt vector. Alternatively, the ADIF flag is reset by writing log. 1 into it. Note that when executing a read-modify-write instruction on the ADCSRA register, the pending interrupt may be disabled. This also applies to the use of SBI and CBI instructions.

Bit 3 – ADIE: ADC Interrupt Enable

After recording log. A 1 to this bit, provided that the I bit in the SREG register is set, enables an interrupt upon completion of ADC conversion.

Bits 2:0 – ADPS2:0: ADC Prescaler Control Bits

These bits determine by what value the CPU clock frequency will differ from the ADC input clock frequency.

Table 99 – ADC prescaler control

ADC Data Registers – ADCL and ADCH

ADLAR = 0:

Discharge 15 14 13 12 11 10 9 8
- - - - - - ADC9 ADC8 ADCH
ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0 ADCL
7 6 5 4 3 2 1 0
Read/Write Thurs. Thurs. Thurs. Thurs. Thurs. Thurs. Thurs. Thurs.
Thurs. Thurs. Thurs. Thurs. Thurs. Thurs. Thurs. Thurs.
Ref. meaning 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

ADLAR = 1:

Discharge 15 14 13 12 11 10 9 8
ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADCH
ADC1 ADC0 - - - - - - ADCL
7 6 5 4 3 2 1 0
Read/Write Thurs. Thurs. Thurs. Thurs. Thurs. Thurs. Thurs. Thurs.
Thurs. Thurs. Thurs. Thurs. Thurs. Thurs. Thurs. Thurs.
Ref. meaning 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

When the conversion is complete, the result is placed in these two registers. When using the differential conversion mode, the result is represented in binary's complement code.

If the ADCL is read, then access to these registers for the ADC will be blocked (i.e., the ADC will not be able to further modify the conversion result) until the ADCH register is read.

The left-hand format for presenting the result is convenient to use if 8 digits are sufficient. In this case, the 8-bit result is stored in the ADCH register and therefore the ADCL register need not be read. With the right-hand format, ADCL must be read first and then ADCH.

ADC9:0: ADC conversion result

These bits represent the result of the conversion.



If you find an error, please select a piece of text and press Ctrl+Enter.