Académique Documents
Professionnel Documents
Culture Documents
Introduction
Aswithothermicrocontrollers,thefirstprogrammingactivityisGPIO(GeneralPurposeInput/Output)control.
Inthisactivity,wewillbeintroducedwithutilizingGPIOsofATmega644.Gizduino+644willbeused.
WINAVR
ThelatestWinAVR(asofthiswriting)is20100120.ItisaGCCbasedcompilerforAVRmicrocontrollers.Itcomes
withitsownIDE,theProgrammerNotepadwhichcanbeusefulbutuserscanalsomakeuseofanytexteditor.Unlikeother
IDEs,usingWinAVRrequiresustomakeourownmakefile.Makefileissimplyascriptthatwillguideustocompileandlink
outprograms.WinAVRinstallationdocomewithamakefilewizard,theMfileeditor.
HelloWorldwithAVR
#include<avr/io.h>
#defineLEDPB7
unsignedchari,j;
voiddelay(void){
for(i=0;i<255;i++) {
for(j=0;j<255;j++);
}
}
intmain(void){
DDRB|=(1<<LED);
PORTB&=~(1<<LED);
while(1){
PORTB|=(1<<LED);
delay();
PORTB&=~(1<<LED);
delay();
}
return0;
}
Thecodeaboveissimpleblinkyprogram.LEDwillbeconnectedtopinPB5ofPORTB.
1|G e t t i n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
Aboutthecode
#include<avr/io.h>
ThislineincludesIO.Hwhichdescribesalldefinitionrequiredtosimplifythecoding.IO.Hcanbefoundin
C:\WinAVR20100110\avr\include\avr,assumingdefaultinstallationofWinAVR.InsideIO.H,theactualheader
filewillbepointedoutdependingonthedevicebeingused.Inourcase,itstheATMEGA644.ATMEGA644should
bedefinedinthemakefile(moreonthislater).
#defineLEDPB7
WedefineornamePB5asLED.PB5isassignedwith5.
unsignedchari,j;
voiddelay(void){
for(i=0;i<255;i++){
for(j=0;j<255;j++);
}
}
Thisfunctionisadelay(asoftwaredelay)thatwewillusetosufficientlyletusseetheblinkingoftheLED.
DDRB|=(1<<LED);
ThislinedefinesthedirectionofaparticularPIN/PORT.DDRBisPORTBDataDirectionRegister.Setting(1)anypin
indicatesanoutput.AndClearing(0)itmakesitaninput.
ThewaythelinewrittenisreferredtoasAVRstylenotation.Actually,thislineexecutesseveralcommands.LEDis
definedasthe5thpin(PB5).Therefore(1<<LED)meansweshifta1LEDtimes.Afterexecution,the8bitvalue
shouldbe0b00010000.
The|=isanORoperatorinC(justlikeinC++).
So,theDDRB|=(1<<LED)islikeDDRB=DDRBOR0b00010000.ThistellsusthatwhenweORaparticularbit/s
with1,itbecomes1.
Inrelationtothis,itisworthnoting:
ThatwhenwewanttomakeabitHIGH,weORitwith'1'.
Example:
REG=0b00001010;
REG=REGOR0b11000000; //REGbecomes0b11001010.
//Thiscanbealsowritenas
REG|=0b11000000;
AndwhenwewanttomakeabitLOW,weANDitwith'0'.
Example:
REG=0b11001010;
REG=REGAND0b00111111; //REGbecomes0b00001010
//Thiscanalsobewritenas
REG&=~0b11000000; //&=isANDoperatorand~isNOToperator
PORTB&=~(1<<LED);
Wewrite0toPORTBpinPB5.
2|G e t t i n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
while(1){
PORTB|=(1<<LED);
delay();
PORTB&=~(1<<LED);
delay();
}
ThisforeverloopshouldtogglethestateoftheLED.SettingapinmakesitHIGHandclearingmakesitLOW
UsingWinAVR
Copypastethecodeabovetoatexteditorandsaveitinfolderwithanyfilenamewithcextension(figure1).
Forthisactivity,letuscallitasmain.c.
Figure1.ThehelloworldusingNotepad++astexteditor.
Launchmfile(fromStartmenu).Adefaultmakefilescriptwillbeshown,saveittoyourworkingfolder(the
folderwhereyousavedthemain.c).
3|G e t t i n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
Figure2.Makefilegenerationonmfile.
Gotheworkingfolderandopenmakefilewithanytexteditor.Andeditthefollowinglinesas:
MCU=atmega644p
F_CPU=16000000
AVRDUDE_PROGRAMMER=Arduino
AVRDUDE_PORT=usb
Thensaveit.
16MHzistheoscillatorinstalledinthegizDuino+644.
Figure3.EditingtheMakefile.
4|G e t t i n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
Openyourcommandpromptandgototheworkingregisterandtypethecommandmakeall.
Themakeallcommandcompiles,linksandgeneratesoutputfiles,suchasHEX,ELFandCOF.Wewillbe
needingHEXfile.
Figure4.Workingfoldershowingthefilesgeneratedafter"makeall".
Connectthegizduino+644ponyourUSBportandwaitforenumerationofthePL2303USBtoserialdriver.
Thedrivercanbedownloadedfrom:http://www.prolific.com.tw/US/ShowProduct.aspx?p_id=225&pcid=41
ConnectanLEDonPB7(withalimitresistor).PB7isPIN13ingizduino+.(Refertotheschematicincludedon
thisactivity)
Inthecommandpromptonthesamefolder,typemakeprogram.TheHEXfilewillnowbedownloaded.
AnLEDonPB7shouldblinkveryfastbutisnoticeable.
Note:Whenrecompilingorusingmakeall,besuretocleanitfirstbymakeclean.Youcanalsomakeuse
ofanoscilloscopeinsteadofLEDtoverifyyourcode.
Usingamoreaccuratedelay
ThereisanincorporateddelayfunctionthatcomeswithWinAVR.Utilizingitissimplybyincludingitasaheader.
Thecodebelowdemonstratetheusageofthedelayfunctionandtheinclusionoftheheaderfile.
#include<avr/io.h>
#include<util/delay.h>
#defineLEDPB7
intmain(void)
{
DDRB|=(1<<LED);
PORTB&=~(1<<LED);
while(1)
{
PORTB|=(1<<LED);
_delay_ms(500);
PORTB&=~(1<<LED);
_delay_ms(500);
}
return0;
5|G e t t i n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
InputswithAVR
Thereare3RegistersinvolvinganI/Oregister.ForPORTB,theseareDDRB,PORTBandPINB.DDRDisasweknowisthe
DataDirectionRegister,PORTBistheDataRegisteritselfandPINBistheInputregisterforPORTB.Whenwewanttowrite
toPORTB,wewritetoPORTBandwhenwewanttoreadPORTB,wereadPINB.
Thecodebelowwillshowushowreadapin.PINBbitzeroistodetectanactivelowsignal.Whenanactivelowisdetected
itshalltoggletheLEDconnectedtobit0.
ThecodebelowshalldemonstratetheusageofanI/Oasinput.
#include<avr/io.h>
#include<util/delay.h>
#defineSWITCH PB0
#defineLED PD0
intmain(void)
{
DDRB&=~(1<<SWITCH);//PB0asinput
DDRD|=(1<<LED); //bit0isoutput
PORTD=(1<<LED); //initializeLEDtoHIGH
while(1)
{
if(!(PINB)&(1<<SWITCH)) //detectsifSWITCHisLOW
{
_delay_ms(200); //adebouncedelay
PORTD^=(1<<LED); //toggleLED
}
}
return0;
}
Theschematicblowshalldemonstratetheinputtingcode.
6|G e t t i n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g
DesignProblem:Keypaddecoder
UsingAVRCprogramming,youaretodecodeakeypadandsimulateitinProteus.Youmayfollowtheschematic
beloworassignyourI/Otootherpins.Theprogramwillshowthenumberpressedonthesevensegment.The
valueshallnotchangeuntilanotherkeyispressed.
7|G e t t i n g S t a r t e d w i t h E m b e d d e d C : A V R p r o g r a m m i n g