loading

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


gmoon8 years ago
Why not use the internal ADC?
sotsirh194 (author)  gmoon8 years ago
How do you use that?
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.
gmoon gmoon8 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.