View Full Version: INTERNAL ADC OF AVR(lm35)(c)

booksbybibin >>Microcontrollers >>INTERNAL ADC OF AVR(lm35)(c)


yogi- 07-28-2006
INTERNAL ADC OF AVR(lm35)(c)
This tutorial is taken from the book MY EXPERIENCE IN PROGRAMMING AVR MICROCONTROLLER IN C USING WINAVR/AVRGCC. you can download it free from the files section(FILE-AVRBOOK.RAR) of yahoo group-booksbybibin http://groups.yahoo.com/group/booksbybibin/ comments about this book on www.booksbybibin.blogspot.com INTERNAL ADC OF AVR See the datasheet for the registers. Atmeg32 has 10 bit ADC having two registers ADCL and ADCH. But we are using it in 8 bit resolution, so that error will be lowered. But there will always be noise error in the reading. I used LM35, got error about .01V. See even conversion is of 10 bit resolution and we are using 8 bits resolution(i.e, first 8 bits leaving last two LSB's). In 8 bit resolution mode we read ADCH. If you want to read 10 bits then use ADC(see in the include file, you will understand better). I used internal analog voltage reference of 2.56 volt. Remember to use a capacitor in the AREF pin, use a .01uF capacitor. The choice of capacitance will affect the reading. See in the datasheet how to avoid noise better. I tried with .1uF and .01uF capacitors. Here I am using LM35 temperature sensor to ADC input. FOLDER:lm_2-7seg(file-avrbook.rar from yahoo group-booksbybibin) main /*---------------------------------------------------------------- -----------------HEADER FILES------------------------------------- -----------------------------------------------------------------*/ #include "two7seg.c" /*---------------------------------------------------------------- -----------------FUNCTIONS--------------------------------------- -----------------------------------------------------------------*/ void Init_ADC(void); int Read_ADC(void); void main() { Init_ADC(); do { Ouptut_Display(Read_ADC()); } while(1); } void Init_ADC(void) { ADMUX|=(_BV(ADLAR) | _BV(REFS1)| _BV(REFS0)) ; // RFS1 and RFS0 are for Internal Reference voltage of 2.56V AND 8 BIT CONVERSION ADMUX&=~(_BV(MUX0)|_BV(MUX1)|_BV(MUX2)|_BV(MUX3)|_BV(MUX4)); //SELECTING CHANNEL0 ADCSRA|=(_BV(ADEN) | _BV(ADPS2) | _BV(ADPS0)) ; //normal conversion without interrupt ADCSRA&=~(_BV(ADSC)|_BV(ADATE)|_BV(ADIF)|_BV(ADIE)|_BV(ADPS1));//clock/32 speed } int Read_ADC(void) { ADCSRA|=_BV(ADSC); //start conversion while(!((ADCSRA&_BV(ADIF))>>ADIF)); return ADCH; } 7seg.c /*---------------------------------------------------------------- -----------------HEADER FILES------------------------------------- -----------------------------------------------------------------*/ #include<avr/io.h> /*---------------------------------------------------------------- -------------CONNECTION BETWEEN 7 segment AND ATMEGA32----------- -----------------------------------------------------------------*/ #define DATA_DDR DDRC #define DATA_PORT PORTC #define Pin_a 0 #define Pin_b 1 #define Pin_c 2 #define Pin_d 3 #define Pin_e 4 #define Pin_f 5 #define Pin_g 6 #define Pin_Dec 7 #define DATA_MASK 0XFF /*---------------------------------------------------------------- -----------------FUNCTIONS--------------------------------------- -----------------------------------------------------------------*/ void Init_Ports(void); void Display(int a); void delay_ms(unsigned char time_ms); /*---------------------------------------------------------------- -----------------FUNCTIONS TO INITIALIZE PORTS-------------------- -----------------------------------------------------------------*/ void Init_Ports(void) { DATA_DDR = DATA_MASK; //for setting data pin's for output } /*---------------------------------------------------------------- -----------------FUNCTIONS TO DISPLAY VALUES---------------------- -----------------------------------------------------------------*/ void Display(int a) { switch(a) { case 0: DATA_PORT|=_BV(Pin_g); DATA_PORT&=~(_BV(Pin_a)|_BV(Pin_b)|_BV(Pin_c)|_BV(Pin_d)|_BV(Pin_e)|_BV(Pin_f)); break; case 1: DATA_PORT|=(_BV(Pin_a)|_BV(Pin_d)|_BV(Pin_e)|_BV(Pin_f)|_BV(Pin_g)); DATA_PORT&=~(_BV(Pin_b)|_BV(Pin_c)); break; case 2: DATA_PORT|=(_BV(Pin_c)|_BV(Pin_f)); DATA_PORT&=~(_BV(Pin_b)|_BV(Pin_d)|_BV(Pin_e)|_BV(Pin_a)|_BV(Pin_g)); break; case 3: DATA_PORT|=(_BV(Pin_e)|_BV(Pin_f)); DATA_PORT&=~(_BV(Pin_c)|_BV(Pin_d)|_BV(Pin_a)|_BV(Pin_b)|_BV(Pin_g)); break; case 4: DATA_PORT|=(_BV(Pin_a)|_BV(Pin_d)|_BV(Pin_e)); DATA_PORT&=~(_BV(Pin_c)|_BV(Pin_b)|_BV(Pin_f)|_BV(Pin_g)); break; case 5: DATA_PORT|=(_BV(Pin_b)|_BV(Pin_e)); DATA_PORT&=~(_BV(Pin_a)|_BV(Pin_c)|_BV(Pin_d)|_BV(Pin_f)|_BV(Pin_g)); break; case 6: DATA_PORT|=(_BV(Pin_a)|_BV(Pin_b)); DATA_PORT&=~(_BV(Pin_c)|_BV(Pin_d)|_BV(Pin_f)|_BV(Pin_g)|_BV(Pin_e)); break; case 7: DATA_PORT|=(_BV(Pin_d)|_BV(Pin_e)|_BV(Pin_f)|_BV(Pin_g)); DATA_PORT&=~(_BV(Pin_a)|_BV(Pin_c)|_BV(Pin_b)); break; case 8: DATA_PORT&=~(_BV(Pin_a)|_BV(Pin_d)|_BV(Pin_e)|_BV(Pin_c)|_BV(Pin_b)|_BV(Pin_f)|_BV(Pin_g)); break; case 9: DATA_PORT|=(_BV(Pin_d)|_BV(Pin_e)); DATA_PORT&=~(_BV(Pin_a)|_BV(Pin_c)|_BV(Pin_b)|_BV(Pin_f)|_BV(Pin_g)); break; }} /*---------------------------------------------------------------- --------FUNCTION TO GENERATE DELAY IN MILLISECONDS---------------- -----------------------------------------------------------------*/ void delay_ms(unsigned char time_ms) { unsigned short delay_count = F_CPU / 400; unsigned short cnt; asm volatile ("\n" "L_dl1%=:\n\t" "mov %A0, %A2\n\t" "mov %B0, %B2\n" "L_dl2%=:\n\t" "sbiw %A0, 1\n\t" "brne L_dl2%=\n\t" "dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt) :"r"(time_ms), "r"((unsigned short) (delay_count)) ); } two7seg.c /*---------------------------------------------------------------- -----------------HEADER FILES------------------------------------- -----------------------------------------------------------------*/ #include "7seg.c" /*---------------------------------------------------------------- -------------CONNECTION BETWEEN 74126 AND ATMEGA32--------------- -----------------------------------------------------------------*/ #define CONTROL_DDR DDRD #define CONTROL_PORT PORTD #define Led_1 0 #define Led_2 1 #define CONTROL_MASK 0X03 /*---------------------------------------------------------------- -----------------FUNCTIONS--------------------------------------- -----------------------------------------------------------------*/ void Init126_Ports(void); void Ouptut_Display(int i); /*---------------------------------------------------------------- -----------------MAIN FUNCTION------------------------------------ -----------------------------------------------------------------*/ void Ouptut_Display(int i) { unsigned int a; Init126_Ports(); Init_Ports(); CONTROL_PORT|=_BV(Led_1); //switching ON first 7 segment to hold LSB Display((i%10&0x0f)); //delay_ms(500); CONTROL_PORT&=~_BV(Led_1); //switching OFF first 7 segment to hold LSB CONTROL_PORT|=_BV(Led_2); //switching ON first 7 segment to hold LSB a=i/10; Display((a%10&0x0f)); //delay_ms(500); CONTROL_PORT&=~_BV(Led_2); //switching OFF first 7 segment to hold LSB*/ //come fast otherwise display go off } void Init126_Ports(void) { CONTROL_DDR=CONTROL_MASK; //setting ports for output CONTROL_PORT&=~(_BV(Led_1)|_BV(Led_2)); //switching off 7 segment at starting } See the problem with persistance of vision. Here the temperature varies with time and it is shown on LED i.e, it is shown a non decimal value. ADCSRA|=_BV(ADSC); //start conversion while(!((ADCSRA&_BV(ADIF))>>ADIF)); return ADCH; Here I am using single conversion mode. I am waiting for the conversion to end and we are using 8 bit conversion mode. The 8 bit converted value is there in ADCH register and we are returning the values.


Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.