|
|
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
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)
No comments:
Post a Comment