What is an ADC?
An ADC, or Analog to Digital Converter, allows one to convert an analog voltage to a digital value that can be used by a microcontroller. There are many sources of analog signals that one might like to measure. There are analog sensors available that measure temperature, light intensity, distance, position, and force, just to name a few. Most of the physical quantities around us are continuous. By continuous we mean that the quantity can take any value between two extreme. For example the atmospheric temperature can take any value (within certain range). If an electrical quantity is made to vary directly in proportion to this value (temperature etc) then what we have is Analogue signal. Now we have brought a physical quantity into electrical domain. The electrical quantity in most case is voltage. To bring this quantity into digital domain we have to convert this into digital form. For this an ADC or analog to digital converter is needed. Most modern MCU including AVRs has an ADC on chip. An ADC converts an input voltage into a number. An ADC has a resolution. A 10 Bit ADC has a range of 0-1023. (2^10=1024) The ADC also has a Reference voltage (ARef). When input voltage is GND the output is 0 and when input voltage is equal to ARef the output is 1023. So the input range is 0-ARef and digital output is 0-1023. The Inbuilt AVR ADC Now you know the basics of ADC let us see how we can use the inbuilt ADC of AVR MCU. The ADC is multiplexed with PORTA that means the ADC channels are shared with PORTA. The ADC can be operated in single conversion and free running mode. In single conversion mode the ADC does the conversion and then stop. While in free it is continuously converting. It does a conversion and then start next conversion immediately after that The ADC has its own power supply, labeled ARef, on the ATMega16. This pin needs to be connected to a power source within .3 volts of the chip's VCC supply. Most of the time, you would wire this to VCC. With the 10 bit DAC, this allows measuring voltages from 0 to 5 volts with a resolution of 5/1024 volts, or 4.88 mV. ADC Prescaler The ADC needs a clock pulse to do its conversion. This clock generated by system clock by dividing it to get smaller frequency. The ADC requires a frequency between 50 KHz to 200 KHz. At higher frequency the conversion is fast while a lower frequency the conversion is more accurate. As the system frequency can be set to any value by the user (using internal or externals oscillators) so the Prescaler is provided to produces acceptable frequency for ADC from any system clock frequency. System clock can be divided by 2, 4, 16, 32, 64 &128 by setting the Prescaler. ADC Channels The ADC in ATmega16 has 8 channels that mean you can take samples from eight different terminals. You can connect up to 8 different sensors and get their values separately. ADC Registers As you know the registers related to any particular peripheral module (like ADC, Timer, USART etc.) provides the communication link between the CPU and that peripheral. You configure the ADC according to need using these registers and you also get the conversion result also using appropriate registers. The ADC has only four registers.
So, to set reference voltage equal to 5 volts i.e. AVCC ADMUX=(1<<REFS0); This 10 bit result of conversion is split across two 8 bit registers, ADCH and ADCL. By default, the lowest 8 bits of the ADC value are found in ADCL, with the upper two being the lowest two bits of ADCH. By setting the ADLAR bit in the ADMUX register, we can left align the ADC value. This puts the highest 8 bits of the measurement in the ADCH register, with the rest in the ADCL register. If we then read the ADCH register, we get an 8 bit value that represents our 0 to 5 volt measurement as a number from 0 to 255. We're basically turning our 10 bit ADC measurement into an 8 bit one. Here's the code to set the ADLAR bit: Code: ADMUX |= (1 << ADLAR); ADCSRA (ADC Control and Status Register A) For example, ADCSRA= (1<<ADEN)|(1<<ADPS2)|(ADPS1)|(ADPS0); //Enable ADC with Prescaler=128 Sample Code A simple test to check ADC of atmega16 is shown below, in which channel 1 of 8 ADC channels is used. A voltage divider network of 2 resistors is used, the voltage of R2 can have any value in between 0 to 5 volts. When VR2 results in a digital value greater than 200 then upper four bits of Port D are high and lower four bits are low and vice versa. #include<avr/io.h> #include<util/delay.h> void init_adc(); //initialize adc uint16_t start_adc(uint8_t);//start adc conversion int main() { uint8_t ch; //variable for channel uint16_t result; DDRA=0x00; //declared port A as input PORTA=0x00; //used port A in tri state DDRD=0xff; //port D as output init_adc(); while(1) { result=start_adc(1); //store adc output in variable "result" if(result>200) PORTD=0xf0; else PORTD=0x0f; } return 0; } void init_adc() { ADMUX=(1<<REFS0)|(1<<ADLAR); //uses reference AVcc and left shifted result ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //enable adc,128 prescale is set } uint16_t start_adc(uint8_t ch) { ch=ch&0x07; //channel selection ADMUX=ADMUX|ch; //put channel in ADMUX(in case of ch=0,channel 0 is selcted) ADCSRA|=1<<ADSC; //start adc conversion while(ADCSRA & (1<<ADSC)){}; //wait to complet adc conversion until ADSC=0; return ADC; //move ADC in result } References http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=56429&postdays=0&postorder=asc http://extremeelectronics.co.in/avr-tutorials/using-the-analog-to-digital-converter/
1 Comment
|
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |