Analog to Digital Converter - PortA
The ADC converts an analog input voltage to a 10-bit digital value.
The ADC is connected to an 8-channel Analog Multiplexer which allows each pin of PortA to be used as input for the ADC. The analog input channel is selected by writing to the MUX bits in ADMUX. This allows the selection of any of the 8 channels, AGND, or a fixed voltage reference.
The ADC has two different operating modes. In single conversion mode, each conversion will be initiated by the user. In free running mode, the ADC is constantly sampling and updating the ADC Data Registers. This mode is selected by the ADFR bit in the ADC Control and Status Register.
The ADC is enabled by setting the ADC Enable bit, ADEN in ADCSR. Voltage reference and input channel selections will not go into effect until ADEN is set.
A conversion is started by writing a logical one to the ADC Start Conversion bit, ADSC. This bit stays high until the conversion is complete (Hardware will clear the bit). If a different data channel is selected while a conversion is in process, the ADC will finish the current conversion before performing the channel change.
The 10-bit result is stored in ADC data registers ADCH and ADCL. Default is right justified, by setting the ADLAR bit in ADMUX, the result can be left adjusted. If using left adjusted, reading ADCH is sufficient if 8-bit precision is only required. Otherwise, ADCL must be read first, then ADCH.
When a conversion is complete, the result is written to the ADC data registers, and ADIF is set. In single conversion mode, ADSC is cleared simultaneously. The software may then set ADSC again to start a new conversion. In Free Running Mode, a new conversion will be started immediately after the conversion completes while ADSC remains high.
The ADC requires an input clock frequency between 50kHz and 200kHz. ADPS bits in ADCSR are used to generate a proper ADC clock input frequency.
Using the ADC:
Following the steps below will setup the Analog to Digital Converter for use.
- Select the channel to convert using the MUX bits.
- Select the voltage reference for the ADC using the REF bits.
- Select the clock frequency for the ADC using the ADPS bits.
- Select the justification through the ADLAR bit.
- Select single conversion or free running mode using the ADFR bit.
- Enable the ADC using the ADEN bit.
The following procedure is used to read the result of the conversion.
- Start a conversion by setting the ADSC bit.
- Wait for the conversion to finish ( monitor the ADIF bit ).
- Clear the conversion flag ADIF.
- Read the results in the ADCH and ADCL registers.
ADMUX - ADC Multiplexer Selection Register
Bit
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 Initial Value 0 0 0 0 0 0 0 0 Bits 7, 6 - REFS1..0: Reference Selection Bits
These bits select the voltage reference for the ADC. The settings and description are shown in the following table.
REFS1
REFS0 Voltage Reference Selection 0 0 AREF, Internal Vref turned off 0 1 AVCC with external capacitor at AREF pin 1 0 Reserved 1 1 Internal 2.56V Voltage Reference with external cap at AREF Bit 5 - ADLAR: ADC Left Adjust Result
This bit affects the presentation of the ADC conversion result in the ADC data register. Setting this bit will make the result left justified.
Bits 4..0 - MUX4..MUX0: Analog Channel and Gain Selection Bits
These bits select which of the analog inputs are connected to the ADC. The following table shows the detailed settings.
MUX4..0
Single-ended Input 00000 ADC0 00001 ADC1 00010 ADC2 00011 ADC3 00100 ADC4 00101 ADC5 00110 ADC6 00111 ADC7 01000..11101 Reserved 11110 1.22V 11111 0V (AGND)
ADCSR - The ADC Control and Status Register
Bit
7 6 5 4 3 2 1 0
ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0 ADCSR
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W Initial Value 0 0 0 0 0 0 0 0 Writing a logical '1' to this bit will enable the ADC.
Bit 6 - ADSC: ADC Start Conversion
Writing a logical '1' to this bit will start a conversion. In single conversion mode, this bit will be cleared at the completion of the conversion.
Bit 5 - ADFR: ADC Free Running Select
Writing a logical '1' to this bit enables the Free Running Mode where the ADC samples and updates the data registers continuously. Clearing this bit will terminate the mode.
Bit 4 - ADIF: ADC Interrupt Flag
This bit is set (one) when an ADC conversion completes and the data registers are updated. The ADC Conversion Complete Interrupt is executed if the ADIE bit and the I-bit in SREG are set. ADIF is cleared by the hardware when executing the corresponding interrupt routine or by writing a logical '1' to the flag.
Bit 3 - ADIE: ADC Interrupt Enable
Setting this bit to a logical '1' will enable the ADC interrupt. The interrupt will only be activated if the I-bit in SREG is also set.
Bits 2..0 - ADPS2..0: ADC Prescaler Selection Bits
These bits determine the division factor between the XTAL frequency and the input clock to the ADC.
ADPS2 ADPS1 ADPS0 Division Factor 0 0 0 2 0 0 1 2 0 1 0 4 0 1 1 8 1 0 0 16 1 0 1 32 1 1 0 64 1 1 1 128
ADCL and ADCH - The ADC Data Registers
The result of the ADC conversion is stored in these two registers. Once ADCL is read, the ADC Data Register will not update again until ADCH is read. If using only 8 bit precision, it is sufficient to just read ADCH. Otherwise, ADCL must be read first.
Bit
15 14 13 12 11 10 9 8 SIGN - - - - - ADC9 ADC8 ADCH ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0 ADCL
Bit
7 6 5 4 3 2 1 0 Read/Write R R R R R R R R R R R R R R R R Initial Value 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Bit
15 14 13 12 11 10 9 8 ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADCH ADC1 ADC0 - - - - - - ADCL
Bit
7 6 5 4 3 2 1 0 Read/Write R R R R R R R R R R R R R R R R Initial Value 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Usage:
ADMUX = 0x00; // selects channel 0 with no reference voltage
ADMUX = ADMUX | 0x40; // selects Avcc as the reference voltage
ADMUX = ADMUX | 0x20; // selects left justified results
ADCSR = 0x07; // set the ADC clock frequency
ADCSR = ADCSR | 0x80; // enables the ADC
ADCSR = ADCSR | 0x40; // start a conversion
while( ( ADCSR & 0x10 ) == 0 ); // wait for the conversion to complete
ADCSR = ADCSR | 0x10; // clear the ADC flag
high = ADCH; // read the high byte of the result
low = ADCL; // read the low byte of the result
Example: