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.

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.

Functions of each bit:
| Bit | Name | Function |
|---|---|---|
ADEN ![]() |
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:

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

No comments to display
No comments to display