Author Options:

How do you read the digital output from an adc on an avr in c? Answered




9 years ago

Why not use the internal ADC?


Answer 9 years ago

First, use an AVR that has an on-board ADC... Most do, but some don't (like the ATtiny2313.)

Here's an example function for the ATmega8:
uint16_t getADC(uint8_t adcnum){	ADMUX = adcnum;				// Select input pin	ADCSRA = _BV(ADEN) | _BV(ADPS2);		ADCSRA |= _BV(ADSC);			// Start sampling	while (ADCSRA & _BV(ADSC) ) {}		// wait till ready        return(ADCW);}

To read the ADC, call this getADC() function. The input argument is the ADC "channel", 0 through 5 (there are 6 ADC pins on the ATmega8.) It's a 2-bit number, 0-3.
adcval = getADC(0);   // get channel 0

What's happening in the function

Line 1-- ADMUX sets the channel (input pin, there are 6 to choose from).
Line 2-- ADCSRA is the ADC control and status register.
.....the bit (ADEN) enables the ADC
.....the bit (ADPS2) is the timing scaler (more later.)
Line 3-- Setting the ADSC bit in the control register begins the sampling
Line 4-- Wait until the ADSC is cleared, the finish signal.
Line 5-- Read the ADC register (W signifys the full Word register, 10 bits.)

Reading an ADC is time-dependent. The ADC must be read at a frequency of 200kHz or lower to reach the full 10-bit resolution. There are three bits in ADCSRA that can be used to "scale" the chip clock speed--slowing down the ADC clock so that accurate readings can be taken at high clock speeds.

The setting in used were:

--ATmega8 running at 4 mHz
--A scaler of 16 (ADPS2)

4 mHz / 16 = 250KHz, a little too fast for the full 10 bits, but I wanted a quick read. Read the datasheet to figure the proper prescaler for your clock speed.

Answer 9 years ago

Sorry: It's a 2-bit number, 0-3. is wrong, I was originally thinking of the ATtiny13, which has only 4 ADC channels.

ADMUX uses a three-bit number 0-5, for the ATmega8.