Wednesday, 15 June 2011

Basic ADC program in Atmega32


ADC (Analog to digital converter) is required because all the real world data is analog and computer cannot process analog data due to its continuous nature. So ADC is used to digitize the analog so that the processor can understand.

Atmega32 has an inbuilt 8-channel multiplexed ADC. Only one of the eight channels can be accessed at a time. ADC is of successive approximation type and hence highly accurate.

Atmega32 has three registers for ADC - ADCSRA , ADMUX and ADCW.

ADCSRA is the control and status register responsible for indicating ADC start and end of converstion , the clock speed or the rate of conversion and interrupt enable.
ADMUX selects one of the 8 adc channels.
ADCW contains the 10 bit  digitized value.

For more details of these registers refer the datasheet here.

#define F_CPU 16000000UL
#include<avr/io.h>
#include<util/delay.h>
#define ADC_VREF_TYPE 0x00
void ADC_init(void)
{
ADMUX=ADC_VREF_TYPE & 0xff; //select AREF as reference voltage
ADCSRA=0x85; //Enable ADC and 32 as prescalar
}
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff); //select the appropriate channel
_delay_us(10);
ADCSRA|=0x40; //start conversion by setting the ADSC flag
while ((ADCSRA & 0x10)==0); //check for conversion complete in ADIF flag
ADCSRA|=0x10; //Clearing ADIF by writing one to it
return ADCW; // returning the 10bit result
}
int main()
{
int adcV;
DDRB = 0xff;
PORTB = 0x00;
ADC_init();
while(1)
{
adcV = read_adc(0); // read the 0th channel of adc
if(adcV > 512){ //Thresholding
PORTB = 0x01;
}
else{
PORTB = 0x00;
}
}
return 0;
}
view raw adc.c hosted with ❤ by GitHub

The code example is for thresholding an analog sensor. We assume the sensor gives maximum of 5V output. The ADC returns a 10 bit value therefore for maximum 5V the adc output is 2^10 = 1024.
So,  5V --> 1024
      2.5V--> 512
There is no need to convert the digital value back to analog, just basic math will do. Additionally, we increase the efficiency by not going into float values.
So if the input to the PORTA0 is greater than 2.5V then the led will glow on PORTB else it will remain off.

ADC input greater than threshold (I simply gave 5V which is obviously greater than 2.5V)


ADC input less than threshold (I simply gave 0V which is obviously less than 2.5V












No comments:

Post a Comment

Popular Posts