AD-converter
ATmega328P.pdf ( Register summary on p 428 )ATmega328/P have a ten-bit ADC. You can choose to measure the voltage from six of the chip pins, or from a built-in temperature sensor.
To examine the AD converter you need connect a potentiometer.


AD converter needs clock pulses at a frequency between 50 kHz and 200 kHz,
the higher the frequency the faster the conversion, but with less accurate result.
The processor clock fCPU is divided down by a prescaler (1/2 1/4 1/4 1/16 1/32 1/64 1/128)
to a suitable frequency fADC. The register ADCSRA and the bits
ADPS2 ADPS1 ADPS0 are used to this.
With 16 MHz clock frequency we choose fCPU/128 = 125 kHz.
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // 16MHz/128 = 125KHz
Same register ADCSRA and the bit ADEN enables the power to the AD-converter.
ADCSRA |= (1 << ADEN) ; // Enable AD converter
The AD converter can be used with different reference voltages. This is set by the register ADMUX and the bits REFS1 REFS0. The combination 01 uses AVCC (the AVCC pin then connected to +5V).
ADMUX |= (1 << REFS0) ; // Set reference voltage to AVCC
Same register ADMUX and the bits ADMUX3 ADMUX2 ADMUX1 ADMUX0 are used to select source, which pin to be connected to the AD converter. If selecting channel 0, "0000", this is the default so in this case nothing has to be done.
It may be useful to turn off the "digital" part of the selected the pin as it will otherwise draw undue high current if the analog voltage happens to be in between the values of the digital '0' and '1'.
DIDR0 |= (1 << ADC0D); // Turn off digital buffer at this AD pin
The value from the AD-converter is 10 bit. It is not held in an 8 bit variable (a char) but needs a 16-bit variable (an int). The result ends up in two 8 bit registers ADCH and ADCL. The 10 bits can be read directly as ADC. Bite ADLAR in ADMUX-register controls whether the bits are distributed as 2 + 8 bits (the default value), or 8 + 2.
You start the AD conversion by writing '1' to the bit ADSC in the register ADCSRA. The bit then remains '1' as long as the AD conversion is in progress.
ADCSRA |= (1 << ADSC); // start AD conversion
while(ADCSRA & (1 << ADSC)){} // wait for ADSC become ’0' again

The full program is available here:
ad.txt
(for Arduino use code stored as: ad\ad.ino)
William Sandqvist willsandqvist@gmail.com