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.

How Work ADC in AVR- Microcontroller

The AVR ADC allows the AVR microcontroller to convert analog voltages to digital values with few to no external parts. The ATmega8 features a 10-bit successive approximation ADC.ATmega8 has 7 channel ADC at PortC. The ADC has a separate analog supply voltage pin, AVCC. AVCC must not differ more than ± 0.3V from VCC.. The voltage reference may be externally decoupled at the AREF pin. AVCC is used as the voltage reference. The ADC can also be set to run continuously (the free-running mode) or to do only one conversion.

ADC Conversion Formula

Where Vin is the voltage on the selected input pin and Vref the selected voltage reference

How to configure ADC in ATmega8?

The following Registers are used for implementation of ADC in ATmega8

ADC Multiplexer Selection

ADC Multiplexer Selection

 ADLAR Selection

 ADC Left Adjust Result The ADLAR bit affects the presentation of the ADC conversion result in the ADC Data Register. Write one to ADLAR to left adjust the result. Otherwise, the result is right adjusted

ADLAR Selection

When an ADC conversion is complete, the result is found in ADCH and ADCL When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently, if the result is left adjusted and no more than 8-bit precision is required, it is sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH. 
Analog Channel Selection Bits The value of these bits selects which analog inputs are connected to the ADC. 


 ADCSRA Selection 

• Bit 7 – ADEN: ADC Enable Writing this bit to one enables the ADC. By writing it to zero, the ADC is turned off 
• Bit 6 – ADSC: ADC Start Conversion In Single Conversion mode, write this bit to one to start each conversion. In Free Running mode, write this bit to one to start the first conversion.
 • Bit 5 – ADFR: ADC Free Running Select When this bit is set (one) the ADC operates in Free Running mode. In this mode, the ADC samples and updates the Data Registers continuously. Clearing this bit (zero) will Terminate Free Running mode. 
• Bit 4 – ADIF: ADC Interrupt Flag This bit is set when an ADC conversion completes and the Data Registers are updated. The ADC Conversion Complete Interrupt is executed if the ADIE bit and the I-bit in SREG are set. ADIF is cleared by hardware when executing the corresponding interrupt Handling Vector. Alternatively, ADIF is cleared by writing a logical one to the flag. 
• Bit 3 – ADIE: ADC Interrupt Enable When this bit is written to one and the I-bit in SREG is set, the ADC Conversion Complete Interrupt is activated. 
• Bits 2:0 – ADPS2:0: ADC Prescaler Select Bits According to the datasheet, this prescalar needs to be set so that the ADC input frequency is between 50 KHz and 200 KHz. The ADC clock is derived from the system clock with help of 
ADPS2:0 These bits determine the division factor between the XTAL frequency and the input clock to the ADC. 



 If you want to take ADC value you have to need some work done that listed below

  • Set ADC value
  • Configure output LED pin 
  • Configure ADC Hardware 
  • Enable ADC 
  • Start Analog to Digital Conversions
  • WHILE Forever

 IF ADC Value Higher then Set value, Turn on LED ELSE Turn Off LED 

Set ADC value

Code: uint8_t ADCValue =128; 

Configure output LED pin 

Code:  DDRB|= (1 << PB1); 

Configure ADC Hardware 

This is done through setting bits in the control registers for the ADC. First, let's set the prescalar for the ADC. According to the datasheet, this prescalar needs to be set so that the ADC input frequency is between 50 KHz and 200 KHz. The ADC clock is derived from the system clock. With a system frequency of 1MHz, a prescaler of 8 will result in an ADC frequency of 125 Khz. The prescaling is set by the ADPS bits in the ADCSRA register. According to the datasheet, all three ADPS2:0 bits must be set to 011 to get the 8 prescaler.
 Code : ADCSRA |= (0 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); 

Next, let's set the ADC reference voltage. This is controlled by the REFS bits in the ADMUX register. The following sets the reference voltage to AVCC.
 Code: ADMUX |= (1 << REFS0); 

To set the channel passed through the multiplexer to the ADC, the MUX bits in the ADMUX register need to be set accordingly. Since we are using ADC5 here 
Code: ADMUX&=0xF0; ADMUX|=5; 

In order to put the ADC into free-running mode, set the aptly-named ADFR bit in the ADCSRA register: 
Code: ADCSRA |= (1 << ADFR); 
One last settings change will be made to make reading the ADC value simpler. Though the ADC has a resolution of 10 bits, this much information is often not necessary. This 10 bit value 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); 
That completes the setup of the ADC hardware for this example. Two more bits need to be set before the ADC will start taking measurements. 

Enable ADC 

To enable the ADC, set the ADEN bit in ADCSRA: 
Code: ADCSRA |= (1 << ADEN); 

Start Analog to Digital Conversions

To start the ADC measurements, the ADSC bit in ADCSRA needs to be set: 
Code: ADCSRA |= (1 << ADSC); 
At this point, the ADC would begin continuously sampling the voltage presented on ADC5. The code to this point would look like this: 

WHILE Forever

The only thing left to do is test the ADC value and set the LEDs to display a high / low indication. Since the ADC reading in ADCH has a maximum value of 255, a test value of th was chosen to determine whether the voltage was high or low. A simple IF/ELSE statement in the FOR loops will allow us to turn the correct LED on: 
Code
if(ADCH >ADCValue)
 { 
 PORTB |= (1 << PB0); // Turn on LED 
 }
 else 
 { 
 PORTB&= ~(1 << PB0); // Turn off LED 
 } 

At the end Complete code is
Code:
 #include <avr/io.h>
int main (void) 
{
 uint8_t ADCValue =128;
 DDRB |= (1 << PB0); // Set LED1 as output 
ADCSRA |= (0 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Set ADC prescalar to 8 - // 125KHz sample rate 1MHz 
ADMUX |= (1 << REFS0); // Set ADC reference to AVCC 
ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading 
ADMUX&=0xF0; 
ADMUX|=5; // MUX values needed to be changed to use ADC0
 ADCSRA |= (1 << ADFR); // Set ADC to Free-Running Mode 
ADCSRA |= (1 << ADEN); // Enable ADC
 ADCSRA |= (1 << ADSC); // Start A2D Conversions while(1) // Loop Forever 
 {
 if(ADCH > ADCValue) 
 {
 PORTB |= (1 << PB0); // Turn on LED1
 } 
 else {
 PORTE &= ~(1 << PB1); // Turn off LED1 
 } 
 }
 return 0; }


No comments

Theme images by Dizzo. Powered by Blogger.