Az előző részben összeszedtünk, hogy mi is kell voltaképpen ahhoz, hogy programot írhassunk egy AVR mikrovezérlőre legyen modjuk egy ATMega16. A programban a kontroller néhány kimeneti kapcsát ki, míg másikakat bekapcsolunk.
Az ATMega16 lábkiosztása
Egy rövid kis kitérő a hardverre: Ebben a kódban a PORTB (B jelű port) minden kapcsa kimenetként van definiálva, és ezek közül néhány logikai 1 ( HIGH ), míg a többi logikai 0 ( LOW ) szintre van állítva. Ezek a kapcsok a rájuk kapcsolt elemekre kényesek lehetnek, így a legveszélytelenebb az, ha a program működését egy mérőműszerrel vizsgáljuk. A feszültségetket a test ( GND ), és a PORTB kapcsain ellenőrizzük.
#include <avr/io.h> int main () { DDRB = 0xFF; PORTB = 0x03; while(1) { /* üres ciklus*/ } return 0; //soha nem fog lefutni }
A első sorban az úgy nevezett Header-file-t include-ojuk. Ez olyan, mintha az io.h fájl tartalmát a program elejére másolnánk be. Ebben a fájlban a regiszterek nevei vannak definiálva, amiket a későbbiekben ismerünk meg.
A harmadik sorban kezdődik a valódi program. Minden programnak a main() függvénny a belépési pontja, ahonnan indul.
Az AVR kapcsai egy blokkba vannak összefoglalva. Egy ilyen blokkot nevezünk portnak. Az ATmega16 minden portja 8 kivezetésű, de a kissebb AVR-ekben lehetnek kevesebb kivezetések is. A tizenharmadik sorban határozzuk meg az adatirányregiszter segítségével, hogy a port egyes kapcsai bemenetek, vagy kimenetek legyenek. Az adatirányregiszter (DDRB) minden olyan bitjének, aminek logikai 1 értéket adunk, kimenetként fog viselkedni. Itt a PORTB minden kapcsa (PB0..PB7) kimenet, ezt a hatodik sorban 0xFF értékkel definiáljuk ( binárisan 0b11111111 ).
A hetedik sorban a kimenetek szintjeit állítjuk be. Itt a PORTB első kettő kapcsát (PB0, és PB1) állítjuk magas szintre (HIGH), mivel a PORTB- nak 0x03 értéket adtunk (0b00000011). Láthatjuk, hogy a PORTB többi PIN-jeit leíró bitek nem kaptak értéket, ( 0 ) így ezek alacsony szinten lesznek (LOW). Az aktív kimenetek (logikai 1, vagy HIGH) közel tápfeszültségen vannak (Vcc, legtöbbször ez 5V), míg a többi kimeneten nem lesz feszültség, (logikai 0, vagy LOW) ezek földpotenciálon (GND, 0V) vannak. Érdemes már most megszokni egy alternatív írásmódot a könnyebb olvashatóság, és a hordozhatóság érdekében, így a továbbiakban legtöbbször a következőképpen fogunk értékeket adni:
PORTB =(1<<PB1) | (1<<PB0);
A nyolcadik és a tizenegyedik sor foglalja magába a programunk főciklusát, ami a programfutás során – a kapcsos zárójelek közötti kód – folyamatosan ismétlődik. A kontroller azon kívül hogy áramot vesz fel nem csinál semmi egyebet, mivel a ciklusunk üres. Minden programba kell egy ilyen ciklus. Enélkül a program csupán egyszer futna le, és azután a kontroller állapota definiálatlan maradna. A tizenharmadik sorban van vége a programnak. Ez lesz a main() függvény visszatérési értéke. Ezt a részt a program soha nem fogja elérni, mivel nem fog soha a ciklusból kilépni. Ezt a sort csupán a C- fordító miatt írjuk be.
Végezetül mentsük el a fájlt demo.c néven.
Ahhoz, hogy a forráskódból a kontroller által futtatható állomány legyen, még le kell fordítsuk azt. Ezt a következő képpen tehetjük: Nyissunk egy Terminal/cmd ablakot. Másoljuk be az alábbi parancsokat egyenként, és minden sort külön futtassunk:
avr-gcc -g -Os -mmcu=atmega16 -c demo.c avr-gcc -g -mmcu=atmega16 -o demo.elf demo.o avr-objcopy -j .text -j .data -O ihex demo.elf demo.hex
Itt jegyzem meg, hogy Makefile használatával is lefordíthatjuk a kódot hex állománnyá, amit pl. win-avr-ben meg is lehet szerkeszteni könnyedén, de Linux vagy macOS alatt az avr-project projekt_neve terminal parancsal is létrejön, a projekt könyvtárral együtt A parancsok lefutása után égessük a kapott hex fájlt az AVR-be. Itt nem kívánok kitérni a hogyanra, mivel többféle szoftver és hardver létezik erre (itt említettem egyet, és itt még egyet). Égetés után a tápfeszültség rákapcsolásával a program a PB0 és PB1 kapcsokra logikai magas szintet ad, ezeken feszültség mérhető, míg a többi lábakon nem mérhető feszültség.
A következő cikkben megismerkedünk a ki -és bemenetek kezelésével.