Sunteți pe pagina 1din 9

ADCProjectwithATmega32

CCDharmaniwww.dharmanitech.com
*********************************
Hi friends,
Im presenting here a small project on how to make use of the ADC of ATmega32. The circuit
checks the voltage present at the ADC channel and displays voltage value on the LCD
(16x2). Whenever the push-button is pressed, the LCD displays voltage present on the next
ADC channel (total 8 channels, CH0 to CH7). The schematic and the firmware of the project
are given here.

Code:

Total 6 files: 3 program files (ADC_main.c, LCD_routines.c,


ADC_routines.c) and 3 header files(ADC_main.h, LCD_routines.h,
ADC_routines.h)
//*****************************************************************
//****************ADC_routines.h*********************
//*****************************************************************
#ifndefADC_ROUTINES_H
#defineADC_ENABLEADCSRA|=(1<<ADEN)
#defineADC_DISABLEADCSRA&=0x7F
#defineADC_START_CONVERSIONADCSRA|=(1<<ADSC)
voidADC_init(void)
intADC_read(void)
floatADC_calculateTemp(int)
unsignedchar*updateTempDisplay(float)
unsignedchar*temporary(void)
voidADC_displayValue(void)
#endif
//*****************************************************************
//****************ADC_routines.c*********************
//*****************************************************************
//Controller:ATmega32(16MHz)
//Compiler:ICCAVR
//Author:CCDharmani,Chennai
//Date:Aug2008
//*****************************************************************
#include<iom32v.h>
#include<macros.h>
#include"ADC_routines.h"
#include"LCD_routines.h"
unsignedcharvalueDisplay[]=":.volt"//11charglobalstringfor
//voltagevaluedisplay
floatVref=5.00//ReferencevoltageVrefofADC
//*****************************************************************
//Purpose:InitializetheADC
//*****************************************************************
voidADC_init(void)
{

ADCSRA=0x00//disableadc
ADMUX=0x40//selectadcinput0
ADCSRA=0x86
}
/********************************************************************
*Purpose:DoaAnalogtoDigitalConversion
*Paramtr:none
*return:integervoltagevalue
********************************************************************/
intADC_read(void)
{
chari
intADC_temp,ADCH_temp
intADC_var=0
ADC_ENABLE
ADC_START_CONVERSION//doadummyreadoutfirst
while(!(ADCSRA&0x10))//waitforconversiondone,ADIFflagactive
ADCSRA|=(1<<ADIF)
for(i=0i<8i++)//dotheADCconversion8timesforbetteraccuracy
{
ADC_START_CONVERSION
while(!(ADCSRA&0x10))//waitforconversiondone,ADIFflagset
ADCSRA|=(1<<ADIF)
ADC_temp=ADCL//readoutADCLregister
ADCH_temp=ADCH//readoutADCHregister
ADC_temp+=(ADCH_temp<<8)
ADC_var+=ADC_temp//accumulateresult(8samples)
//forlateraveraging
}
ADC_var=ADC_var>>3//averagethe8samples
ADC_DISABLE
returnADC_var
}
/**************************************************************************
*Purpose:Tocalculatetempindegrecelsius
*Paramtr:Integervalueofvoltage,receivedfromADCread
*Return:floatvoltagevalue
***************************************************************************/
floatADC_calculateValue(intinputValue)
{
floatactualValue
actualValue=(inputValue*Vref/1024.0)//calculatesthevoltagepresent
returnactualValue
}
/***************************************************************************
*Purpose:ToupdatethetempDisplaystringbasedonthelatesttempread

*Paramtr:Floatvalueofvoltage
*Return:StringpointerpointingtotheupdatedvalueDisplay
***************************************************************************/
unsignedchar*updateDisplay(floatactualValue)
{
inttemp
unsignedcharc
temp=(int)(actualValue*100.0)//toincludedecimalpointfordisplay
if((actualValue*100.0temp)>=0.5)temp=temp+1
valueDisplay[5]=((unsignedchar)(temp%10))|0x30
temp=temp/10
valueDisplay[4]=((unsignedchar)(temp%10))|0x30
temp=temp/10
valueDisplay[2]=((unsignedchar)(temp%10))|0x30
temp=temp/10
returnvalueDisplay
}
/**************************************************************************
*Purpose:TodisplayvalueofvoltageappliedtoselectedADCchannelon
theLCD
*Paramtr:None
*Return:None
***************************************************************************/
voidADC_displayValue(void)
{
intvalue
floatvalue1
value=ADC_read()
value1=ADC_calculateValue(value)
LCD_DisplayString(2,4,updateDisplay(value1))//voltagedisplayon2ndrow,
//4thcolumn
}
//*****************************************************************
//****************LCD_routines.c*********************
//*****************************************************************
#ifndefLCD_ROUTINES_H
//***LCDFunctionsdeclaration***//
voidLCD_init(void)
voidLCD_WriteCommand(unsignedcharCMD)
voidLCD_WriteData(unsignedcharData)
voidLCD_DisplayString_F(charrow,charcolumn,constunsignedchar*string)
voidLCD_DisplayString(charrow,charcolumn,unsignedchar*string)
voidLCD_Cursor(charrow,charcolumn)
voiddelay_ms(intmiliSec)

#defineENABLE_LCDPORTD|=0x80
#defineDISABLE_LCDPORTD&=~0x80
#defineSET_LCD_DATAPORTD|=0x20
#defineSET_LCD_CMDPORTD&=~0x20
#endif
//********************************************************
//**************LCD_routines.c******************
//********************************************************
//Controller:ATmega32(16MHz)
//Compiler:ICCAVR
//Author:CCDharmani,Chennai
//Date:Aug2008
//********************************************************
#include<iom32v.h>
#include<macros.h>
#include"LCD_routines.h"
//*********************************
//***InitializetheLCDdriver***
//*********************************
voidLCD_init(void)
{
delay_ms(100)//waitfor100ms
LCD_WriteCommand(0x38)//8datalines
LCD_WriteCommand(0x06)//cursorsetting
LCD_WriteCommand(0x0f)//displayON
LCD_WriteCommand(0x01)//clearLCDmemory
delay_ms(10)//10msdelayafterclearingLCD
}
//**********************************************
//***WriteacommandinstructiontotheLCD***
//**********************************************
voidLCD_WriteCommand(unsignedcharCommand)
{
SET_LCD_CMD//SetLCDincommandmode
PORTC=Command//Loaddatatoport
ENABLE_LCD//WritedatatoLCD
asm("nop")
asm("nop")
DISABLE_LCD//DisableLCD
delay_ms(1)//waitfor1ms
}

//*****************************************
//***WriteonebyteofdatatotheLCD***
//*****************************************
voidLCD_WriteData(unsignedcharData)
{
SET_LCD_DATA//SetLCDindatamode
PORTC=Data//Loaddatatoport
ENABLE_LCD//WritedatatoLCD
asm("nop")
asm("nop")
DISABLE_LCD//DisableLCD
delay_ms(1)//waitfor1ms
}
//*********************************************************************
//***Displayastringatthespecifiedrowandcolumn,fromFLASH****
//*********************************************************************
voidLCD_DisplayString_F(charrow,charcolumn,constunsignedchar
*string)
{
LCD_Cursor(row,column)
while(*string)
LCD_WriteData(*string++)
}
//*********************************************************************
//***Displayastringatthespecifiedrowandcolumn,fromRAM****
//*********************************************************************
voidLCD_DisplayString(charrow,charcolumn,unsignedchar*string)
{
LCD_Cursor(row,column)
while(*string)
LCD_WriteData(*string++)
}
//***************************************************
//***PositiontheLCDcursorat"row","column".***
//***************************************************
voidLCD_Cursor(charrow,charcolumn)
{
switch(row)
{
case1:LCD_WriteCommand(0x80+column1)break
case2:LCD_WriteCommand(0xc0+column1)break
default:break
}
}
//********************************************************
//****Functionfordelayof1msec(appx.)at16Mhz*****

//********************************************************
voiddelay_ms(intmiliSec)//for16Mhzcrystal
{
inti,j
for(i=0i<miliSeci++)
for(j=0j<1550j++)
{
asm("nop")
asm("nop")
}
}
//********************************************************************
//ADC_main.h
//********************************************************************
#ifndefADC_MAIN_H
#defineKEY_PRESSED!(PINB&0x02)
#defineKEY_OPEN(PINB&0x02)
voidport_init(void)
voidinit_devices(void)
#endif
//********************************************************************
//******MAINPROGRAMFORTESTINGADCOFMEGA32ADC_main.c******
//********************************************************************
//Controller:ATmega32(Crystal:16Mhz)
//Compiler:ICCAVR
//Author:CCDharmani,Chennai
//Date:Aug2008
//********************************************************************
#include<iom32v.h>
#include<macros.h>
#include"ADC_main.h"
#include"LCD_routines.h"
#include"ADC_routines.h"
//portinitialize
voidport_init(void)
{
DDRA=0x00
PORTA=0x00
DDRB=0x00
PORTB=0x02//internalpullupforpushbutton
DDRC=0xFF
PORTC=0x00
DDRD=0xF0
PORTD=0x00

}
//callthisroutinetoinitializeallperipherals
voidinit_devices(void)
{
//stoperrantinterruptsuntilsetup
CLI()//disableallinterrupts
port_init()
ADC_init()
LCD_init()
MCUCR=0x00
TIMSK=0x00//timerinterruptsources
//SEI()//reenableinterrupts
}
//MAINFUNCTION
voidmain(void)
{
unsignedcharchannel=0
init_devices()
LCD_DisplayString_F(1,1,"ADCTesting..")
while(1)
{
LCD_DisplayString_F(2,1,"CH")
LCD_WriteData(channel|0x30)//displaychannelnumber
START:
while(KEY_OPEN)//waitheretillkeyisopen
{
ADMUX&=0xe0
ADMUX|=channel//selectADCchannel
ADC_displayValue()
delay_ms(50)
}
delay_ms(20)//keydebouncedelaywhenkeyispressed
if(KEY_OPEN)
gotoSTART
while(KEY_PRESSED)//waitheretillkeyispressed
delay_ms(20)//keydebouncedelaywhenkeyisreleased
channel++//selectnextchannelafterkeypress
if(channel==8)//onlychannel0tochannel7canbeselected
channel=0
}

//***********************END**************************
CCDharmaniwww.dharmanitech.com

S-ar putea să vă placă și