Skip to main content

6. Specific Registers for ADC In ATmega328p

6.1 ADMUX — ADC Multiplexer Selection Register

ADMUX is an 8-bit register that handles the basic ADC configuration: reference voltage source, data storage format, and which analog input channel to read.

image

Functions of each field:

a) REFS1:REFS0 — Reference Selection

Selects the ADC reference voltage source:

REFS1 REFS0 Reference Voltage
0 0 AREF Pin (external)
0 1 AVcc (supply voltage, typically 5V)
1 0 Unused
1 1 Internal 2.56V

b) ADLAR — ADC Left Adjust Result

Determines the storage position of the 10-bit result within the two 8-bit registers (ADCH + ADCL):

ADLAR ADCH (8-bit) ADCL (8-bit)
1 (Left-justified) D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 (unused 6-bit)
0 (Right-justified) (unused 6-bit) D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
  • Right-justified (ADLAR=0): ADCL stores the bottom 8 bits, and ADCH stores the top 2 bits. Typically used for reading the full 10-bit value.
  • Left-justified (ADLAR=1): ADCH stores the top 8 bits of the result. Useful when only 8-bit precision is needed (just read ADCH).

c) MUX3:MUX0 — Analog Channel Selection

Selects which analog input pin will be converted:

MUX3 MUX2 MUX1 MUX0 Analog Pin
0 0 0 0 ADC0 / A0
0 0 0 1 ADC1 / A1
0 0 1 0 ADC2 / A2
0 0 1 1 ADC3 / A3
0 1 0 0 ADC4 / A4
0 1 0 1 ADC5 / A5
0 1 1 0 ADC6 / A6
0 1 1 1 ADC7 / A7

6.2 ADCSRA — ADC Control and Status Register A

ADCSRA is an 8-bit register that serves as the command center for controlling and monitoring the ADC process status.

image

Functions of each bit:

Bit Name Function
ADEN image ADC Enable Set to 1 to enable the ADC. If 0, the ADC will not run and analog pins won't be converted.
ADSC ADC Start Conversion Set to 1 to start a single conversion cycle. This bit stays at 1 while conversion is in progress, then automatically returns to 0.
ADATE ADC Auto Trigger Enable If 1, conversion starts automatically triggered by a specific event (e.g., timer overflow, external pin change).
ADIF ADC Interrupt Flag Set to 1 by hardware when conversion is complete (End of Conversion). Reset by manually writing a 1 to this bit.
ADIE ADC Interrupt Enable If 1, the program will jump to an ISR (Interrupt Service Routine) when conversion is complete. Useful so the CPU doesn't have to wait (polling).
ADPS2:ADPS0 ADC Prescaler Select 3 bits that determine the clock divider for the ADC (see the prescaler table above).

6.3 ADCL and ADCH — ADC Data Registers

ADCL and ADCH are two 8-bit registers where the 10-bit ADC conversion result is stored after conversion is complete.

Since the ATmega328p uses a 10-bit ADC, the result (0–1023) cannot fit into a single 8-bit register, so it's split across two registers:

image

IMPORTANT: ADCL must be read first before ADCH. Reading ADCL locks ADCH to prevent it from changing until ADCH is read, ensuring data consistency.

How to read the full 10-bit ADC value (right-justified):

// In C:
uint16_t adc_value = ADC;  // or:
uint8_t  low  = ADCL;
uint8_t  high = ADCH;
uint16_t adc_value = (high << 8) | low;
; In Assembly:
LDS R18, ADCL    ; read low-byte first
LDS R19, ADCH    ; then read high-byte