Programiranje mikroupravlja£a porodice AVR - VUB

262

Transcript of Programiranje mikroupravlja£a porodice AVR - VUB

VELEUILITE U BJELOVARU

MIKROUPRAVLJAI

Programiranje mikroupravlja£a porodice AVR

Prvo izdanje

Bjelovar, 2020.

ii

dr. sc. Zoran Vrhovski

MIKROUPRAVLJAIProgramiranje mikroupravlja£a porodice AVR

Izdava£:Veleu£ili²te u Bjelovaru

Za izdava£a:doc. dr. sc. Zrinka Puhari¢, dr. med.

Tehni£ki urednik:dr. sc. Zoran Vrhovski

Recenzenti:dr. sc. Mihael Kukecdr. sc. Igor Petrovi¢

Lektorica:Mirjana Bu£ar, prof.

Prijelom i oblikovanje naslovnice / gra£ki urednik:dr. sc. Zoran Vrhovski

ISBN 978-953-7676-34-6

c©Niti jedan dio ove knjige ne smije se preslikavati ni umnoºavatibez prethodne pismene suglasnosti autora.

dr. sc. Zoran Vrhovski

MIKROUPRAVLJAIProgramiranje mikroupravlja£a porodice AVR

Prvo izdanje

Bjelovar, 2020.

iv

Predgovor

Tko ºeli ne²to nau£iti, na¢i ¢e na£in;

tko ne ºeli, na¢i ¢e izliku.

Pablo Picasso

Udºbenik Mikroupravlja£i namijenjen je prvenstveno studentima preddiplomskih stru£nihstudija Mehatronika i Ra£unarstvo na Veleu£ili²tu u Bjelovaru koji u svom studijskom programuslu²aju predmet koji se bavi mikroupravlja£ima. Svakako se ovaj rukopis moºe koristiti i nadrugim visokim u£ili²tima koja se u svom nastavnom programu bave mikroupravlja£ima.

Ovaj udºbenik opisuje razvoj programa za mikroupravlja£ ATmega32U4 u programskomokruºenju Atmel Studio 7. Programi su pisani u sintaksi programskih jezika C i C++. Vjeºbekoje ¢e biti opisane u ovom udºbeniku napisane su u programskom okruºenju Atmel Studio 7i nalaze se na mreºnoj stranici www.vub.hr/mikroracunala. Uz vjeºbe se na mreºnoj stranicinalaze i rje²enja vjeºbi kako biste mogli provjeriti ispravnost vlastitih programskih rje²enja. Uudºbeniku su opisana rje²enja ukupno 58 vjeºbi koje su vrlo prakti£ne i daju dobar uvod u svijetrazvoja programske podr²ke za ugradbene ra£unalne sustave.

Motiv pisanja ovog udºbenika jest nepostojanje sli£nog rukopisa na hrvatskom jeziku. Akobudete uºivali u £itanju ovog udºbenika i radu na razvojnom okruºenju s mikroupravlja£emATmega32U4 barem upola kao ²to sam ja uºivao stvaraju¢i rukopis, moja ¢e misija biti ispunjena.Moºda se pitate za²to nisam koristio neku drugu porodicu mikroupravlja£a pri pisanju udºbenika.Odgovor je vrlo jednostavan. Ja sam veliki ljubitelj AVR porodice mikroupravlja£a i to je jedinirazlog.

Zahvaljujem se recenzentima dr. sc. Mihaelu Kukecu i dr. sc. Igoru Petrovi¢u na korisnimsavjetima i sugestijama te lektorici Mirjani Bu£ar, prof. na strpljenju pri £itanju ovog udºbenikai usklaivanju teksta s hrvatskim standardnim jezikom.

Posebno se zahvaljujem Veleu£ili²tu u Bjelovaru na potpori u izdavanju ove knjige. Velikuzahvalnost upu¢ujem kolegi Goranu Benkeku koji je aktivno radio na razvoju i proizvodnjirazvojnog okruºenja s mikroupravlja£em ATmega32U4.

Udºbenik posve¢ujem k¢eri Soji i supruzi Ani. Obje ste moj neiscrpan izvor energije i hvalavam na tome.

Zoran Vrhovski

vi

Sadrºaj

1 Uvod 1

2 Razvojno okruºenje Atmel Studio 7 3

2.1 Odabir razvojnog okruºenja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.2 Stvaranje projekta u razvojnom okruºenju Atmel Studio 7 . . . . . . . . . . . . . 4

3 Snimanje i pokretanje strojnog koda na mikroupravlja£u ATmega32U4 11

3.1 Razvojno okruºenje s mikroupravlja£em ATmega32U4 . . . . . . . . . . . . . . . 11

3.2 Programiranje mikroupravlja£a ATmega32U4 . . . . . . . . . . . . . . . . . . . . 15

4 Digitalni izlazi i ulazi 25

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4 . . . . . . . . . . . . . . . . . . . . 26

4.1.1 Vjeºbe - digitalni izlazi mikroupravlja£a ATmega32U4 . . . . . . . . . . . 26

4.1.2 Zadaci - digitalni izlazi mikroupravlja£a ATmega32U4 . . . . . . . . . . . 42

4.2 Digitalni ulazi mikroupravlja£a ATmega32U4 . . . . . . . . . . . . . . . . . . . . 44

4.2.1 Vjeºbe - digitalni ulazi mikroupravlja£a ATmega32U4 . . . . . . . . . . . 45

4.2.2 Zadaci - digitalni ulazi mikroupravlja£a ATmega32U4 . . . . . . . . . . . 58

5 LCD displej 61

5.1 Vjeºbe - LCD displej . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

5.1.1 Zadaci - LCD displej . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

6 EEPROM memorija 81

6.1 Vjeºbe - EEPROM memorija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

6.1.1 Zadaci - EEPROM memorija . . . . . . . . . . . . . . . . . . . . . . . . . 84

7 Analogno-digitalna pretvorba 85

7.1 Vjeºbe - analogno-digitalna pretvorba . . . . . . . . . . . . . . . . . . . . . . . . 85

7.1.1 Zadaci - analogno-digitalna pretvorba . . . . . . . . . . . . . . . . . . . . 99

8 Tajmeri i broja£i 101

8.1 Vjeºbe - Normalan na£in rada tajmera . . . . . . . . . . . . . . . . . . . . . . . 105

8.1.1 Zadaci - Normalan na£in rada tajmera . . . . . . . . . . . . . . . . . . . . 123

8.2 Vjeºbe - PWM na£in rada tajmera . . . . . . . . . . . . . . . . . . . . . . . . . . 124

viii SADRAJ

8.2.1 Fast PWM na£in rada tajmera . . . . . . . . . . . . . . . . . . . . . . . . 124

8.2.2 Phase Correct PWM na£in rada tajmera . . . . . . . . . . . . . . . . . . 127

8.2.3 Konguracija PWM na£ina rada tajmera pomo¢u zaglavlja "timer.h" . . 130

8.2.4 Zadaci - PWM na£in rada tajmera . . . . . . . . . . . . . . . . . . . . . . 147

9 Numeri£ki displej i posma£ni registar 149

9.1 Vjeºbe - numeri£ki displej i posma£ni registar . . . . . . . . . . . . . . . . . . . . 156

9.2 Zadaci - numeri£ki displej . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

10 Univerzalna asinkrona serijska komunikacija 175

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija . . . . . . . . . . . . . . . . 177

10.1.1 Zadaci - univerzalna asinkrona serijska komunikacija . . . . . . . . . . . . 204

11 Vanjski prekidi 207

11.1 Vjeºbe - vanjski prekidi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

11.1.1 Zadaci - vanjski prekidi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218

12 Povezivanje odabranih elektroni£kih modula na mikroupravlja£ 219

12.1 Rotacijski enkoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

12.1.1 Zadatak - rotacijski enkoder . . . . . . . . . . . . . . . . . . . . . . . . . . 226

12.2 Tranzistor kao sklopka i relej . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227

12.2.1 Zadatak - tranzistor kao sklopka i relej . . . . . . . . . . . . . . . . . . . . 230

12.3 Ultrazvu£ni senzor HC-SR04 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230

12.3.1 Zadatak - ultrazvu£ni senzor HC-SR04 . . . . . . . . . . . . . . . . . . . . 236

12.4 Temperaturni senzor LM35 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236

12.4.1 Zadatak - temperaturni senzor LM35 . . . . . . . . . . . . . . . . . . . . . 238

12.5 Servomotor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239

12.5.1 Zadatak - servomotor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246

12.6 RGB dioda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246

12.6.1 Zadatak - RGB dioda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249

Bibliograja 250

Poglavlje 1

Uvod

Mikrora£unala su mala, relativno jeftina i pouzdana ra£unala koja sadrºe mikroprocesor kaocentralnu procesorsku jedinicu, memoriju te ulazno/izlazne digitalne pinove koji omogu¢uju vezus vanjskim okruºenjem.

Mikroupravlja£i su upravlja£ka mikrora£unala posebne namjene. Ova mikrora£unalasadrºe programirljive ulazno/izlazne digitalne pinove, tajmere, analogno-digitalne pretvornike,su£elja za serijsku komunikaciju i drugo. Dana²nji elektroni£ki ureaji nezamislivi su bezmikroupravlja£a koji sluºi za obradu signala, upravljanje sustavima, prikupljanje informacijaiz sustava i sli£no. Mikroupravlja£i se koriste u automobilima, sustavima automatizacije,ku¢anstvima, mjernim instrumentima, pametnim ku¢ama, robotima, CNC strojevima, LEDrasvjeti, odnosno gotovo u svim tehni£kim sustavima. Jedan automobil ima na desetkemikroupravlja£a koji su sastavni dio sustava sigurnosti, putnog ra£unala, navigacijskog sustava,ozvu£enja, sustava zra£nih jastuka i drugih.

Ovaj udºbenik opisuje razvoj programa za mikroupravlja£ ATmega32U4 u programskomokruºenju Atmel Studio 7. Programi su pisani u sintaksi programskih jezika C i C++. Vjeºbekoje ¢e biti opisane u ovom udºbeniku napisane su u programskom okruºenju Atmel Studio 7i nalaze se na mreºnoj stranici www.vub.hr/mikroracunala. Uz vjeºbe se na mreºnoj stranicinalaze i rje²enja vjeºbi kako biste mogli provjeriti ispravnost vlastitih programskih rje²enja. Uudºbeniku su opisana rje²enja ukupno 58 vjeºbi koje su vrlo prakti£ne i daju dobar uvod u svijetrazvoja programske podr²ke za ugradbene ra£unalne sustave.

U ovom uvodnom poglavlju ukratko ¢emo pro¢i kroz sva poglavlja ovog udºbenika kakobismo zainteresirali £itatelje, a to su na prvom mjestu studenti preddiplomskih stru£nih studijaMehatronika i Ra£unarstvo na Veleu£ili²tu u Bjelovaru.

U drugom poglavlju ukratko su opisana programska okruºenja koja se koriste za razvojprograma za mikroupravlja£ ATmega32U4. Nadalje, opisano je stvaranje projekata uprogramskom okruºenju Atmel Studio 7.

Razvojno okruºenje s mikroupravlja£em ATmega32U4 i programiranje mikroupravlja£aATmega32U4 pomo¢u softvera eXtreme Burner AVR te pomo¢u programskog okruºenja AtmelStudio 7 opisano je u tre¢em poglavlju.

Digitalni izlazi i ulazi mikroupravlja£a ATmega32U4 kao veza prema vanjskom okruºenjuopisani su u £etvrtom poglavlju. Mikroupravlja£ ATmega32U4 ima 26 digitalnih pinova kojiimaju vi²e namjena, a svaki pin zasebno mogu¢e je kongurirati kao izlaz ili kao ulaz. Ako jepin konguriran kao ulazni pin, na njemu je mogu¢e uklju£iti pritezni otpornik, ²to je korisno zadigitalne senzore s otvorenim kolektorom, tipkala i krajnje prekida£e.

U petom poglavlju opisan je LCD displej koji se £esto koristi za prikazivanje varijabli sustava

2 Uvod

u kojem se nalazi mikroupravlja£. Prikazana je konguracija raznih tipova LCD displeja koji semogu spojiti na mikroupravlja£ ATmega32U4.

EEPROM memorija koja podatke £uva i kad nema napajanja mikroupravlja£a opisana je u²estom poglavlju.

U sedmom poglavlju opisano je kori²tenje analogno-digitalne pretvorbe na mikroupravlja£uATmega32U4. Analogni senzori koji se koriste za mjerenje napona, tlaka, vlage, temperature idrugih zikalnih veli£ina £esto se koriste u kombinaciji s mikroupravlja£ima koji mjerne rezultatemogu prikazivati na LCD displeju ili na neki drugi na£in.

Primjena tajmera i broja£a opisana je u osmom poglavlju. Ovo je jedno od najvaºnijihpoglavlja jer je primjena tajmera i broja£a ²iroka. Opisana su tri na£ina rada tajmera: normalanna£in rada, Fast PWM na£in rada i Phase Correct PWM na£in rada. Ovo poglavlje predstavljauvod u prekide i prekidne rutine.

U devetom poglavlju opisano je kori²tenje posma£nog registra i numeri£kih displeja. Primjenaposma£nog registra velika je, a naj£e²¢e se koristi u svrhu pro²irenja digitalnih izlaza. Numeri£kidispleji koriste se za prikaz broj£anih vrijednosti.

Univerzalna asinkrona serijska komunikacija opisana je u desetom poglavlju. Uz ovo poglavljedostupna je aplikacija kojom se testira asinkrona serijska komunikacija izmeu ra£unala imikroupravlja£a ATmega32U4. Ovo poglavlje bitno je zbog upravljanja i nadzora sustavapomo¢u ra£unala gdje je mikroupravlja£ posrednik u komunikaciji.

U jedanaestom poglavlju opisani su vanjski prekidi. Ovi prekidi generiraju se na temeljuvanjskih dogaaja koji su naj£e²¢e rastu¢i i padaju¢i bridovi signala s digitalnih senzora.

U zadnjem, dvanaestom poglavlju opisani su elektroni£ki moduli koji se mogu spojiti namikroupravlja£ ATmega32U4. Elektroni£ki moduli koji su opisani u ovom poglavlju jesurotacijski enkoder, tranzistor kao sklopka i relej, ultrazvu£ni senzor HC-SR04, temperaturnisenzor LM35, servo motor i RGB dioda. Za svaki od modula razvijen je i program kojim setestira pojedini elektroni£ki modul.

Poglavlje 2

Razvojno okruºenje Atmel Studio 7

2.1 Odabir razvojnog okruºenja

Prvi korak u razvoju strojnog koda za mikroupravlja£ jest odabir razvojnog okruºenja ukojem ¢emo stvarati programska rje²enja za zadani problem. Na trºi²tu postoje razna programskaokruºenja. Neka od njih jesu:

• BASCOM,

• CodeVision,

• AVR Studio 5,

• MPLAB X IDE i

• Atmel Studio 7 .

Programsko okruºenje BASCOM jednostavno je za kori²tenje zato ²to ima podr²ku za nizelektroni£kih ureaja koji se mogu priklju£iti na mikroupravlja£. Programski jezik koji za razvojaplikacija koristi BASCOM jest Basic. Nedostaci ovog programskog okruºenja jesu zatvorenostprogramskog koda, programiranje u programskom jeziku Basic1 i nemogu¢nost naprednijegrazvijanja aplikacija. Programsko okruºenje BASCOM preporu£uje se po£etnicima te onimakoji se mikroupravlja£ima bave iz hobija.

Programsko okruºenje CodeVision, kao i BASCOM, ima podr²ku za niz elektroni£kihureaja. Prednost naspram programskog okruºenja BASCOM jest kori²tenje programskog jezikaC za programiranje. Najve¢i nedostatak programskog okruºenja CodeVision zatvorenost jeprogramskog koda. Programsko okruºenje CodeVision preporu£ujemo po£etnicima koji ºeleprogramirati u ozbiljnijem programskom jeziku i onima koji kasnije ºele jednostavno prije¢i nanaprednija razvojna okruºenja.

AVR Studio 5 prete£a je razvojnog okruºenja Atmel Studio 7 koje ¢emo koristiti u nastavkuovog udºbenika. Atmel Studio 7 profesionalno je razvojno programsko okruºenje za stvaranjeaplikacija mikroupravlja£a porodice Atmel. Ovo programsko okruºenje izraeno je na platformiprogramskog okruºenja Visual Studio koje slovi za jedno od najboljih programskih okruºenja.Prema tome, Atmel Studio 7 ima sve prednosti koje donosi programsko okruºenje Visual Studio.Razvojno je okruºenje Atmel Studio 7 besplatno, za razliku od programskih okruºenja BASCOM

1U dana²nje vrijeme programski jezik Basic gotovo se ne koristi zbog niza nedostataka.

4 Razvojno okruºenje Atmel Studio 7

i CodeVision. MPLAB X IDE razvojno je okruºenje istog proizvoa£a kao i razvojno okruºenjeAtmel Studio 7. Radi se o tvrtki Microchip koja je od 2016. godine preuzela tvrtku Atmel.MPLAB X IDE razvojno je okruºenje koje omogu¢uje programiranje mikroupravlja£a porodicePIC, dsPIC, AVR, SAM itd. Programski jezici koji su podrºani ovim razvojnim okruºenjemjesu C i C++. MPLAB X IDE vrlo je napredno razvojno okruºenje, no za AVR porodicumikroupravlja£a ono je u beta verziji.

Od navedenih razvojnih okruºenja, zbog svih prednosti, za daljnji razvoj programskih rje²enjakoristit ¢emo Atmel Studio 7 . Najnoviju verziju razvojnog okruºenja Atmel Studio 7 moºetepreuzeti na stranici https://www.microchip.com/mplab/avr-support/atmel-studio-7.

2.2 Stvaranje projekta u razvojnom okruºenju Atmel Studio 7

Razvojno okruºenje Atmel Studio 7 moºemo pokrenuti dvostrukim klikom na ikonu sa slike2.1.

Slika 2.1: Atmel Studio 7 - ikona

Nakon pokretanja razvojnog okruºenja Atmel Studio 7, pojavit ¢e se po£etna stranicaprikazana na slici 2.2.

Slika 2.2: Razvojno okruºenje Atmel Studio 7 - po£etna stranica

Po£etna stranica omogu¢uje nam stvaranje novog projekta, otvaranje postoje¢eg projekta iliotvaranje nedavno otvorenog projekta. Novi projekt moºemo stvoriti na jedan od dvaju na£ina:

1. na po£etnoj stranici odaberite New Project... (slika 2.3) ili

2.2 Stvaranje projekta u razvojnom okruºenju Atmel Studio 7 5

2. u izborniku odaberite File → New → Project... (slika 2.4),

nakon £ega ¢e se otvoriti prozor prikazan na slici 2.5 koji sluºi za unos vrste, imena i lokacijeprojekta.

Slika 2.3: Razvojno okruºenje Atmel Studio 7 - stvaranje novog projekta (1)

Slika 2.4: Razvojno okruºenje Atmel Studio 7 - stvaranje novog projekta (2)

U prozoru sa slike 2.5 potrebno je provesti korake ozna£ene brojevima od 1 do 6:

1. U izborniku Installed Templates odaberite C/C++.

2. Odaberite GCC C++ Executable Project.

3. Upi²ite ime projekta (npr. Prvi projekt).

4. Odaberite lokaciju projekta (npr. C:\Mikroracunala\Prvi projekt\).

5. Odaberite ime solucije2 (npr. Prvi projekt).

6. Pritisnite OK za nastavak.

2U razvojnom okruºenju Atmel Studio 7 jedna solucija moºe imati nekoliko projekata.

6 Razvojno okruºenje Atmel Studio 7

Slika 2.5: Razvojno okruºenje Atmel Studio 7 - prozor za unos vrste, imena i lokacije projekta

Nakon prozora sa slike 2.5 otvara se novi prozor u kojem je mogu¢e odabrati mikroupravlja£za koji ¢emo pisati program (slika 2.6).

Slika 2.6: Razvojno okruºenje Atmel Studio 7 - odabir mikroupravlja£a

2.2 Stvaranje projekta u razvojnom okruºenju Atmel Studio 7 7

Odabir mikroupravlja£a prikazan je koracima od 1 do 4 na slici 2.6:

1. Odaberite porodicu mikroupravlja£a (npr. ATmega).

2. Odaberite mikroupravlja£ iz odabrane porodice (npr. ATmega32U4).

3. Korak 1 i 2 mogu se presko£iti ukoliko poznajete to£no ime mikroupravlja£a koji ¢eteupisati u pretraºiva£.

4. Pritisnite OK za nastavak.

Nakon ²to ste zavr²ili prethodnu fazu stvaranja novog projekta, otvorit ¢e se ureiva£programskog koda prikazan na slici 2.7.

Slika 2.7: Razvojno okruºenje Atmel Studio 7 - ureiva£ programskog koda

Ureiva£ programskog koda sadrºi sljede¢e elemente ozna£ene brojevima na slici 2.7:

1. tekstualni ureiva£ programskog koda,

2. projektno stablo i

3. pokaznik statusnih poruka.

U tekstualni ureiva£ koda pi²e se programski kod u programskom jeziku C3. Projektno stablosluºi za strukturiranje programskog koda u zaglavlja, dok pokaznik statusnih poruka ispisujeupozorenja i pogre²ke koje se eventualno javljaju prilikom prevoenja programskog jezika C ustrojni kod.

3Jedan dio programskog koda koji ¢emo koristiti pisan je u programskom jeziku C++ te je stoga ekstenzijadatoteke s main() funkcijom *.cpp. Programski jezik C++ u pravilu je povratno kompatibilan (engl. backward

compatibility) s programskim jezikom C.

8 Razvojno okruºenje Atmel Studio 7

Prvi projekt stvoren u razvojnom okruºenju Atmel Studio 7 imat ¢e zada¢u uklju£ivati LEDdiode spojene na port B (pinovi 4 do 7) pomo¢u tipkala spojenih na port D (pinovi 0 i 1) teport F (pinovi 6 i 7) . U ovom trenutku ne¢emo prou£avati programski kod, ve¢ samo na£in nakoji se koristi razvojno okruºenje Atmel Studio 7 za stvaranje strojnog koda. Programski kodprikazan je u nastavku.

/*

* Prvi_projekt.c

*

* Vrijeme kreiranja: 29.2.2020. 23:49:48

* Autor: Zoran Vrhovski

*/

#include <avr/io.h>

int main(void)

// postavljanje ulaznih pinova za tipkala

DDRD &= ~((1 << 0) | (1 << 1));

DDRF &= ~((1 << 6) | (1 << 7));

// uklju£enje pull up otpornika

PORTD |= (1 << 0) | (1 << 1);

PORTF |= (1 << 6) | (1 << 7);

// postavljanje izlaznih pinova za LED diode

DDRB |= (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4);

uint8_t portb = PORTB;

while (1)

portb &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4));

portb |= ((~(( PIND & (1 << 0)) >> 0) & 0x01) << 4);

portb |= ((~(( PIND & (1 << 1)) >> 1) & 0x01) << 5);

portb |= ((~(( PINF & (1 << 6)) >> 6) & 0x01) << 6);

portb |= ((~(( PINF & (1 << 7)) >> 7) & 0x01) << 7);

PORTB = portb;

Prethodni programski kod potrebno je prevesti u strojni kod. Prevoenje programskog kodamogu¢e je provesti na dva na£ina (slika 2.8):

• pritisnite tipku F7 ili

• u izborniku odaberite Build → Build Solution.

Programski kod uspje²no je preveden ako se u pokazniku statusnih poruka (slika 2.8) pojaviporuka Uspje²no prevoenje (engl. Build succeeded). Ukoliko prevoenje nije uspje²no,potrebno je korigirati programski kod sukladno pravilima programskog jezika C. Rezultatprevoenja programskog koda strojni je kod prikazan na slici 2.9.

2.2 Stvaranje projekta u razvojnom okruºenju Atmel Studio 7 9

Slika 2.8: Razvojno okruºenje Atmel Studio 7 - prevoenje programskog koda u strojni jezik

Slika 2.9: Strojni kod zapisan u datoteci Prvi projekt.hex

Datoteka sa strojnim kodom nalazi se na lokaciji C:\Mikroracunala\Prvi projekt\Prviprojekt\Debug i ima ekstenziju *.hex. Strojni kod sa slike 2.9 u heksadecimalnom je zapisu, au mikroupravlja£ se snima pomo¢u softvera za programiranje mikroupravlja£a.

10 Razvojno okruºenje Atmel Studio 7

Poglavlje 3

Snimanje i pokretanje strojnog koda na

mikroupravlja£u ATmega32U4

3.1 Razvojno okruºenje s mikroupravlja£em ATmega32U4

U prethodnom poglavlju napisali smo programski kod i preveli ga u strojni kod pomo¢urazvojnog okruºenja Atmel Studio 7. Strojni kod potrebno je snimiti na mikroupravlja£ATmega32U4 pomo¢u programatora. U sklopu laboratorijskih vjeºbi iz predmeta Mikrora£unalakoristit ¢emo razvojno okruºenje s mikroupravlja£em ATmega32U4 prikazano na slici 3.1.

TipkalaReset

tipkalo

Mikroupravljač ATmega32U4

LED diode

RGB dioda

7 segmentni

displeji

Konektor za

LCD displej

Konektor za

matričnu tipkovnicu

Relej i konektor

kontakata releja

Konektor za ultrazvučni

senzor HC-SR04

Konektor za servomotor

UART konektor (preko CP2102)

UART konektor

(direktno na ATmega32U4)

USB konektor

Konektor za ISP

programator

Rotacijski enkoder

Konektor za

napajanje

Potenciometar

Buzzer

Temperaturni

senzor LM35

Temperaturni

senzor NTC

Slika 3.1: Razvojno okruºenje s mikroupravlja£em ATmega32U4

12 Snimanje i pokretanje strojnog koda na mikroupravlja£u ATmega32U4

Na slici 3.1 prikazani su osnovni dijelovi razvojnog okruºenja s mikroupravlja£emATmega32U4:

• konektor za napajanje,

• mikroupravlja£ ATmega32U4,

• tipkala,

• LED diode i RGB dioda,

• konektori za ultrazvu£ni senzor HC-SR04 i servomotor,

• USB konektor,

• relej,

• 7 segmentni displej (numeri£ki displej),

• konektori za LCD displej i za matri£nu tipkovnicu,

• potenciometar,

• temperaturni senzori LM35 i NTC,

• Buzzer,

• RESET tipkalo,

• rotacijski enkoder,

• konektori za serijsku (UART) komunikaciju,

• konektor za ISP programiranje.

Ostali dijelovi razvojnog okruºenja sa slike 3.1 bit ¢e opisani kroz naredna poglavlja. Razvojnookruºenje moºe se napajati putem USB konektora, konektora za napajanje i ISP programatora.

Mikroupravlja£ ATmega32U4 jedan je od £esto kori²tenih mikroupravlja£a op¢e namjene(nalazi se na razvojnom okruºenju Arduino Leonardo). Karakteristike su ATmega32U4mikroupravlja£a sljede¢e [1]:

• visoke performanse,

• mala snaga,

• AVR R©porodica, 8-bitni mikroupravlja£,

• RISC arhitektura:

135 instrukcija,

32 registra op¢e namjene,

do 16 MIPS (16 milijuna instrukcija u jednoj sekundi) na 16 MHz.

• 32 kB (engl. In-System Self-programmable Flash) programske memorije,

• 1 kB EEPROM memorije,

• 2.5 kB SRAM memorije,

3.1 Razvojno okruºenje s mikroupravlja£em ATmega32U4 13

• Ciklus pisanja/brisanja: Flash 10 000 puta/EEPROM 100 000 puta,

• JTAG su£elje za ispravljanje pogre²aka u programu,

• jedan 8-bitni tajmer (Timer)/broja£ (Counter) s djeliteljima frekvencije,

• dva 16-bitna tajmera (Timers)/broja£a (Counters) s djeliteljima frekvencije,

• jedan 10-bitni tajmer (High-Speed Timer)/broja£a (High-Speed Counter) visoke brzine,

• 12 ADC pretvornika (rezolucija 10 bitova),

• dva Master/Slave SPI (engl. Serial Peripheral Interface) su£elja za komunikaciju,

• jedno 2-wire Serial Interface su£elje za komunikaciju (isto ²to i I2C komunikacija),

• programirljivi USART (engl. Universal Synchronous and Asynchronous Serial Receiverand Transmitter),

• programirljivi tajmer za nadzor ispravnog rada (engl. Watchdog Timer),

• Power-on Reset,

• programirljivi detektor pada napona napajanja (engl. Brown Out Detection),

• unutarnji i vanjski izvor prekida (engl. Interrupts),

• ²est Sleep modova rada,

• interni oscilator 8 MHz (kalibrirani),

• 26 ulaznih/izlaznih pinova koji su smje²teni na pet portova,

• I/O podnoºje: 44-lead TQFP Package/QFN Package,

• nazivni napon: 2.7 - 5.5 V

• radni takt: 0 - 16 MHz.

Raspored pinova na mikroupravlja£u ATmega32U4 prikazan je na slici 3.2. Mikroupravlja£ima 26 ulaznih/izlaznih pinova koji su smje²teni na pet portova:

• PORTB (pinovi: PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7),

• PORTC (pinovi: PC6, PC7),

• PORTD (pinovi: PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7),

• PORTE (pinovi: PE2, PE6) i

• PORTF (pinovi: PF0, PF1, PF4, PF5, PF6, PF7).

Ve¢ina je digitalnih pinova vi²enamjenska, ²to omogu¢uje veliku eksibilnost pri razvijanjuelektroni£kog ureaja. Tipkala su spojena na port D i F, a LED diode spojene su na portB mikroupravlja£a i koristit ¢e se za testiranje digitalnih ulaza i izlaza. Serijska komunikacijakoristit ¢e se za komunikaciju mikroupravlja£a s ra£unalom, ²to nam omogu¢uje upravljanje inadzor sustava putem ra£unala. Pinovi mikroupravlja£a koji se koriste za serijsku komunikacijujesu RXD1 (PD2) i TXD1 (PD3) (slika 3.2). Vanjski prekidi (engl. External Interrupts) okidajuse pomo¢u pinova INT0 (PD0), INT1 (PD1), INT2 (PD2), INT3 (PD3) i INT6 (PE6) (slika3.2). Osoba koja razvija elektroni£ki ureaj mora voditi ra£una da, ukoliko koristi serijsku

14 Snimanje i pokretanje strojnog koda na mikroupravlja£u ATmega32U4

komunikaciju, ne¢e imati dostupne vanjske prekide INT2 i INT3 jer serijska komunikacija i vanjskiprekidi INT2 i INT3 dijele iste digitalne pinove (PD2, PD3). Analognih ulaza na mikroupravlja£uATmega32U4 ima ukupno 14: ADC0 (PF0), ADC1 (PF1), ADC4 (PF4), ADC5 (PF5), ADC6(PF6), ADC7 (PF7), ADC8 (PD4), ADC9 (PD6), ADC10 (PD7), ADC11 (PB4), ADC12 (PB5)i ADC13 (PB6) (slika 3.2).

Slika 3.2: Raspored pinova na mikroupravlja£u ATmega32U4 [1]

Za programiranje mikroupravlja£a ATmega32U4 koristit ¢emo programator USBasp prikazanna slici 3.3. Prednosti ovog programatora naspram ostalih jesu kompatibilnost s USB su£eljem,niska cijena i besplatni softver za programiranje. Programator je potrebno spojiti na konektor zaISP1 programator (slika 3.1). Shema spajanja programatora s mikroupravlja£em ATmega32U4prikazana je na slici 3.4. Za programiranje mikroupravlja£a potrebno je napajanje iznosa 5 Vkoje se moºe dovesti ili preko programatora ili preko vanjskog izvora. Programiranje se izvodiputem SPI2 protokola £ije se su£elje sastoji od pinova SS (PB0), SCLK (PB1), MOSI (PB2)i MISO (PB3). Pri programiranju mikroupravlja£a programator koristi i RESET pin. Vanjskioscilator prikazan na shemi 3.4 oznakom Q1 kvarcni je oscilator frekvencije 16 MHz.

1Oznaka ISP dolazi od In-System Programming, ²to ukazuje na mogu¢nost programiranja mikroupravlja£a kojise nalazi na razvojnom okruºenju. Nekada su se mikroupravlja£i programirali na samom programatoru, ²to jezahtijevalo neprestano premje²tanje mikroupravlja£a s programatora na razvojno okruºenje i obratno.

2Serial Peripheral Interface.

3.2 Programiranje mikroupravlja£a ATmega32U4 15

Slika 3.3: Programator USBasp

+5V

GND

100n

10k

+5V

1uF

22p

22p

GND

+5V

GND

+5V

+5V

UGND

+5V

GND

100n

Konektor za programiranje

SPI konektor

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2

C12

C13

134 2

S5

21

Q1

123456

C14

RESET

MISO

MISO

MOSI

MOSI

RXTX

AREF

D-D+

VUSB

SCK

SCK

PD6

PC7

PE6

PD7

PC6

PF1PF0

SS

SS

NC

MOSI

RESET

SCK

MISOGND

Slika 3.4: Shema spajanja programatora s mikroupravlja£em ATmega32U4

3.2 Programiranje mikroupravlja£a ATmega32U4

Kao programsku podr²ku programatoru USBasp koristit ¢emo softver eXtreme Burner AVR. Najnoviju verziju softvera eXtreme Burner AVR moºete prona¢i na stranicihttps://extreme-burner-avr.software.informer.com/download/.

Softver eXtreme Burner AVR moºemo pokrenuti dvostrukim klikom na ikonu sa slike 3.5.Nakon pokretanja softvera eXtreme Burner AVR pojavit ¢e se prozor sa slike 3.6. Strojni kodkoji smo stvorili pomo¢u razvojnog programskog okruºenja Atmel Studio 7 potrebno je u£itatiu softver eXtreme Burner AVR. To moºemo u£initi na dva na£ina:

1. na po£etnoj stranici softvera eXtreme Burner AVR odaberite Open (slika 3.7) ili

2. u izborniku softvera eXtreme Burner AVR odaberite File → Open Flash (slika 3.8).

16 Snimanje i pokretanje strojnog koda na mikroupravlja£u ATmega32U4

Slika 3.5: Softver eXtreme Burner AVR - ikona

Slika 3.6: Softver eXtreme Burner AVR - po£etni prozor

Slika 3.7: Softver eXtreme Burner AVR - u£itavanje strojnog koda (1)

Slika 3.8: Softver eXtreme Burner AVR - u£itavanje strojnog koda (2)

3.2 Programiranje mikroupravlja£a ATmega32U4 17

Prozor za u£itavanje strojnog koda prikazan je na slici 3.9. Na slici 3.9 moºe se primijetitida je jedina ekstenzija datoteke koja se moºe u£itati u softver eXtreme Burner AVR *.hex.Strojni kod stvoren razvojnim programskim okruºenjem Atmel Studio 7 nalazi se na lokacijiC:\Mikroracunala\Prvi projekt\Prvi projekt\Debug. Na ovoj lokaciji potrebno je odabratidatoteku Prvi projekt.hex (slika 3.9).

Slika 3.9: Softver eXtreme Burner AVR - prozor za u£itavanje strojnog koda

Strojni kod u£itan u softver eXtreme Burner AVR prikazan je na slici 3.10 i istovjetan jestrojnom kodu sa slike 2.9. Strojni kod nalazi se na kartici Flash u softveru eXtreme Burner AVR. Osim kartice Flash, softver eXtreme Burner AVR ima kartice EEPROM3 i FuseBits/Settings.

Slika 3.10: Strojni kod u£itan u softver eXtreme Burner AVR

3Memorija koja £uva svoj sadrºaj nakon gubitka napajanja.

18 Snimanje i pokretanje strojnog koda na mikroupravlja£u ATmega32U4

Nakon u£itavanja strojnog koda u softver eXtreme Burner AVR potrebno je odabrati nakoji ¢emo mikroupravlja£ snimiti strojni kod. Za odabir mikroupravlja£a potrebno je u izbornikuChip odabrati jedan od ponuenih mikroupravlja£a porodice AVR. Mikroupravlja£ koji moramoodabrati jest ATmega32U4, no, kako se vidi na slici 3.11, on ne postoji na listi ponuenihmikroupravlja£a.

Slika 3.11: Softver eXtreme Burner AVR - odabir AVR mikroupravlja£a

Ovaj problem moºemo rije²iti dodavanjem novog mikroupravlja£a na listu. Dodavanje novogmikroupravlja£a moºe se provesti na sljede¢i na£in:

1. pomo¢u ureiva£a teksta (npr. Notepad++) potrebno je otvoriti XML datoteku Chipskoja se nalazi na lokaciji C:\Program Files\eXtreme Burner - AVR\Data4,

2. u XML datoteku Chips dodati XML programski kod koji je crveno zaokruºen na slici 3.12te

3. snimiti promjene u XML datoteci Chips i zatvoriti datoteku.

Klju£na svojstva u XML programskom kodu za mikroupravlja£ ATmega32U4 jesu:

• <NAME>ATmega32U4</NAME> - ime dodanog mikroupravlja£a,

• <FLASH>32768</FLASH> - koli£ina programske memorije (32 kB = 32768 B),

• <EEPROM>1024</EEPROM> - koli£ina EEPROM memorije (1 kB = 1024 B),

• <SIG>0x0087951E</SIG> - jedinstveni potpis (engl. Signature) mikroupravlja£aATmega32U4 koji se moºe prona¢i u njegovoj tehni£koj dokumentaciji:

1. 0x1E ozna£ava proizvoa£a mikroupravlja£a

2. 0x95 ozna£ava 32 kB Flash memorije

3. 0x87 ozna£ava mikroupravlja£ ATmega32U4

• <PAGE>64</PAGE> - programska memorija podijeljena je na stranice (engl. PAGE) odkojih svaka ima 64 memorijskih rije£i (1 memorijska rije£ = 16 bitova = 2 B).

4Lokacija XML datoteke Chips moºe biti druga£ija ukoliko ste softver eXtreme Burner AVR instalirali nanekom drugom mjestu.

3.2 Programiranje mikroupravlja£a ATmega32U4 19

Ostala svojstva XML koda ozna£avaju koliko bajtova memorije zauzimaju Fuse bitovi, postojeli Lock bitovi i postoji li polje za kalibraciju unutarnjeg oscilatora.

Slika 3.12: Sadrºaj XML datoteke Chips

Nakon provedene procedure dodavanja novoga mikroupravlja£a na listu, mikroupravlja£ATmega32U4 pojavit ¢e se na popisu mikroupravlja£a (slika 3.13) te ga je potrebno odabrati.

Slika 3.13: Softver eXtreme Burner AVR - odabir AVR mikroupravlja£a ATmega32U4

Ako prvi put programiramo mikroupravlja£ ili mu se mijenjaju osnovne postavke, potrebnoje namjestiti tzv. Fuse bitove. Ti bitovi odreuju rad mikroupravlja£a. U softveru eXtremeBurner AVR odaberite karticu Fuse Bits/Settings prikazanu na slici 3.14.

20 Snimanje i pokretanje strojnog koda na mikroupravlja£u ATmega32U4

Slika 3.14: Softver eXtreme Burner AVR - pode²avanje Fuse bitova

Fuse bitovima mogu¢e je mijenjati frekvenciju rada mikroupravlja£a, izvor radnog takta kojimoºe biti unutanji i vanjski, na£in programiranja i drugo. Tvorni£ke su postavke mikroupravlja£aATmega32U4 sljede¢e:

• izvor radnog takta vanjski je oscilator frekvencije ve¢e od 8 MHz i sa Start-up vremenom258 CK + 65 ms,

• radni takt interno se dijeli s 8,

• omogu¢eno je programiranje putem SPI su£elja,

• omogu¢eno je ispravljanje pogre²aka na mikroupravlja£u (engl. JTAG Interface Enabled),

• Brown-out razina pode²ena je na 2.6 V,

• Boot Flash veli£ine je 2048 memorijskih rije£i (4 kB),

• omogu¢en je Hardware Boot.

Ovim postavkama odgovaraju sljede¢e vrijednosti Fuse bitova u heksadecimalnom zapisu:

• niºi Fuse bitovi (engl. Low Fuse) jesu 0x5E,

• vi²i Fuse bitovi (engl. High Fuse) jesu 0x99,

• pro²ireni Fuse bitovi (engl. Extended Fuse) jesu 0xF3.

Za prora£un Fuse bitova preporu£uje se kalkulator Fuse bitova koji se nalazi na straniciwww.engbedded.com/fusecalc/. Za potrebe vjeºbi u nastavku ovog udºbenika podesit ¢emosljede¢e vrijednosti Fuse bitova:

3.2 Programiranje mikroupravlja£a ATmega32U4 21

• niºi Fuse bitovi (engl. Low Fuse) jesu 0xFF,

• vi²i Fuse bitovi (engl. High Fuse) jesu 0xD9,

• pro²ireni Fuse bitovi (engl. Extended Fuse) jesu 0xFB.

Navedeni Fuse bitovi (slika 3.14) odgovaraju sljede¢im postavkama mikroupravlja£aATmega32U4:

• izvor radnog takta vanjski je oscilator frekvencije ve¢e od 8 MHz i sa Start-up vremenom16k CK + 65 ms,

• omogu¢eno je programiranje putem SPI su£elja,

• Brown-out razina pode²ena je na 2.6 V,

• Boot Flash veli£ine je 2048 memorijskih rije£i (4 kB),

Nakon ²to prora£unamo Fuse bitove potrebno ih je snimiti na mikroupravlja£. To ¢emou£initi tako da na kartici Fuse Bits/Settings slijedimo korake od 1 do 7 (slika 3.14):

1. u polje Low Fuse upi²ite FF,

2. u polje High Fuse upi²ite D9

3. u polje Extended Fuse upi²ite FB,

4. kva£icom ozna£ite Write u polju Low Fuse,

5. kva£icom ozna£ite Write u polju High Fuse,

6. kva£icom ozna£ite Write u polju Extended Fuse,

7. odaberite Write.

Osim snimanja Fuse bitova, oni se mogu i pro£itati iz mikroupravlja£a ukoliko na kartici FuseBits/Settings odaberete dugme Read All.

U kona£nici, nakon namje²tanja postavki mikroupravlja£a, potrebno je strojni kod snimitiu programsku memoriju mikroupravlja£a tako da u softveru eXtreme Burner AVR odabereteWrite → Flash. Postupak je prikazan na slici 3.15.

Slika 3.15: Softver eXtreme Burner AVR - snimanje strojnog koda u programsku memorijumikroupravlja£a ATmega32U4

Ukoliko je programiranje mikroupravlja£a uspje²no zavr²ilo, pojavit ¢e se prozor na slici 3.18.Na slici 3.18 moºemo vidjeti da proces programiranja mikroupravlja£a ima nekoliko koraka:

1. detektiranje mikroupravlja£a,

2. brisanje programske memorije mikroupravlja£a,

22 Snimanje i pokretanje strojnog koda na mikroupravlja£u ATmega32U4

3. snimanje strojnog koda u programsku memoriju mikroupravlja£a,

4. verikacija strojnog koda u mikroupravlja£u.

Slika 3.16: Softver eXtreme Burner AVR - proces programiranja mikroupravlja£a

Nakon programiranja mikroupravlja£a potrebno je provjeriti ispravnost rada programskogkoda koji smo napisali na razvojnom okruºenju sa slike 3.1. Ako se razvojno okruºenje nepona²a u skladu s na²im naumom, potrebno je ispraviti gre²ke u programskom kodu, ponovnoprevesti programski kod u strojni kod te snimiti novi strojni kod na mikroupravlja£. Ovaj seciklus ponavlja dokle god ne postignemo ispravan rad razvojnog okruºenja u skladu s na²imnaumom.

Strojni kod iz mikroupravlja£a mogu¢e je pro£itati tako da u softveru eXtreme Burner AVRodaberete Read → Flash (slika 3.17). Strojni kod nije £itljiv i na temelju njega ne¢ete znati ²toi kako radi mikroupravlja£. Strojni se kod ne moºe pretvoriti u programski kod koji je £itljivprogrameru mikroupravlja£a.

Slika 3.17: Softver eXtreme Burner AVR - £itanje programske memorije mikroupravlja£a

Princip programiranja mikroupravlja£a isti je i za ostale mikroupravlja£e iz porodice AVRkoji su na popisu mikroupravlja£a u softveru eXtreme Burner AVR te onih koji se mogu dodati

3.2 Programiranje mikroupravlja£a ATmega32U4 23

na popis, a podrºavaju ISP programiranje. Prilikom u£itavanja strojnog koda u softver eXtremeBurner AVR pazite da nijedna datoteka na putanji prema *.hex datoteci nema dijakriti£kihznakova. U suprotnom softver eXtreme Burner AVR ne¢e u£itati strojni kod.

Programiranje mikroupravlja£a porodice AVR mogu¢e je i neposredno iz razvojnog okruºenjaAtmel Studio 7. U tu svrhu potrebno je imati programator AVRISP mkII proizvoa£aMicrochip.Taj programator puno je skuplji od programatora USBasp, ali zato omogu¢uje razvoj aplikacijeu jednom softveru i brºe ispravljanje gre²aka. No, postoji rje²enje u kojem je mogu¢e dodativanjski ureaj za programiranje u razvojno okruºenje Atmel Studio 7. Na slici 3.18 je prikazanpostupak dodavanja USBasp programatora za mikroupravlja£ ATmega32U4 kao vanjskog ureajau razvojno okruºenje Atmel Studio 7.

Slika 3.18: Programiranje mikroupravlja£a iz razvojnog okruºenja Atmel Studio 7 -parametriranje programatora USBasp

Postupak dodavanja USBasp programatora za mikroupravlja£ ATmega32U4 moºe se provestiu osam koraka:

1. u razvojnom okruºenju Atmel Studio 7 odaberite izbornik Tools,

2. u izborniku Tools odaberite External Tools...,

3. u novootvorenom prozoru pritisnite gumb Add,

4. u polju Title upi²ite: USBasp ATmega32U4,

5. u polje Command upi²ite: C:\Program Files (x86)\Atmel\avrdude\avrdude.exe5

6. u polje Arguments upi²ite:avrdude -c usbasp -p atmega32u4 -U ash:w:$(ProjectDir)Debug\$(TargetName).hex:i

7. ozna£ite opciju Use Output window,

8. zavr²ite parametriranje pritiskom na gumb OK.5Potrebno je skinuti Avrdude sa stranice https://www.nongnu.org/avrdude/.

24 Snimanje i pokretanje strojnog koda na mikroupravlja£u ATmega32U4

Nakon provedenog postupka, prevedeni programski kod za mikroupravlja£ ATmega32U4moºete snimiti na razvojno okruºenje sa slike 3.1 odabirom Tools -> USBasp ATmega32U4 (slika3.19 - koraci 1 i 2). Uspje²nost programiranja moºete pratiti u Output prozoru (slika 3.19 - korak3).

Slika 3.19: Programiranje mikroupravlja£a iz razvojnog okruºenja Atmel Studio 7 pomo¢uprogramatora USBasp

Fuse bitove i dalje je potrebno snimiti pomo¢u softvera eXtreme Burner AVR, no kadaih jednom podesite daljnje programiranje moºete provoditi pomo¢u razvojnog okruºenja AtmelStudio 7, ²to ¢e Vam omogu¢iti rad u samo jednom softveru.

Strojni kod koji se nalazi u programskoj memoriji mikroupravlja£a izvodi se onog trenutkakada na mikroupravlja£ dovedemo napajanje i ako na pin RESET dovedemo visoko stanje(5 V). Ako mikroupravlja£ izgubi napajanje ili na pin RESET dovedemo nisko stanje (0 V),mikroupravlja£ se zaustavlja, a ponovnim se pokretanjem mikroupravlja£a strojni kod izvodiispo£etka.

Naj£e²¢a gre²ka koju rade po£etnici u programiranju mikroupravlja£a jest izostavljanje visokerazine na pinu RESET mikroupravlja£a pa iz tog razloga mikroupravlja£ ne¢e raditi. Na slici3.4 moºemo vidjeti da je visoko stanje na pin RESET dovedeno preko priteznog (engl. pull-up)otpornika iznosa otpora 10 kΩ, ²to zna£i da je dovoljno na mikroupravlja£ dovesti samo napajanjekako bi on izvodio strojni kod.

Poglavlje 4

Digitalni izlazi i ulazi

Mikroupravlja£ ATmega32U4 ima 26 digitalnih pinova koji se mogu kongurirati kao izlaznipinovi ili kao ulazni pinovi. Smjer djelovanja digitalnog pina moºe se mijenjati tijekom radamikroupravlja£a. Na primjer, digitalni pin moºe biti izlazni pin te tijekom rada mikroupravlja£apostati ulazni pin i obratno. Digitalni pinovi mikroupravlja£a ATmega32U4 rasporeeni su u petgrupa koje nazivamo portovima. Mikroupravlja£ ATmega32U4 ima sljede¢e portove s oznakamadigitalnih pinova:

• PORTB (oznake digitalnih pinova: PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7),

• PORTC (oznake digitalnih pinova: PC6, PC7),

• PORTD (oznake digitalnih pinova: PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7),

• PORTE (oznake digitalnih pinova: PE2, PE6),

• PORTF (oznake digitalnih pinova: PF0, PF1, PF4, PF5, PF6, PF7).

Svaki digitalni pin ima vi²estruku namjenu, pa se npr. pinovi PD2 i PD3 koriste za serijskukomunikaciju. Na£in rada digitalnog pina na nekom portu odreuju registri za konguraciju:

• DDRx, (x = B, C, D, E, F), (engl. Data Direction Register) - registar smjera podataka,

• PORTx, (x = B, C, D, E, F) - podatkovni registar i

• PINx, (x = B, C, D, E, F) - registar ulaznih pinova.

Svi navedeni registri ²irine su 8 bitova. Pozicija bita i (i = 0, 1, ..., 7) u registru odreujekonguraciju pina na poziciji i. Ako mijenjamo, primjerice, vrijednost bita u registru DDRD napoziciji bita i = 5, tada se promijenjena vrijednost bita odnosi na konguraciju pina PD5.

Vrijednost bita na poziciji i (i = 0, 1, ..., 7) u registru DDRx odreuje ho¢e li pin na pozicijii biti ulazni ili izlazni prema pravilima:

• ako je bit na poziciji i u registru DDRx jednak 0, tada ¢e pin na poziciji i biti kongurirankao ulazni pin,

• ako je bit na poziciji i u registru DDRx jednak 1, tada ¢e pin na poziciji i biti kongurirankao izlazni pin.

Na primjer, ako je DDRB = 0xF0 = 0b111100001, tada su gornja £etiri pina na portu B izlaznipinovi, a donja £etiri pina na portu B ulazni pinovi (tablica 4.1).

10x u programskom jeziku C/C++ ozna£ava heksadecimalni zapis broja, a 0b binarni zapis broja.

26 Digitalni izlazi i ulazi

Tablica 4.1: Konguracija pinova na portu B sa sadrºajem registra DDRB = 0xF0 = 0b1111000

DDRB registar bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0

Sadrºaj DDRB registra 1 1 1 1 0 0 0 0

Port B PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0

Konguracija izlaz izlaz izlaz izlaz ulaz ulaz ulaz ulaz

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4

Ako je bit na poziciji i u registru DDRx jednak 1, tada ¢e pin na poziciji i biti kongurirankao izlazni pin. Pin koji je konguriran kao izlaz moºe biti u dvama stanjima:

• nisko stanje ili stanje logi£ke nule - stanje koje odgovara naponu 0 V,

• visoko stanje ili stanje logi£ke jedinice - stanje koje odgovara naponu 5 V.

Nisko ili visoko stanje na izlaznom pinu odreujemo registrom PORTx prema pravilima:

• ako je bit na poziciji i u registru PORTx jednak 0, tada ¢e izlazni pin na poziciji i biti uniskom stanju (stanju logi£ke nule),

• ako je bit na poziciji i u registru PORTx jednak 1, tada ¢e izlazni pin na poziciji i biti uvisokom stanju (stanju logi£ke jedinice).

4.1.1 Vjeºbe - digitalni izlazi mikroupravlja£a ATmega32U4

Digitalne izlaze mikroupravlja£a ATmega32U4 testirat ¢emo pomo¢u £etiriju LED diodai jedne zujalice. Sheme spajanja LED dioda i zujalice na digitalne izlaze mikroupravlja£aATmega32U4 prikazane su na slikama 4.1 i 4.2.

150150150150

LED

+5V

GND

100n

10k

+5V

150 150 150 150

1uF

22p

22p

GND

GND

+5V

+5V

GND

UGND

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

R2 R3 R4 R5

C2

LED1 LED2 LED3

C12

C13

134 2

S5

21

Q1

LED4

1 2 3

JP4

R66R67R68R69

G BR

RESET

MISOMOSI

RXTX

AREF

D-D+

VUSB

SCK

PD6

PC7

PE6

PD7

PC6

PF1PF0

SS

Slika 4.1: Shema spajanja LED dioda na mikroupravlja£ ATmega32U4

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4 27

+5V

GND

100n

10k

+5V

1uF

10k

4k7

+5V

GND

+5V

GND

22p

22p

GND

GND

GND

+5V

330

+5V

UGND

+5V

LM35CAZ

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2

AE

SPOT1

12

NTC

R17

C12

C13

+ -

BUZZ

134 2

S5

R56

21

Q1

1 2 3

JP1

1 2 3

JP2

+VS1

GND3

VOUT 2

U1

RESET

MISOMOSI

RXTX

AREF

D-D+

VUSB

SCK

PD6

PC7

PE6

PD7

PC6

PF5

PF5

PF4

PF4

PF1PF0

SS

Slika 4.2: Shema spajanja zujalice (engl. buzzer) na mikroupravlja£ ATmega32U4

LED diode i zujalicu mogu¢e je spojiti na bilo koji digitalni pin. Sheme sa slika 4.1 i 4.2usklaene su s razvojnim okruºenjem prikazanim na slici 3.1. Pri spajanju LED dioda i zujalicena digitalne izlaze kori²teni su otpornici serijski spojeni s LED diodama i zujalicom. Razlog tomejest strujna za²tita digitalnog pina. Struja digitalnog pina ne smije biti ve¢a od 40 mA prema[1]. Vrijednost otpora otpornika iznosi 300 Ω za LED diode i 330 Ω za zujalicu.

Na digitalne izlaze moºemo spojiti bipolarne i unipolarne tranzistore, releje s maksimalnomupravlja£kom strujom od 40 mA, opti£ke spreºnike (engl. optocoupler), dijke, trijke i ostaledigitalne aktuatore, uz uvjet da se ne prema²i maksimalna struja digitalnog pina.

Za detalje oko konguracije digitalnih izlaza pogledajte tablicu 10-1 u literaturi [1] na stranici69. Programsko razvojno okruºenje Atmel Studio 7 ima denirana imena registara DDRxi PORTx (x = B, C, D, E, F) te se konguracija pinova svodi na dodjeljivanje vrijednostiu denirana imena registara. Na primjer, ako ºelimo da svi pinovi porta D budu izlaznipinovi u programskom razvojnom okruºenju Atmel Studio 7, napisat ¢emo DDRD = 0xFF; uheksadecimalnom zapisu ili DDRD = 0b11111111; u binarnom zapisu. Op¢enito vrijedi da suimena registara koja se koriste u literaturi [1] jednaka imenima deniranim u programskomrazvojnom okruºenju Atmel Studio 7.

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku Digital Output.zip. Naradnoj povr²ini stvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢ipritom dijakriti£ke znakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢etestvoriti zvat ¢e se Ivica Ivic. Datoteku Digital Output.zip raspakirajte u novostvorenudatoteku na radnoj povr²ini. Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini tedvostrukim klikom pokrenite VUB mikroracunala.atsln u datoteci \\Digital Output\vjezbe.U otvorenom projektu nalaze se sve naredne vjeºbe koje ¢emo obraditi u poglavlju Digitalniizlazi mikroupravlja£a ATmega32U4. Vjeºbe ¢emo pisati u datoteke s ekstenzijom *.cpp.Budu¢i da ¢e svaka datoteka u koju ¢emo pisati vjeºbe sadrºavati funkciju main()2, za svakuvjeºbu potrebno je napraviti sljede¢e korake (slika 4.3):

1. u projektnom stablu odaberite datoteku s ekstenzijom *.cpp (npr. vjezba411.cpp) i nanjoj pritisnite desni gumb mi²a te odaberite Properties,

2U programskom jeziku C/C++ poznato je da program moºe imati samo jednu funkciju main().

28 Digitalni izlazi i ulazi

2. ispod prozora projektnog stabla otvorit ¢e se prozor sa svojstvima datoteke koju steodabrali. Za datoteku koju ºelite prevesti u strojni kod potrebno je u polju Build Actionodabrati opciju Compile, a za sve ostale datoteke u projektnom stablu koje sadrºe funkcijumain() u polju Build Action odabrati opciju None.

Na ovaj na£in osigurali ste da se samo jedna vjeºba prevodi u strojni kod. Ukoliko je navi²e vjeºbi u polju Build Action odabrana opcija Compile, prevoditelj ¢e javiti gre²ku da uprogramskom kodu postoji vi²estruka denicija funkcije main(), ²to je prema pravilimaprogramskog jezika C/C++ nedopustivo.

Ovaj postupak obja²njen je samo na ovom mjestu i dalje se vi²e ne¢e spominjati te ¢e se priprelasku s vjeºbe na vjeºbu samo napomenuti da se omogu¢i ili onemogu¢i prevoenje vjeºbe.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koja moºete koristiti za provjeru ispravnostiprogramskih zadataka.

Slika 4.3: Odabir datoteke koja ¢e se prevoditi u strojni kod

Vjeºba 4.1.1

Napravite program koji ¢e uklju£iti plavu LED diodu na razvojnom okruºenju smikroupravlja£em ATmega32U4. Shema spajanja plave LED diode na digitalni izlaz PB7mikroupravlja£a ATmega32U4 prikazana je na slici 4.1.

U projektnom stablu otvorite datoteku vjezba411.cpp. Omogu¢ite samo prevoenjedatoteke vjezba411.cpp. Po£etni sadrºaj datoteke vjezba411.cpp prikazan je programskimkodom 4.1. Objasnimo sada nepoznate linije programskog koda 4.1:

• #include "AVR VUB/avrvub.h" - zaglavlje avrvub.h s deniranim makronaredbama za

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4 29

konguraciju mikroupravlja£a. Zaglavlje avrvub.h napisano je od strane korisnika te se uprogramski kod uklju£uje naredbom #include "".,

• #include <avr/io.h> - zaglavlje io.h s deniranim makronaredbama i funkcijama zamanipulaciju s digitalnim ulazima i izlazima. Ovo zaglavlje u obzir uzima mikroupravlja£ zakoji je stvoren projekt u programskom razvojnom okruºenju Atmel Studio 7. Zaglavlje io.hrazvijeno je u tvrtki Microchip te se u programski kod uklju£uje naredbom #include <>.

• void inicijalizacija() - inicijalizacijska funkcija koju programeri mikroupravlja£a£esto koriste za deniranje i objedinjavanje po£etnih postavki mikroupravlja£a. Nazivinicijalizacijske funkcije proizvoljan je.

Programski kod 4.1: Po£etni sadrºaj datoteke vjezba411.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

void inicijalizacija ()

int main(void)

inicijalizacija ();

return 0;

Na² je zadatak napisati tijelo funkcije inicijalizacija() kako bi se uklju£ila plava LEDdioda spojena na digitalni pin PB7. LED dioda elektroni£ka je naprava kojoj je potreban dovoljannapon kako bi kroz sebe provela struju i pri tome emitirala svjetlost. Iz tog razloga pin na kojije spojena dioda mora se kongurirati kao izlazni pin. Prema tome, u registar DDRB potrebnoje na mjestu bita 7 upisati 1, a na sva ostala mjesta 0. Vrijednost konstante koju je potrebnoupisati u registar DDRB jest 0b1000000 binarno ili 0x80 heksadecimalno. e²¢e ¢emo koristitiheksadecimalni zapis, no £itatelju prepu²tam da sam odlu£i koji mu je pristup prihvatljiviji.Kada je digitalni pin PB7 deniran kao izlaz, u registar PORTB na mjestu bita 7 potrebno jeupisati 1 kako bi se taj pin postavio u visoko stanje te kako bi se na taj na£in uklju£ila plavaLED dioda. Prema tome, sadrºaj registra PORTB bit ¢e 0x80.

U tijelo funkcije inicijalizacija() upi²ite gore navedene konstante.

Programski kod 4.2: Funkcija inicijalizacije mikroupravlja£a - prvi na£in

void inicijalizacija ()

DDRB = 0b10000000;

PORTB = 0x80;

Tijelo funkcije inicijalizacija() mora odgovarati programskom kodu 4.2. Sada jedatoteku vjezba411.cpp potrebno prevesti u strojni kod sukladno uputama iz poglavljaRazvojno okruºenje Atmel Studio 7 . Strojni kod pomo¢u softvera eXtreme Burner AVRsnimite na mikroupravlja£ ATmega32U4 prema uputama iz poglavlja Snimanje i pokretanjestrojnog koda na mikroupravlja£u ATmega32U4. Testirajte program na razvojnom okruºenjus mikroupravlja£em ATmega32U4.

Inicijalizacija 4.2 samo je jedan od na£ina inicijalizacije mikroupravlja£a i koristi se akosu poznate funkcije ostalih pinova ili ako se ostali pinovi ne koriste. U praksi se £e²¢e javlja

30 Digitalni izlazi i ulazi

problem u kojem je potrebno ciljani pin postaviti kao izlazni, a da se konguracija ostalih pinovane mijenja. U tu svrhu potrebno je koristiti bitovne operatore i operator posmaka (programskikod 4.3).

Programski kod 4.3: Funkcija inicijalizacije mikroupravlja£a - drugi na£in

void inicijalizacija ()

DDRB |= (1 << PB7);

PORTB |= (1 << PB7);

U programskom kodu 4.3 kori²tena je denirana konstanta PB7 i njezina vrijednost iznosi7, odnosno jednaka je poziciji pina na portu B. Konstante su denirane i za ostale pinove naostalim portovima i dostupne su u datoteci vjezba411.cpp putem uklju£enih zaglavlja io.hi avrvub.h. U programskom okruºenju Atmel Studio 7 iznad konstante PB7 pritisnite desnigumb mi²a te odaberite Goto Implementation. Otvorit ¢e se zaglavlje u kojem su deniranekonstante za sve portove. Odvojite vremena i progledajte ostali sadrºaj otvorenog zaglavlja.Opcija Goto Implementation vrlo je korisna i preporu£uje se njezino £esto kori²tenje za svedenirane konstante i makronaredbe. Denirane konstante i makronaredbe prepoznat ¢ete poljubi£astoj boji.

U tablici 4.2 prikazani su bitovni operator i operator posmaka kori²teni za konguriranjeizlaznog pina. Broj 1 posmi£e se ulijevo za 7 mjesta naredbom 1 << PB7. Na taj smo na£inbroj 1 pozicionirali upravo ispod bita broj 7. Pretpostavimo da su stanja bitova registra DDRBnepoznata i ta stanja ozna£it ¢emo s x. Ako ºelimo da pin PB7 bude izlazni pin, tada namjestu bita broj 7 u registru DDRB moramo postaviti 1. To ¢emo ostvariti tako da koristimoILI operator. Stanje registra DDRB podvrgnemo bitovnom ILI operatoru s konstantom koja jedobivena naredbom 1 << PB7 te rezultat spremimo u registar DDRB. Na taj smo na£in samociljani sedmi bit postavili u 1, a ostali bitovi ostali su nepromijenjeni.

Tablica 4.2: Bitovni operator i operator posmaka kori²teni za konguriranje izlaznog pina

Pozicija bita bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0

1 0 0 0 0 0 0 0 1

1 PB7 1 0 0 0 0 0 0 0

Stanje registra DDRB x x x x x x x x

DDRB |= (1 PB7) 1 x x x x x x x

Tijelo funkcije inicijalizacija() promijenite tako da odgovara programskom kodu 4.3.Prevedite datoteku vjezba411.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4.Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Programski kod 4.4: Funkcija inicijalizacije mikroupravlja£a - tre¢i na£in

void inicijalizacija ()

output_port(DDRB ,PB7);

set_port(PORTB ,PB7 ,1);

Tre¢i je na£in inicijalizacije najjednostavniji. Autor udºbenika napisao je makronaredbe kojesu intuitivne i jednostavne za kori²tenje. Makronaredbe se nalaze u zaglavlju avrvub.h, a uprogramskom kodu 4.4 koristimo sljede¢e:

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4 31

• output_port(DDRx, pin) - makronaredba koja kao argumente prima registar DDRx ipoziciju pina kojeg ºelimo postaviti kao izlazni pin,

• set_port(PORTx, pin, stanje) - makronaredba koja kao argumente prima registarPORTx, poziciju pina koji ºelimo postaviti u visoko ili nisko stanje te ºeljeno stanje pina(0 - nisko stanje, 1 - visoko stanje).

Prednost ovog na£ina inicijalizacije ogleda se u tome ²to nije potrebno voditi brigu okonguraciji ostalih pinova jer makronaredbe same vode brigu o tome. itatelju se prepu²tana volju odabir na£ina konguracije. Preporu£ujem drugi na£in konguracije jer daje jasnu slikuo tome ²to radite.

Tijelo funkcije inicijalizacija() promijenite tako da odgovara programskom kodu 4.4.Prevedite datoteku vjezba411.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4.Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba411.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 4.1.2

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 tri putauklju£iti i isklju£iti plavu LED diodu u razmaku od jedne sekunde izmeu svakog uklju£ivanja.Shema spajanja plave LED diode na digitalni izlaz PB7 mikroupravlja£a ATmega32U4 prikazanaje na slici 4.1.

U projektnom stablu otvorite datoteku vjezba412.cpp. Omogu¢ite samo prevoenjedatoteke vjezba412.cpp. Po£etni sadrºaj datoteke vjezba412.cpp prikazan je programskimkodom 4.5.

Programski kod 4.5: Po£etni sadrºaj datoteke vjezba412.cpppp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

void inicijalizacija ()

DDRB |= (1 << PB7); // pin PB7 izlazni pin

PORTB |= (1 << PB7); // pin PB7 po£etno u visokom stanju

int main(void)

inicijalizacija (); // inicijalizacija mikroupravlja£a

return 0;

U vjeºbi je zadano da se plava LED dioda mora uklju£iti i isklju£iti ukupno tri puta i to urazmaku od jedne sekunde. Postavlja se pitanje kako je uop¢e mogu¢e da se LED dioda uklju£ujei isklju£uje u razmaku od jedne sekunde. U tu svrhu potrebno je koristiti funkcije za ka²njenje.U programski kod 4.5 upi²ite naredbu #include <util/delay.h> kako bi omogu¢ili kori²tenjefunkcija za ka²njenje. U zaglavlju delay.h nalaze se sljede¢e korisne funkcije:

• _delay_ms(double) - funkcija koja kao argument prima realan broj dvostruke preciznostikoji predstavlja ka²njenje u ms,

• _delay_us(double) - funkcija koja kao argument prima realan broj dvostruke preciznostikoji predstavlja ka²njenje u µs.

32 Digitalni izlazi i ulazi

Navedene funkcije doslovno zaustave rad mikroupravlja£a na zadano vrijeme, ²to u principui nije dobro jer se u tom vremenu onemogu¢uje obrada podataka s vanjskih senzora. Za sada jeovo jedino rje²enje koje ¢e nam omogu¢iti uklju£ivanje i isklju£ivanje plave LED diode u razmakuod jedne sekunde. Funkcije _delay_ms(double) i _delay_us(double) poºeljno je izbjegavati uozbiljnijim programima ili ih eventualno koristiti na ispravan na£in.

Kako bi funkcije _delay_ms(double) i _delay_us(double) mogle ostvariti vremenskoka²njenje, potrebno je napraviti ispravnu konguraciju Fuse bitova, kao ²to smo to pokazali upro²lom poglavlju. U programskom okruºenju Atmel Studio 7 frekvencija se denira konstantomF_CPU. Vaºno je znati da se konstantom F_CPU ne odabire frekvencija mikroupravlja£a, ve¢se svim bibliotekama u razvojnom okruºenju Atmel Studio 7 daje do znanja da frekvencijamikroupravlja£a iznosi F_CPU. Frekvencija vanjskog oscilatora spojenog na mikroupravlja£ iznosi16 MHz pa je i konstantu F_CPU potrebno namjestiti na 16 MHz.

U zaglavlju avrvub.h nalazi se naredba #define F_CPU 16000000ul kojom se prevoditeljuukazuje da frekvencija rada mikroupravlja£a iznosi 16 MHz. Konstantu F_CPU moºete deniratibilo gdje u programskom kodu, ali svakako prije kori²tenja funkcija za ka²njenje. Ako nedenirate konstantu F_CPU, prevoditelj pretpostavlja da frekvencija rada mikroupravlja£a iznosi1 MHz. Usklaenost frekvencija na hardverskoj i softverskoj razini lako je testirati na razvojnomokruºenju s mikroupravlja£em ATmega32U4.

Sada kada poznajemo funkcije ka²njenja, u programski kod 4.5 u funkciju main() ispodpoziva funkcije inicijalizacija(); unesite sljede¢i niz naredbi koje ¢e omogu¢iti uklju£ivanjei isklju£ivanje plave LED diode u razmaku od jedne sekunde ukupno tri puta:

• _delay_ms(1000); - funkcija koja omogu¢uje ka²njenje od 1000 ms, ²to je jedna sekunda.U inicijalizacijskoj je funkciji postavljeno da je plava LED dioda u po£etku radamikroupravlja£a uklju£ena. Prema tome, prvo je potrebno sa£ekati jednu sekundu, a zatimugasiti plavu LED diodu.

• set_port(PORTB,PB7,0); - makronaredba koja isklju£uje plavu LED diodu.

• _delay_us(1000000); - funkcija koja omogu¢uje ka²njenje od 1000000 µs, ²to je jednasekunda. Nakon ²to je plava LED dioda bila isklju£ena jednu sekundu, sada ju je potrebnouklju£iti.

• set_port(PORTB,PB7,1); - makronaredba koja uklju£uje plavu LED diodu.

• _delay_ms(1000); - funkcija koja omogu¢uje ka²njenje od 1000 ms, ²to je jedna sekunda.

• PORTB &= 0x7F; - naredba kojom isklju£ujemo plavu LED diodu pomo¢u bitovnog Ioperatora i maske 0x7F = 0b01111111.

• _delay_us(1000000); - funkcija koja omogu¢uje ka²njenje od 1000000 µs, ²to je jednasekunda.

• set_port(PORTB,PB7,1); - makronaredba koja uklju£uje plavu LED diodu.

• _delay_ms(1000); - funkcija koja omogu¢uje ka²njenje od 1000 ms, ²to je jedna sekunda.

• PORTB &= ~(1 << PB7); - naredba kojom isklju£ujemo plavu LED diodu pomo¢u bitovnogI operatora, operatora posmaka i operatora komplementa.

Prevedite datoteku vjezba412.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Za²to plava LED dioda ne izmjenjuje svoje stanje nakon naredbe PORTB &= ~(1 << PB7);?

Zatvorite datoteku vjezba412.cpp i onemogu¢ite prevoenje ove datoteke.

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4 33

Vjeºba 4.1.3

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢itibeskona£no uklju£ivanje i isklju£ivanje plave LED diode u razmaku od jedne sekunde izmeusvakog uklju£ivanja. Shema spajanja plave LED diode na digitalni izlaz PB7 mikroupravlja£aATmega32U4 prikazana je na slici 4.1.

U projektnom stablu otvorite datoteku vjezba413.cpp. Omogu¢ite samo prevoenjedatoteke vjezba413.cpp. Po£etni sadrºaj datoteke vjezba413.cpp prikazan je programskimkodom 4.6.

Programski kod 4.6: Po£etni sadrºaj datoteke vjezba413.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

#include <util/delay.h>

void inicijalizacija ()

DDRB |= (1 << PB7); // pin PB7 izlazni pin

PORTB |= (1 << PB7); // pin PB7 po£etno u visokom stanju

int main(void)

inicijalizacija (); // inicijalizacija mikroupravlja£a

return 0;

U vjeºbi je zadano da se plava LED dioda mora neprestano uklju£ivati i isklju£ivati u razmakuod jedne sekunde. Uvjet zadatka bit ¢e zadovoljen dok mikroupravlja£ ima napajanje i dok jeRESET pin u visokom stanju. Kako bismo ostvarili beskona£nu izmjenu visokog i niskog stanjana plavoj LED diodi, potrebno je koristiti beskona£nu petlju. U programskom jeziku C naraspolaganju imamo tri vrste petlji. Mi ¢emo koristiti petlju while. U programskom kodu 4.6 ufunkciju main() ispod poziva funkcije inicijalizacija(); napi²ite programski kod 4.7.

Programski kod 4.7: Beskona£na while petlja

while (1)

// ovdje pi²emo blok naredbi koje izvodi mikroupravlja£

// sve dok ima napajanje i dok je RESET pin u visokom stanju

Petlja while u programskom kodu 4.7 kao uvjet izvoenja ima broj razli£it od nule, ²to jeistinit uvjet izvoenja, pa je prema tome ova petlja beskona£na. Unutar bloka naredbi beskona£newhile petlje sada je potrebno upisati niz naredbi koje ¢e osigurati beskona£nu izmjenu stanjaplave diode svaku sekundu. U blok naredbi beskona£ne while upi²ite sljede¢e dvije naredbe:

• _delay_ms(1000); - funkcija koja omogu¢uje ka²njenje od 1000 ms, ²to je jedna sekunda,

• toggle_port(PORTB,PB7); - makronaredba koja mijenja stanje izlaznog pina, a kaoargumente prima registar PORTx u kojem treba napraviti promjenu stanja pina i pozicijupina kojem je potrebno promijeniti stanje. Ako je stanje izlaznog pina PB7 bilo visoko,nakon izvoenja makronaredbe toggle_port(PORTB,PB7); bit ¢e nisko i obratno.

U svakom se prolazu kroz blok naredbi beskona£ne while petlje prethodne dvije naredbe

34 Digitalni izlazi i ulazi

ponovno izvode. U while petlji £eka se jednu sekundu i nakon toga se stanje mijenja, ²to ¢edovesti do beskona£ne izmjene stanja plave LED diode.

Prevedite datoteku vjezba413.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Poku²ajte ubrzati izmjenu stanja plave LED diode.

Zatvorite datoteku vjezba413.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 4.1.4

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢ititzv. beskona£no tr£anje svih LED dioda svakih 100 ms i to redoslijedom crvena → ºuta→ zelena → plava → crvena → ... . Za izmjenu stanja LED diode koristite makronaredbutoggle_port. Shema spajanja LED dioda na digitalne izlaze mikroupravlja£a ATmega32U4prikazana je na slici 4.1. Crvena LED dioda spojena je na digitalni pin PB4, ºuta LED diodaspojena je na digitalni pin PB5, zelena LED dioda spojena je na digitalni pin PB6, a plava LEDdioda spojena je na digitalni pin PB7.

U projektnom stablu otvorite datoteku vjezba414.cpp. Omogu¢ite samo prevoenjedatoteke vjezba414.cpp. Po£etni sadrºaj datoteke vjezba414.cpp prikazan je programskimkodom 4.8.

Programski kod 4.8: Po£etni sadrºaj datoteke vjezba414.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

#include <util/delay.h>

void inicijalizacija ()

// PB7 , PB6 , PB5 i PB4 izlazni pinovi

DDRB |= (1 << PB7) | (1 << PB6) | (1 << PB5) | (1 << PB4);

PORTB |= (1 << PB4); // postavljanje PB4 u visoko stanje

int main(void)

inicijalizacija (); // inicijalizacija mikroupravlja£a

while (1) // beskona£na petlja

return 0;

U vjeºbi je potrebno ostvariti tr£anje LED dioda na na£in da tr£i uklju£ena LED dioda.Princip je sljede¢i:

• Uklju£ite crvenu LED diodu, a zatim isklju£ite plavu LED diodu. Pri£ekajte 100 ms.

• Uklju£ite ºutu LED diodu, a zatim isklju£ite crvenu LED diodu. Pri£ekajte 100 ms.

• Uklju£ite zelenu LED diodu, a zatim isklju£ite ºutu LED diodu. Pri£ekajte 100 ms.

• Uklju£ite plavu LED diodu, a zatim isklju£ite zelenu LED diodu. Pri£ekajte 100 ms.

• Ponovite prethodna £etiri koraka.

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4 35

Obratite paºnju na tijelo funkcije inicijalizacija() u programskom kodu 4.8. Digitalnipinovi PB7, PB6, PB5 i PB4 kongurirani su kao izlazni pinovi tako ²to je u registar DDRB namjesto bitova 7, 6, 5 i 4 upisan broj 1. U po£etnom je stanju crvena LED dioda uklju£ena(PORTB |= (1 << PB4);). U programskom kodu 4.8 u blok naredbi beskona£ne while petljeupi²ite sljede¢e naredbe:

• _delay_ms(100); - ka²njenje od 100 ms.

• toggle_port(PORTB,PB4); - promijeni stanje crvene LED diode. Prethodno je bilauklju£ena, a nakon ove naredbe bit ¢e isklju£ena.

• toggle_port(PORTB,PB5); - promijeni stanje ºute LED diode. Prethodno je bilaisklju£ena, a nakon ove naredbe bit ¢e uklju£ena.

• _delay_ms(100); - ka²njenje od 100 ms.

• toggle_port(PORTB,PB5); - promijeni stanje ºute LED diode. Prethodno je bilauklju£ena, a nakon ove naredbe bit ¢e isklju£ena.

• toggle_port(PORTB,PB6); - promijeni stanje zelene LED diode. Prethodno je bilaisklju£ena, a nakon ove naredbe bit ¢e uklju£ena.

• Poku²ajte samostalno posti¢i ka²njenje programa od 100 ms, uklju£iti zelenu LED diodu,a zatim isklju£iti ºutu LED diodu na temelju prethodnih koraka.

• _delay_ms(100); - ka²njenje od 100 ms.

• toggle_port(PORTB,PB7); - promijeni stanje plave LED diode. Prethodno je bilauklju£ena, a nakon ove naredbe bit ¢e isklju£ena.

• Poku²ajte samostalno promijeniti stanje crvene LED diode.

Prethodni blok naredbi moºe se napisati na razne na£ine. Poku²ajte umjesto makronaredbetoggle_port koristiti makronaredbu set_port.

Prevedite datoteku vjezba414.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba414.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 4.1.5

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢ititzv. beskona£no tr£anje svih LED dioda svakih 100 ms i to redoslijedom crvena → ºuta →zelena → plava → crvena → ... . Za izmjenu stanja LED diode koristite for petlju. Shemaspajanja LED dioda na digitalne izlaze mikroupravlja£a ATmega32U4 prikazana je na slici 4.1.Crvena LED dioda spojena je na digitalni pin PB4, ºuta LED dioda spojena je na digitalnipin PB5, zelena LED dioda spojena je na digitalni pin PB6, a plava LED dioda spojena je nadigitalni pin PB7.

U projektnom stablu otvorite datoteku vjezba415.cpp. Omogu¢ite samo prevoenjedatoteke vjezba415.cpp. Po£etni sadrºaj datoteke vjezba415.cpp prikazan je programskimkodom 4.9.

36 Digitalni izlazi i ulazi

Programski kod 4.9: Po£etni sadrºaj datoteke vjezba415.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

#include <util/delay.h>

void inicijalizacija ()

int main(void)

inicijalizacija (); // inicijalizacija mikroupravlja£a

while (1) // beskona£na petlja

for (int i = 4; i <= 7; i++)

_delay_ms (100);

PORTB &= ~(1 << i);

if (i != 7)

PORTB |= (1 << (i+1));

else

PORTB |= (1 << PB4);

return 0;

U vjeºbi je ponovno potrebno ostvariti tr£anje LED dioda, ali pomo¢u for petlje. Ovo jeteºa izvedba vjeºbe pa je stoga rje²enje prikazano u programskom kodu 4.9. U tijelu funkcijeinicijalizacija() u programskom kodu 4.9 kongurirajte digitalne pinove PB7, PB6, PB5 iPB4 kao izlazne tako da u registar DDRB na mjesto bitova 7, 6, 5 i 4 upi²ete 1. Konguracijuizlaznih pinova ostvarite pomo¢u makronaredbe output_port. Po£etno stanje crvene LED diodepostavite u visoko stanje pomo¢u makronaredbe set_port.

Pogledajmo sada blok naredbi while petlje u programskom kodu 4.9. U bloku naredbiwhile petlje nalazi se for petlja koja se izvodi ukupno £etiri puta. Broja£ for petlje ipoprima vrijednosti 4, 5, 6 i 7. Primijetite da su to pozicije digitalnih pinova PB4, PB5, PB6i PB7. Unutar for petlje nalazi se ka²njenje od 100 ms. Naredbom PORTB &= ~(1<< i);isklju£uje se prethodno uklju£ena LED dioda. Uvjetnim if blokom provjeravamo je li broja£for petlje i razli£it od 7. Ako je i razli£it od 7, uklju£ujemo sljede¢u LED diodu naredbomPORTB |= (1 << (i+1));. Onog trenutka kada broja£ for petlje i poprimi vrijednost 7 uklju£ujese crvena LED dioda naredbom PORTB |= (1 << PB4); kao po£etno stanje za sljede¢a £etiriprolaza kroz for petlju.

Prevedite datoteku vjezba415.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba415.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 4.1.6

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢iti50 ciklusa tr£anja svih LED dioda svakih 100 ms i to redoslijedom crvena → ºuta → zelena →plava → crvena → ... . Nakon ²to 50 ciklusa tr£anja LED dioda zavr²i, trajno uklju£ite zujalicu

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4 37

spojenu na pin PF4. Sheme spajanja LED dioda i zujalice na digitalne izlaze mikroupravlja£aATmega32U4 prikazane su na slikama 4.1 i 4.2. Crvena LED dioda spojena je na digitalni pinPB4, ºuta LED dioda spojena je na digitalni pin PB5, zelena LED dioda spojena je na digitalnipin PB6, a plava LED dioda spojena je na digitalni pin PB7.

U projektnom stablu otvorite datoteku vjezba416.cpp. Omogu¢ite samo prevoenjedatoteke vjezba416.cpp. Po£etni sadrºaj datoteke vjezba416.cpp prikazan je programskimkodom 4.10.

Programski kod 4.10: Po£etni sadrºaj datoteke vjezba416.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

void inicijalizacija ()

// PB7 , PB6 , PB5 i PB4 izlazni pinovi

DDRB |= (1 << PB7) | (1 << PB6) | (1 << PB5) | (1 << PB4);

PORTB |= (1 << PB4); // postavljanje PB7 u visoko stanje

DDRF |= (1 << PF4); //pin PF4 za Buzzer

int main(void)

inicijalizacija (); // inicijalizacija mikroupravlja£a

for (int i = 0; i < 50; i++) // petlja koja se izvodi 50 puta

// ovdje ugasiti crvenu LED diodu

// ovdje uklju£iti Buzzer

return 0;

U vjeºbi je ponovno potrebno ostvariti tr£anje LED dioda, ali kona£an broj puta. Uprogramskom kodu 4.10 u blok naredbi for petlje kopirajte blok naredbi while petlje iz datotekevjezba414.cpp. U praksi se £esto ponavljaju dijelovi programskog koda pa je uobi£ajeno kopiratigotovi programski kod u trenutni projekt koji radite.

Prevedite datoteku vjezba416.cpp u strojni kod. Prilikom prevoenja prevoditelj jeu pokazniku statusnih poruka javio gre²ku koja upu¢uje na izostanak deklaracije funkcije_delay_ms. Uklju£ite zaglavlje u kojem je deklarirana funkcija _delay_ms.

Nakon ²to for petlja zavr²i ciklus od 50 koraka, potrebno je isklju£iti crvenu LED diodu kojaje ostala uklju£ena. Ispod bloka naredbi for petlje isklju£ite crvenu LED diodu makronaredbomset_port. Zatim, potrebno je trajno uklju£iti zujalicu spojenu na pin PF4, ²to moºete napravitimakronaredbom set_port(PORTF,PF4, 1);.

Prevedite datoteku vjezba416.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba416.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 4.1.7

Napravite program kojim ¢e razvojno okruºenje s mikroupravlja£em ATmega32U4 reproduciratizvu£nu signalizaciju pomo¢u zujalice i funkcije BUZZ(double trajanje, int frekvencija).Shema spajanja zujalice na digitalni izlaz PF4 mikroupravlja£a ATmega32U4 prikazana je na

38 Digitalni izlazi i ulazi

slici 4.2.

U projektnom stablu otvorite datoteku vjezba417.cpp. Omogu¢ite samo prevoenjedatoteke vjezba417.cpp. Po£etni sadrºaj datoteke vjezba417.cpp prikazan je programskimkodom 4.11.

Programski kod 4.11: Po£etni sadrºaj datoteke vjezba417.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

#include <util/delay.h>

int main(void)

while (1) // beskona£na petlja

//super mario sound - isje£ak

BUZZ (0.1, 660); _delay_ms (150);

BUZZ (0.1, 660); _delay_ms (300);

BUZZ (0.1, 660); _delay_ms (300);

BUZZ (0.1, 510); _delay_ms (100);

BUZZ (0.1, 660); _delay_ms (300);

BUZZ (0.1, 770); _delay_ms (550);

BUZZ (0.1, 770); _delay_ms (575);

BUZZ (0.1, 510); _delay_ms (450);

BUZZ (0.1, 380); _delay_ms (400);

BUZZ (0.1, 320); _delay_ms (500);

BUZZ (0.1, 440); _delay_ms (300);

BUZZ (0.08 , 480);_delay_ms (330);

BUZZ (0.1, 450); _delay_ms (150);

BUZZ (0.1, 430); _delay_ms (300);

BUZZ (0.1, 380); _delay_ms (200);

BUZZ (0.08 , 660);_delay_ms (200);

BUZZ (0.1, 760); _delay_ms (150);

BUZZ (0.1, 860); _delay_ms (300);

BUZZ (0.08 , 700);_delay_ms (150);

BUZZ (0.05 , 760);_delay_ms (350);

BUZZ (0.08 , 660);_delay_ms (300);

BUZZ (0.08 , 520);_delay_ms (150);

BUZZ (0.08 , 580);_delay_ms (150);

BUZZ (0.08 , 480);_delay_ms (1000);

return 0;

Zvu£na signalizacija £esto je potrebna u praksi kako bi ukazala na neki dogaaj. U ovoj vjeºbikoristit ¢emo funkciju BUZZ(double trajanje, int frekvencija) koja prima dva argumenta:

1. trajanje - realni broj dvostruke preciznosti koji predstavlja trajanje zvu£nog signala usekundama,

2. frekvencija - cijeli broj koji predstavlja frekvenciju zvu£nog signala u Hz.

Zujalica je spojena na digitalni izlaz PF4. Na shemi sa slike 4.2 primijetite da je zujalica namikroupravlja£ spojena preko kratkospojnika (engl. jumper) JP2 izmeu trnova 2 i 3. Ako narazvojnom okruºenju s mikroupravlja£em ATmega32U4 nema kratkospojnika JP2, zujalica ne¢eraditi. Zujalicu moºemo spojiti na bilo koji digitalni pin.

Denicija funkcije BUZZ() nalazi se u datoteci AVR VUB/avrvub.h. Prou£ite denicijuove funkcije. U datoteci AVR VUB/avrvub.h povrh deklaracije funkcije BUZZ nalazi se dio

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4 39

programskog koda koji omogu¢uje deniranje digitalnog pina na koji je spojena zujalica.Deniranje digitalnog pina prikazano je programskim kodom 4.12.

Programski kod 4.12: Deniranje digitalnog pina PF4 na koji je spojena zujalica

#define BUZZER_PORT PORTF

#define BUZZER_DDR DDRF

#define BUZZER_PIN PF4

Pojasnimo deniranje digitalnog pina na koji je spojena zujalica kako je prikazano uprogramskom kodu 4.12:

• #define BUZZER_PORT PORTF - podatkovni registar koji uklju£uje i isklju£uje digitalni pinPF4,

• #define BUZZER_DDR DDRF - registar smjera podataka koji denira digitalni pin PF4 kaoizlazni pin,

• #define BUZZER_PIN PF4 - pozicija digitalnog pina PF4.

Ako bi zujalica bila spojena na digitalni pin PD7, programski kod 4.12 trebalo bi promijenitina na£in prikazan u programskom kodu 4.13.

Programski kod 4.13: Deniranje digitalnog pina PD7 na koji je spojena zujalica

#define BUZZER_PORT PORTD

#define BUZZER_DDR DDRD

#define BUZZER_PIN PD7

Prevedite datoteku vjezba417.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Sada poku²ajte napraviti vlastitu zvu£nu signalizaciju. Ponovno prevedite datotekuvjezba417.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte programna razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba417.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 4.1.8

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢ititzv. beskona£no tr£anje svih LED dioda svakih 250 ms i to redoslijedom plava → zelena→ ºuta → crvena → plava → ... . Implementaciju rje²enja potrebno je izvesti pomo¢ubiblioteke DigitalIO.h i klase DigitalOutput. Shema spajanja LED dioda na digitalne izlazemikroupravlja£a ATmega32U4 prikazana je na slici 4.1. Crvena LED dioda spojena je na digitalnipin PB4, ºuta LED dioda spojena je na digitalni pin PB5, zelena LED dioda spojena je nadigitalni pin PB6, a plava LED dioda spojena je na digitalni pin PB7.

U projektnom stablu otvorite datoteku vjezba418.cpp. Omogu¢ite samo prevoenjedatoteke vjezba418.cpp. Po£etni sadrºaj datoteke vjezba418.cpp prikazan je programskimkodom 4.14.

Programski kod 4.14: Po£etni sadrºaj datoteke vjezba418.cpp

#include "AVR VUB/avrvub.h"

#include "DigitalIO/DigitalIO.h"

#include <avr/io.h>

#include <util/delay.h>

40 Digitalni izlazi i ulazi

int main(void)

DigitalOutput plava(B7); // stvori objekt plava za diodu na pinu PB7

while (1)

plava.toggle (); // promjena stanja plave diode

_delay_ms (250); // £ekaj 250 ms

// nastaviti dalje

return 0;

Autor je za manipulaciju digitalnim izlazima i ulazima izradio biblioteku DigitalIO.h ukojoj se nalaze klase DigitalOutput i DigitalInput. Biblioteka DigitalIO.h u programskomje kodu 4.14 uklju£ena pomo¢u naredbe #include "DigitalIO/DigitalIO.h". Ovaj pristupkonguracije i manipulacije digitalnim izlazima i ulazima sli£an je implementaciji u Arduinorazvojnom okruºenju s kojim ste se moºda ve¢ susreli.

U ovom zadatku koristi se klasa DigitalOutput pa ¢e ona biti detaljnije opisana. U klasiDigitalOutput denirana su tri preoptere¢ena konstruktora. Dva konstruktora bitna su zastvaranje objekata koji ¢e se koristiti kao digitalni izlazi. Stvaranje objekata koji su digitalniizlazi mogu¢e je na dva na£ina:

• DigitalOutput plava(B7); - objekt se inicijalizira konstantom Xi (X = B, C, D, E, F; i= 0,1,2,3,4,5,6,7) gdje X ozna£ava port, a i pin na portu. Npr. za pin 7 na portu B koristit¢emo konstantu B7, a za pin 2 na portu D koristit ¢emo konstantu D2.

• DigitalOutput crvena(PB, PB4); - objekt se inicijalizira konstantama X i Xi (X = PB,PC, PD, PE, PF; i = 0,1,2,3,4,5,6,7), gdje X ozna£ava port, a Xi pin na portu. Npr. zapin 4 na portu B koristit ¢emo konstante (PB, PB4), a za pin 2 na portu D koristit ¢emokonstante (PD, PD2).

Crvena LED dioda spojena je na digitalni pin PB4, ºuta LED dioda spojena je na digitalnipin PB5, zelena LED dioda spojena je na digitalni pin PB6, a plava LED dioda spojena jena digitalni pin PB7. Instanciranje objekata za digitalne izlaze na koje su spojene LED diodeprikazano je programskim kodom 4.15. Taj kod potrebno je napisati na samom po£etku main()funkcije.

Programski kod 4.15: Instanciranje objekata za digitalne izlaze na koje su spojene LED diode

DigitalOutput plava(B7); // stvori objekt plava za diodu na pinu PB7

DigitalOutput zelena(B6); // stvori objekt zelena za diodu na pinu PB6

DigitalOutput zuta(B5); // stvori objekt zuta za diodu na pinu PB5

DigitalOutput crvena(PB , PB4); // stvori objekt crvena za diodu na pinu PB4

Primijetite kako u ovom pristupu nema inicijalizacijske funkcije inicijalizacija(). Razlogtome jest to ²to se objekti trebaju tretirati kao i varijable jer egzistiraju samo u bloku u kojem sudenirani. Dakle, objekti plava, zelena, zuta, crvena dohvatljivi su samo u main() funkciji.

Klasa DigitalOutput ima brojne metode (funkcije klase) koje se mogu pozvati nadobjektima:

• on() - metoda uklju£uje izlazni digitalni pin objekta,

• off() - metoda isklju£uje izlazni digitalni pin objekta,

• set() - metoda uklju£uje izlazni digitalni pin objekta,

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4 41

• reset() - metoda isklju£uje izlazni digitalni pin objekta,

• toggle() - metoda mijenja stanje izlaznog digitalnog pina objekta,

• disable() - metoda onemogu¢uje kori²tenje izlaznog digitalnog pina objekta,

• enable() - metoda omogu¢uje kori²tenje izlaznog digitalnog pina objekta,

• state() - metoda vra¢a bool stanje izlaznog digitalnog pina objekta.

Metode se nad objektima pozivaju operatorom . pa se na primjer plava LED dioda moºeuklju£iti naredbom plava.on();. Da bismo ostvarili funkcionalnost traºenu u zadatku, potrebnoje u beskona£nu petlju upisati sljede¢i niz naredaba (koristit ¢e se brojne metode iako je rje²enjemogu¢e samo metodom toggle()):

• plava.toggle(); - promijeni stanje plave LED diode (po£etno stanje bilo je 0, a nakonnavedene naredbe bit ¢e 1),

• _delay_ms(250); - pri£ekaj 250 ms,

• plava.toggle(); - promijeni stanje plave LED diode (prethodno stanje bilo je 1, a nakonnavedene naredbe bit ¢e 1),

• zelena.on(); - uklju£i zelenu LED diodu,

• _delay_ms(250); - pri£ekaj 250 ms,

• zelena.off(); - isklju£i zelenu LED diodu,

• zuta.set(); - uklju£i ºutu LED diodu,

• _delay_ms(250); - pri£ekaj 250 ms,

• zuta.reset(); - isklju£i ºutu LED diodu,

• crvena.on(); - uklju£i crvenu LED diodu,

• _delay_ms(250); - pri£ekaj 250 ms,

• crvena.off(); // isklju£i crvenu diodu.

Prevedite datoteku vjezba418.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba418.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

42 Digitalni izlazi i ulazi

4.1.2 Zadaci - digitalni izlazi mikroupravlja£a ATmega32U4

Zadatak 4.1.1

Napravite program koji ¢e uklju£iti zelenu LED diodu na razvojnom okruºenju smikroupravlja£em ATmega32U4. Shema spajanja zelene LED diode na digitalni izlazPB6 mikroupravlja£a ATmega32U4 prikazana je na slici 4.1.

Zadatak 4.1.2

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 tri putauklju£iti i isklju£iti zelenu LED diodu u razmaku od jedne sekunde izmeu svakog uklju£ivanja.Shema spajanja zelene LED diode na digitalni izlaz PB6 mikroupravlja£a ATmega32U4prikazana je na slici 4.1.

Zadatak 4.1.3

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢itibeskona£no uklju£ivanje i isklju£ivanje zelene LED diode svakih 500 ms. Shema spajanja zeleneLED diode na digitalni izlaz PB6 mikroupravlja£a ATmega32U4 prikazana je na slici 4.1.

Zadatak 4.1.4

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢ititzv. beskona£no tr£anje svih LED dioda svakih 350 ms i to redoslijedom plava → zelena→ ºuta → crvena→ plava → ... . Za izmjenu stanja LED diode koristite makronaredbutoggle_port. Shema spajanja LED dioda na digitalne izlaze mikroupravlja£a ATmega32U4prikazana je na slici 4.1. Crvena LED dioda spojena je na digitalni pin PB4, ºuta LED diodaspojena je na digitalni pin PB5, zelena LED dioda spojena je na digitalni pin PB6, a plava LEDdioda spojena je na digitalni pin PB7.

Zadatak 4.1.5

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢ititzv. beskona£no tr£anje svih LED dioda svakih 350 ms i to redoslijedom plava → zelena→ ºuta → crvena→ plava → ... . Za izmjenu stanja LED diode koristite for petlju. Shemaspajanja LED dioda na digitalne izlaze mikroupravlja£a ATmega32U4 prikazana je na slici 4.1.Crvena LED dioda spojena je na digitalni pin PB4, ºuta LED dioda spojena je na digitalnipin PB5, zelena LED dioda spojena je na digitalni pin PB6, a plava LED dioda spojena je nadigitalni pin PB7.

4.1 Digitalni izlazi mikroupravlja£a ATmega32U4 43

Zadatak 4.1.6

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢iti100 ciklusa tr£anja svih LED dioda svakih 200 ms i to redoslijedom plava → zelena → ºuta →crvena→ plava → ... Nakon ²to 100 ciklusa tr£anja LED dioda zavr²i, trajno uklju£ite zujalicuspojenu na pin PF4. Sheme spajanja LED dioda i zujalice na digitalne izlaze mikroupravlja£aATmega32U4 prikazane su na slikama 4.1 i 4.2. Crvena LED dioda spojena je na digitalni pinPB4, ºuta LED dioda spojena je na digitalni pin PB5, zelena LED dioda spojena je na digitalnipin PB6, a plava LED dioda spojena je na digitalni pin PB7.

Zadatak 4.1.7

Napravite program kojim ¢e razvojno okruºenje s mikroupravlja£em ATmega32U4 reproduciratizvu£nu signalizaciju pomo¢u zujalice i funkcije BUZZ(double trajanje, int frekvencija).Zujalica mora reproducirati zvuk frekvencije 550 Hz u trajanju od jedne sekunde, a zatim zvukfrekvencije 780 Hz u trajanju od 500 ms. Navedenu je zvu£nu signalizaciju potrebno neprestanoponavljati. Shema spajanja zujalice na digitalni izlaz PF4 mikroupravlja£a ATmega32U4prikazana je na slici 4.2.

Zadatak 4.1.8

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢ititzv. beskona£no tr£anje svih LED dioda svakih 300 ms i to redoslijedom crvena → ºuta→ zelena → plava → crvena → ... . Implementaciju rje²enja potrebno je izvesti pomo¢ubiblioteke DigitalIO.h i klase DigitalOutput. Shema spajanja LED dioda na digitalne izlazemikroupravlja£a ATmega32U4 prikazana je na slici 4.1. Crvena LED dioda spojena je nadigitalni pin PB4, ºuta LED dioda spojena je na digitalni pin PB5, zelena LED dioda spojenaje na digitalni pin PB6, a plava LED dioda spojena je na digitalni pin PB7.

44 Digitalni izlazi i ulazi

4.2 Digitalni ulazi mikroupravlja£a ATmega32U4

Ako je bit na poziciji i u registru DDRx jednak 0, tada ¢e pin na poziciji i biti kongurirankao ulazni pin. Pin koji je konguriran kao ulaz moºe biti u dvama stanjima:

• nisko stanje ili stanje logi£ke nule - stanje koje odgovara naponu 0 V,

• visoko stanje ili stanje logi£ke jedinice - stanje koje odgovara naponu 5 V.

Nisko ili visoko stanje na ulaznom pinu moºemo pro£itati u registru PINx prema pravilima:

• ako je bit na poziciji i u registru PINx jednak 0, tada je na ulaznom pinu na poziciji i niskostanje (stanje logi£ke nule),

• ako je bit na poziciji i u registru PINx jednak 1, tada je na ulaznom pinu na poziciji ivisoko stanje (stanje logi£ke jedinice).

Kada je pin konguriran kao ulazni pin, tada se pomo¢u registra PORTx moºe uklju£iti iliisklju£iti pritezni otpornik (engl. pull-up resistor) prema pravilima:

• ako je bit na poziciji i u registru PORTx jednak 0, tada je pritezni otpornik na pozicijipina i isklju£en,

• ako je bit na poziciji i u registru PORTx jednak 1, tada je pritezni otpornik na pozicijipina i uklju£en.

Koja je svrha uklju£enja priteznog otpornika prikazat ¢emo pomo¢u slike 4.4 3.

(a) Tipkalo nije pritisnuto (b) Tipkalo je pritisnuto

Slika 4.4: Tipkalo spojeno na ulazni pin PD0 mikroupravlja£a ATmega32U4

Pretpostavimo da pritezni otpornik nije uklju£en. Koliki je potencijal na digitalnom ulazuPD0 ako tipkalo nije pritisnuto (slika 4.4a)? To ne znamo jer je digitalni ulaz u stanju visokeimpedancije te u registru PIND ne¢emo dobiti ispravno o£itanje. Bilo kakav manji poreme¢ajmoºe promijeniti stanje bita 0 u registru PIND. Iz tog se razloga pin pritegne na potencijal 5

3Izvor: https://www.mikroe.com/ebooks/pic-microcontrollers-programming-in-assembly/io-ports

4.2 Digitalni ulazi mikroupravlja£a ATmega32U4 45

V. Kada tipkalo nije pritisnuto (slika 4.4a), stanje pina je visoko, odnosno 5 V, a stanje bita 0u registru PIND bit ¢e 1. Kada je tipkalo pritisnuto (slika 4.4b), stanje pina je nisko, odnosno0 V, a stanje bita 0 u registru PIND bit ¢e 0. Struja ¢e u slu£aju pritisnutog tipkala te¢i izmikroupravlja£a prema masi (slika 4.4b).

Pritezni otpornici uklju£uju se ako se na mikroupravlja£ spajaju tipkala i senzori s otvorenimkolektorom. Postoje i senzori koji aktivno na svom izlazu mogu dati i visoko i nisko stanje4.Ako na mikroupravlja£ spajamo takav senzor, pritezni otpornik nije potrebno uklju£ivati5.Pritezni otpornik moºe se na mikroupravlja£ spojiti izvana, a njegova je vrijednost naj£e²¢e10 kΩ.

4.2.1 Vjeºbe - digitalni ulazi mikroupravlja£a ATmega32U4

+5V

GND

100n

10k

+5V

GND

GND

1uF

22p

22p

GND

GND

+5V

330

330

+5V

UGND

GND

GND

330

330

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

312

4 S4

312

4 S3

C2

C12

C13

134 2

S5

R54

R55

21

Q1

312

4 S1

312

4 S2

R58

R59

123

JP8

123

JP9

123 JP10

RESET

MISOMOSI

RXTX

AREF

D-D+

VUSB

SCK

PD6

PC7

PE6

PD7

PC6

PF1PF0

SS

S1

RO1

S2

RO2

RO_SW

Slika 4.5: Shema spajanja tipkala na mikroupravlja£ ATmega32U4

Digitalne ulaze mikroupravlja£a ATmega32U4 testirat ¢emo pomo¢u £etiriju tipkala spojenihna pinove PD0, PD1, PF6 i PF7. Shema spajanja tipkala na digitalne ulaze mikroupravlja£aATmega32U4 prikazana je na slici 4.5. LED diode koje ¢emo uz tipkala takoer koristiti u ovojvjeºbi prikazane su na slici 4.1.

Za detalje o konguraciji digitalnih ulaza pogledajte tablicu 10-1 u literaturi [1] na stranici69. Programsko razvojno okruºenje Atmel Studio 7 ima denirana imena registara DDRx,PORTx i PINx (x = B, C, D, E, F). Konguracija pinova svodi se na dodjeljivanje vrijednostiu denirana imena registara DDRx i PORTx. Stanja ulaznih pinova £itaju se u registruPINx. Na primjer, ako ºelimo da svi pinovi porta D budu ulazni pinovi u programskomrazvojnom okruºenju Atmel Studio 7, napisat ¢emo DDRD = 0x00; u heksadecimalnom zapisu

4Senzori s tzv. push-pull izlazom.5Ni²ta se ne¢e dogoditi ako uklju£ite pritezni otpornik.

46 Digitalni izlazi i ulazi

ili DDRD = 0b00000000; u binarnom zapisu. Ukoliko na portu D ºelimo uklju£iti pritezneotpornike na svim pinovima u programskom razvojnom okruºenju Atmel Studio 7, napisat ¢emoPORTD = 0xFF; ili PORTD = 0b11111111;. Pretpostavimo da su na ulaznim pinovima PD0,PD1, PD2 i PD3 visoka stanja, a na pinovima PD4, PD5, PD6 i PD7 niska stanja. Tadabi u programskom razvojnom okruºenju Atmel Studio 7 vrijednost registra PIND bila 0x0F =0b00001111.

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku Digital Input.zip. Naradnoj povr²ini stvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢ipritom dijakriti£ke znakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢etestvoriti zvat ¢e se Ivica Ivic. Datoteku Digital Input.zip raspakirajte u novostvorenudatoteku na radnoj povr²ini. Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini tedvostrukim klikom pokrenite VUB mikroracunala.atsln u datoteci \\Digital Input\vjezbe.U otvorenom projektu nalaze se sve vjeºbe koje ¢emo obraditi u poglavlju Digitalni ulazimikroupravlja£a ATmega32U4. Vjeºbe ¢emo pisati u datoteke s ekstenzijom *.cpp.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koja moºete koristiti za provjeru ispravnostiprogramskih zadataka.

Vjeºba 4.2.1

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 uklju£itisve LED diode ako je pritisnuto tipkalo spojeno na pin PD0. Sheme spajanja tipkala i LEDdioda na mikroupravlja£ ATmega32U4 prikazane su na slikama 4.1 i 4.5.

U projektnom stablu otvorite datoteku vjezba421.cpp. Omogu¢ite samo prevoenjedatoteke vjezba421.cpp. Po£etni sadrºaj datoteke vjezba421.cpp prikazan je programskimkodom 4.16.

Programski kod 4.16: Po£etni sadrºaj datoteke vjezba421.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

void inicijalizacija ()

output_port(DDRB ,PB7); // PB7 postavljen kao izlazni pin

output_port(DDRB ,PB6); // PB6 postavljen kao izlazni pin

output_port(DDRB ,PB5); // PB5 postavljen kao izlazni pin

output_port(DDRB ,PB4); // PB4 postavljen kao izlazni pin

input_port(DDRD ,PD0); // PD0 postavljen kao ulazni pin

set_port(PORTD ,PD0 ,1); // uklju£enje priteznog otpornika na PD0

int main(void)

inicijalizacija (); // inicijalizacija mikroupravlja£a

while (1)

if((PIND & 0x01) == 0x00) // ako je pin PD0 u logi£koj nuli

PORTB |= 0xF0; // uklju£i sve led diode

else

PORTB &= ~0xF0; // ina£e ih isklju£i

return 0;

4.2 Digitalni ulazi mikroupravlja£a ATmega32U4 47

U tijelu funkcije inicijalizacija() nalazi se makronaredba input_port(DDRx,pin) kojudo sada nismo koristili. Ova makronaredba sluºi za konguraciju ulaznog pina. Kao argumenteprima registar DDRx i poziciju pina koji ºelimo postaviti kao ulazni pin.

U bloku naredbi while petlje nalazi se if uvjetni blok koji uklju£uje ili isklju£uje LEDdiode u ovisnosti o stanju bita 0 registra PIN. U tablici 4.3 prikazan je slu£aj u kojem jepritisnuto tipkalo spojeno na pin PD0. Kada je tipkalo pritisnuto, na pinu PD0 nisko je stanje,a vrijednost bita 0 u registru PIND jest 0. Maska 0x01 koja se koristi za ispitivanje stanja bita0 formira se tako da se na poziciju bita 0 postavi 1, a na poziciju ostalih bitova postavi se 0(tablica 4.3). Stanje pina PD0 u programskom razvojnom okruºenju Atmel Studio 7 ispituje senaredbom if((PIND & 0x01)== 0x00). Rezultat bitovne operacije PIND & 0x01 bit ¢e jednak0x00 ako je tipkalo pritisnuto (tablica 4.3). Ako tipkalo nije pritisnuto, rezultat bitovne operacijePIND & 0x01 bit ¢e jednak 0x01 (tablica 4.4).

Tablica 4.3: Ispitivanje stanja pina PD0 - slu£aj u kojem je pritisnuto tipkalo

Pozicija bita bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0

PIND x x x x x x x 0

0x01 0 0 0 0 0 0 0 1

PIND & 0x01 0 0 0 0 0 0 0 0

Tablica 4.4: Ispitivanje stanja pina PD0 - slu£aj u kojem nije pritisnuto tipkalo

Pozicija bita bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0

PIND x x x x x x x 1

0x01 0 0 0 0 0 0 0 1

PIND & 0x01 0 0 0 0 0 0 0 1

Op¢enito, stanje ulaznog pina na poziciji i na portu D ispituje se naredbomif((PIND & maska)== 0x00). Varijabla maska formira se tako da se na poziciju bita i postavi1, a na poziciju ostalih bitova 0. Isti je princip i za port B, C , E ili F, gdje je registar PINDpotrebno zamijeniti registrom PINB, PINC, PINE ili PINF.

Prevedite datoteku vjezba421.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Mikroupravlja£ se moºe inicijalizirati i funkcijom inicijalizacija() prikazanomprogramskim kodom 4.17.

Programski kod 4.17: Funkcija inicijalizacije mikroupravlja£a - drugi na£in

void inicijalizacija ()

DDRB |= 0xF0;

DDRD &= 0xFE;

PORTD |= 0x01;

Ovaj na£in inicijalizacije zahtijeva kreiranje maski kojima ¢e se uklju£iti, odnosno isklju£itibitovi u pojedinim registrima. Na primjer, naredbom DDRB |= 0xF0; gornja £etiri bita uregistru DDRD bit ¢e postavljena u 1 (izlazni pinovi), a donja £etiri bita istog registra ne¢e biti

48 Digitalni izlazi i ulazi

promijenjena. Promijenite funkciju inicijalizacija() u programskom razvojnom okruºenjuAtmel Studio 7 sukladno programskom kodu 4.17. Prevedite datoteku vjezba421.cpp u strojnikod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenjus mikroupravlja£em ATmega32U4.

Tre¢i na£in inicijalizacije mikroupravlja£a jest pomo¢u bitovnih operatora (programski kod4.18). Ovo je najsloºeniji na£in inicijalizacije, ali daje jasnu sliku o konguraciji pinova.Promijenite funkciju inicijalizacija() u programskom razvojnom okruºenju Atmel Studio 7sukladno programskom kodu 4.18. Prevedite datoteku vjezba421.cpp u strojni kod isnimite ga na mikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenju smikroupravlja£em ATmega32U4.

Programski kod 4.18: Funkcija inicijalizacije mikroupravlja£a - tre¢i na£in

void inicijalizacija ()

DDRB |= (1 << PB7) | (1 << PB6) | (1 << PB5) | (1 << PB4);

DDRD &= ~(1 << PD0);

PORTD |= (1 << PD0);

Izbri²ite naredbu PORTD |= (1 << PD0); u funkciji inicijalizacija(). Prevedite datotekuvjezba421.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte programna razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Poku²ajte sada jednim prstom dotaknuti noºice tipkala koje je spojeno na pin PD0, a drugimprstom dotaknuti trn konektora za serijsku komunikaciju na kojem pi²e 5 V. Primijetite da se LEDdiode neprestano uklju£uju i isklju£uju iako niste pritisnuli tipkalo spojeno na pin PD0. Onogtrenutka kada smo u funkciji inicijalizacija() izbrisali naredbu PORTD |= (1 << PD0);,isklju£ili smo pritezni otpornik na pinu PD0. Kada tipkalo nije pritisnuto, pin PD0 nalazi se ustanju visoke impedancije te svaki vanjski poreme¢aj utje£e na promjenu stanja bita 0 u registruPIND.

Zatvorite datoteku vjezba421.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 4.2.2

Napravite program kojim ¢e se na razvojnom okruºenju s mikroupravlja£em ATmega32U4uklju£iti crvena LED dioda ako je pritisnuto tipkalo spojeno na pin PD0, ºuta LED dioda akoje pritisnuto tipkalo spojeno na pin PD1, zelena LED dioda ako je pritisnuto tipkalo spojenona pin PF6 i plava LED dioda ako je pritisnuto tipkalo spojeno na pin PF7. Sheme spajanjatipkala i LED dioda na mikroupravlja£ ATmega32U4 prikazane su na slikama 4.1 i 4.5.

U projektnom stablu otvorite datoteku vjezba422.cpp. Omogu¢ite samo prevoenjedatoteke vjezba422.cpp. Po£etni sadrºaj datoteke vjezba422.cpp prikazan je programskimkodom 4.19.

Programski kod 4.19: Po£etni sadrºaj datoteke vjezba422.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

void inicijalizacija ()

// PB7 ,PB6 ,PB5 ,i PB4 postavljeni kao ulazni pinovi

DDRB |= (1 << PB7) | (1 << PB6) | (1 << PB5) | (1 << PB4);

// PD1 i PD0 postavljeni kao izlazni pinovi

4.2 Digitalni ulazi mikroupravlja£a ATmega32U4 49

DDRD &= ~((1 << PD1) | (1 << PD0));

// PF7 i PF6 postavljeni kao izlazni pinovi

DDRF &= ~((1 << PF7) | (1 << PF6));

// pritezni otpornici uklju£eni na pinovima PD1 i PD0

PORTD |= (1 << PD1) | (1 << PD0);

// pritezni otpornici uklju£eni na pinovima PF7 i PF6

PORTF |= (1 << PF7) | (1 << PF6);

int main(void)

inicijalizacija (); // inicijalizacija mikroupravlja£a

while (1)

if((PIND & (1 << PD0)) == 0x00) // ako je pin PD0 u logi£koj nuli

PORTB |= (1 << PB4); // uklju£i crvenu LED diodu

else

PORTB &= ~(1 << PB4); // ina£e je isklju£i

// nastavite za ostala tipkala

return 0;

U vjeºbi je potrebno uklju£iti crvenu LED diodu ako je pritisnuto tipkalo spojeno na pinPD0, ºutu LED diodu ako je pritisnuto tipkalo spojeno na pin PD1, zelenu LED diodu ako jepritisnuto tipkalo spojeno na pin PF6 i plavu LED diodu ako je pritisnuto tipkalo spojeno napin PF7.

U programskom kodu 4.19 prikazano je tijelo funkcije inicijalizacija(). Pinovi PB7, PB6,PB5 i PB4 kongurirani su kao izlazni pinovi, dok su pinovi PD0, PD1, PF6 i PF7 konguriranikao ulazni. Uklju£eni su pritezni otpornici za pinove PD0, PD1, PF6 i PF7. Pri pokretanjustrojnog koda u mikroupravlja£u svi DDRx registri inicijalno su u stanju 0x00, pa smo stoga mogliizostaviti dio tijela funkcije inicijalizacija() koji kongurira ulazne pinove. Preporu£uje seda unato£ tome ne izostavljate konguraciju ulaznih pinova zbog preglednosti programskog kodai jasnog uvida u namjenu digitalnog pina.

U while petlji prikazanoj u programskom kodu 4.19 nalazi se niz naredbi koje ¢e uklju£iticrvenu LED diodu ako je pritisnuto tipkalo spojeno na pin PD0. Pro²irite niz naredbi whilepetlje tako da uklju£ite ºutu LED diodu ako je pritisnuto tipkalo spojeno na pin PD1, zelenuLED diodu ako je pritisnuto tipkalo spojeno na pin PF6 i plavu LED diodu ako je pritisnutotipkalo spojeno na pin PF7. Maska za naredbu if((PIND & maska)== 0x00)) formira se nasljede¢i na£in:

• maska = (1 << PD0) - ako ºelite provjeriti stanje pina PD0 ((1 << PD0)= 0x01 na pozicijibita 0 ima vrijednost 1, ostali bitovi imaju vrijednost 0),

• maska = (1 << PD1) - ako ºelite provjeriti stanje pina PD1 ((1 << PD1)= 0x02 na pozicijibita 1 ima vrijednost 1, ostali bitovi imaju vrijednost 0).

Maska za naredbu if((PINF & maska)== 0x00)) formira se na sljede¢i na£in:

• maska = (1 << PF6) - ako ºelite provjeriti stanje pina PF6 ((1 << PF6)= 0x40 na pozicijibita 6 ima vrijednost 1, ostali bitovi imaju vrijednost 0),

• maska = (1 << PF7) - ako ºelite provjeriti stanje pina PF7 ((1 << PF7)= 0x80 na pozicijibita 7 ima vrijednost 1, ostali bitovi imaju vrijednost 0).

50 Digitalni izlazi i ulazi

Prevedite datoteku vjezba422.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba422.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 4.2.3

Napravite program kojim ¢e se na razvojnom okruºenju s mikroupravlja£em ATmega32U4uklju£iti crvena LED dioda ako je pritisnuto tipkalo spojeno na pin PD0, ºuta LED dioda akoje pritisnuto tipkalo spojeno na pin PD1, zelena LED dioda ako je pritisnuto tipkalo spojenona pin PF6 i plava LED dioda ako je pritisnuto tipkalo spojeno na pin PF7. Za provjerustanja ulaznog pina koristite makronaredbu get_pin. Sheme spajanja tipkala i LED dioda namikroupravlja£ ATmega32U4 prikazane su na slikama 4.1 i 4.5.

U projektnom stablu otvorite datoteku vjezba423.cpp. Omogu¢ite samo prevoenjedatoteke vjezba423.cpp. Po£etni sadrºaj datoteke vjezba423.cpp prikazan je programskimkodom 4.20.

Programski kod 4.20: Po£etni sadrºaj datoteke vjezba423.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

void inicijalizacija ()

output_port(DDRB ,PB7); // PB7 postavljen kao izlazni pin

output_port(DDRB ,PB6); // PB6 postavljen kao izlazni pin

output_port(DDRB ,PB5); // PB5 postavljen kao izlazni pin

output_port(DDRB ,PB4); // PB4 postavljen kao izlazni pin

input_port(DDRD ,PD0); // PD0 postavljen kao ulazni pin

input_port(DDRD ,PD1); // PD1 postavljen kao ulazni pin

input_port(DDRF ,PF6); // PF6 postavljen kao ulazni pin

input_port(DDRF ,PF7); // PF7 postavljen kao ulazni pin

set_port(PORTD ,PD0 ,1); // uklju£ivanje priteznog otpornika na PD0

set_port(PORTD ,PD1 ,1); // uklju£ivanje priteznog otpornika na PD1

set_port(PORTF ,PF6 ,1); // uklju£ivanje priteznog otpornika na PF6

set_port(PORTF ,PF7 ,1); // uklju£ivanje priteznog otpornika na PF7

int main(void)

inicijalizacija (); // inicijalizacija mikroupravlja£a

while (1)

if(get_pin(PIND ,PD0) == 0) // ako je pin PD0 u logi£koj nuli

set_port(PORTB , PB4 , 1); // uklju£i crvenu LED diodu

else

set_port(PORTB , PB4 , 0); // ina£e je isklju£i

// nastavite za ostala tipkala

return 0;

U ovoj vjeºbi cilj je isti kao i u prethodnoj vjeºbi. U programskom kodu 4.20 prikazano je

4.2 Digitalni ulazi mikroupravlja£a ATmega32U4 51

tijelo funkcije inicijalizacija(). Pinovi PB7, PB6, PB5 i PB4 kongurirani su kao izlaznipinovi, dok su pinovi PD0, PD1, PF6 i PF7 kongurirani kao ulazni. Uklju£eni su pritezniotpornici za pinove PD0, PD1, PF6 i PF7. Za navedene konguracije kori²tene su makronaredbeoutput_port, input_port i set_port iz zaglavlja avrvub.h.

U while petlji prikazanoj u programskom kodu 4.20 nalazi se niz naredbi koje ¢e uklju£iticrvenu LED diodu ako je pritisnuto tipkalo spojeno na pin PD0. Za provjeru stanja ulaznogpina kori²tena je makronaredba get_pin. Ova makronaredba kao argumente prima registarPINx i poziciju pina za koji ºelite ispitati stanje, a kao rezultat vra¢a stanje ulaznog pina. Naprimjer, ako je na ulaznom pinu PD0 visoko stanje, makronaredba get_pin(PIND,PD0) vratit¢e vrijednost 1. Ako je na ulaznom pinu PD0 nisko stanje, makronaredba get_pin(PIND,PD0)vratit ¢e vrijednost 0. Kada je tipkalo pritisnuto, stanje je pina nisko. Prema tome, logi£kiuvjet (get_pin(PIND,PD0)== 0) bit ¢e istinit ako je tipkalo pritisnuto, a laºan ako tipkalo nijepritisnuto.

Pro²irite niz naredbi while petlje tako da uklju£ite ºutu LED diodu ako je pritisnuto tipkalospojeno na pin PD1, zelenu LED diodu ako je pritisnuto tipkalo spojeno na pin PF6 i plavu LEDdiodu ako je pritisnuto tipkalo spojeno na pin PF7 kori²tenjem makronaredbe get_pin.

Prevedite datoteku vjezba423.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba423.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 4.2.4

Napravite program kojim ¢e se na razvojnom okruºenju s mikroupravlja£em ATmega32U4uklju£iti crvena LED dioda ako je pritisnuto tipkalo spojeno na pin PD0, ºuta LED dioda akoje pritisnuto tipkalo spojeno na pin PD1, zelena LED dioda ako je pritisnuto tipkalo spojeno napin PF6 i plava LED dioda ako je pritisnuto tipkalo spojeno na pin PF7. Za provjeru stanjaulaznog pina koristite funkciju filtered_pin_state. Funkcija filtered_pin_state moºeltrirati smetnje koje se javljaju zbog istitravanja tipkala. Sheme spajanja tipkala i LED diodana mikroupravlja£ ATmega32U4 prikazane su na slikama 4.1 i 4.5.

U projektnom stablu otvorite datoteku vjezba424.cpp. Omogu¢ite samo prevoenjedatoteke vjezba424.cpp. Po£etni sadrºaj datoteke vjezba424.cpp prikazan je programskimkodom 4.21.

Programski kod 4.21: Po£etni sadrºaj datoteke vjezba424.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

void inicijalizacija ()

// PB7 ,PB6 ,PB5 ,i PB4 postavljeni kao ulazni pinovi

DDRB |= (1 << PB7) | (1 << PB6) | (1 << PB5) | (1 << PB4);

// PD1 i PD0 postavljeni kao izlazni pinovi

DDRD &= ~((1 << PD1) | (1 << PD0));

// PF7 i PF6 postavljeni kao izlazni pinovi

DDRF &= ~((1 << PF7) | (1 << PF6));

// pritezni otpornici uklju£eni na pinovima PD1 i PD0

PORTD |= (1 << PD1) | (1 << PD0);

// pritezni otpornici uklju£eni na pinovima PF7 i PF6

PORTF |= (1 << PF7) | (1 << PF6);

52 Digitalni izlazi i ulazi

int main(void)

inicijalizacija (); // inicijalizacija mikroupravlja£a

while (1)

// ako je filtrirani pin PD0 u logi£koj nuli

if(filtered_pin_state(PD,PD0 ,false ,30) == false)

set_port(PORTB , PB4 , 1); // uklju£i crvenu LED diodu

else

set_port(PORTB , PB4 , 0); // ina£e je isklju£i

// nastavite za ostala tipkala

return 0;

U trenutku kada pritisnemo istro²eno tipkalo na razvojnom okruºenju s mikroupravlja£emATmega32U4, brid signala tipkala ne¢e odmah pasti na nisku razinu, ve¢ dolazi do istitravanja(slika 4.6).

Slika 4.6: Istitravanje koje se javlja kod istro²enog tipkala

Istitravanje moºe biti nezgodno ako npr. moramo brojati koliko je puta tipkalo pritisnuto.Pogledajmo signal tipkala na slici 4.6. Ukoliko bi za provjeru stanja tipkala koristilimakronaredbu get_pin, broja£ koji broji koliko je puta pritisnuto tipkalo uve¢ao bi se za tri.Razlog tome jest uzastopni prijelaz iz visokog u nisko stanje zbog mehani£kih karakteristikatipkala.

Ovaj problem moºe se rije²iti uvoenjem vremenskog okvira unutar kojeg ¢emo pratitikoliko je vremena tipkalo bilo pritisnuto. U zaglavlju avrvub.h nalazi se funkcijafiltered_pin_state koja rje²ava problem istitravanja tipkala.

Funkcija filtered_pin_state prima £etiri argumenta:

• oznaku porta ulaznog pina £ije stanje ºelite ispitati (PB, PC, PD, PE, PF),

• poziciju ulaznog pina £ije stanje ºelite ispitati (npr. PD1),

• stanje koje ºelite ispitati na poziciji ulaznog pina (npr. ako ºelite ispitati je li na pozicijipina nisko stanje, ovdje ¢ete upisati 0),

• vremenska konstanta u milisekundama predstavlja vremenski okvir unutar kojeg ¢e se svakemilisekunde ispitivati koje je trenutno stanje ulaznog pina.

Pretpostavimo da smo koristili funkciju filtered_pin_state(PF,PF6,0,30). Ova ¢e funkcijavratiti vrijednost 0 ako je ulazni pin PF6 na portu F (PF) 90 % vremena deniranog vremenskom

4.2 Digitalni ulazi mikroupravlja£a ATmega32U4 53

konstantom (£etvrti argument 30 ms) bio u niskom stanju. Na ovaj na£in kratkotrajni ¢eporeme¢aji biti ltrirani zbog £injenice da ulazni pin PF6 90 % vremena deniranog vremenskomkonstantom biti ne¢e u niskom stanju. Vremenska konstanta pode²ava se iskustveno, apreporu£ena joj je vrijednost 25 ms.

Denicija funkcije filtered_pin_state nalazi se u datoteci avrvub.cpp. Znatiºeljni £itateljdetaljno ¢e prou£iti na£in rada ove funkcije.

U programskom kodu 4.21 prikazano je tijelo funkcije inicijalizacija(). Pinovi PB7, PB6,PB5 i PB4 kongurirani su kao izlazni pinovi, dok su pinovi PD0, PD1, PF6 i PF7 konguriranikao ulazni. Uklju£eni su pritezni otpornici za pinove PD0, PD1, PF6 i PF7.

U while petlji prikazanoj u programskom kodu 4.21 nalazi se niz naredbi koje ¢e uklju£iticrvenu LED diodu ako je pritisnuto tipkalo spojeno na pin PD0. Za provjeru stanja ulaznog pinakori²tena je funkcija filtered_pin_state. Pro²irite niz naredbi while petlje tako da uklju£iteºutu LED diodu ako je pritisnuto tipkalo spojeno na pin PD1, zelenu LED diodu ako je pritisnutotipkalo spojeno na pin PF6 i plavu LED diodu ako je pritisnuto tipkalo spojeno na pin PF7kori²tenjem funkcije filtered_pin_state. Vremensku konstantu funkcije filtered_pin_statepostavite na 25 ms.

Prevedite datoteku vjezba424.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Sada promijenite vremensku konstantu tako da za pin PD0 ona iznosi 30 ms, za pin PD1100 ms, za pin PF6 500 ms, a za pin PF7 1000 ms. Ponovno prevedite datoteku vjezba424.cppu strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte program na razvojnomokruºenju s mikroupravlja£em ATmega32U4. Komentirajte rezultat!

Zatvorite datoteku vjezba424.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 4.2.5

Napravite program kojim ¢e se na razvojnom okruºenju s mikroupravlja£em ATmega32U4promijeniti stanje crvene LED diode na padaju¢i brid signala tipkala spojenog na pin PD0,ºute LED diode na rastu¢i brid signala tipkala spojenog na pin PD1, zelene LED diode napadaju¢i brid signala tipkala spojenog na pin PF6 i plave LED diode na rastu¢i brid signalatipkala spojenog na pin PF7. Za detekciju padaju¢eg brida koristite funkciju isFalling_edge,a za detekciju rastu¢eg brida funkciju isRising_edge. Sheme spajanja tipkala i LED dioda namikroupravlja£ ATmega32U4 prikazane su na slikama 4.1 i 4.5.

U projektnom stablu otvorite datoteku vjezba425.cpp. Omogu¢ite samo prevoenjedatoteke vjezba425.cpp. Po£etni sadrºaj datoteke vjezba425.cpp prikazan je programskimkodom 4.22.

Programski kod 4.22: Po£etni sadrºaj datoteke vjezba425.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

void inicijalizacija ()

// napravite konfiguraciju

int main(void)

inicijalizacija (); // inicijalizacija mikroupravlja£a

while (1)

54 Digitalni izlazi i ulazi

// ako je padaju¢i brid na pinu PD0

if(isFalling_edge(PD , PD0) == true)

toggle_port(PORTB , PB4); // promijeni stanje crvene LED diode

// ako je rastu¢i brid na pinu PD1

if(isRising_edge(PD ,PD1) == true)

toggle_port(PORTB , PB5); // promijeni stanje ºute LED diode

// nastavite za ostala tipkala

return 0;

esto se u prakti£noj primjeni koriste gumbovi na dodir (engl. touch button). Oni sluºeza uklju£enje nekog dijela sustava. Do uklju£enja sustava mora do¢i kada dodirnemo gumb inakon toga sustav mora nastaviti raditi. Dosad nismo imali takav slu£aj jer su LED diode bileuklju£ene samo ako su tipkala konstantno bila pritisnuta.

U programskom kodu 4.22 prikazano je tijelo funkcije inicijalizacija(). Napravitekonguraciju svih pinova koji ¢e se koristiti u ovoj vjeºbi. Na£in konguracije proizvoljan je.

U while petlji prikazanoj u programskom kodu 4.22 nalazi se niz naredbi koje ¢e promijenitistanje crvene LED diode ako se na pinu PD0 pojavi padaju¢i brid signala te promijeniti stanjeºute LED diode ako se na pinu PD1 pojavi rastu¢i brid signala. Padaju¢i brid signala na pinuPD0 javit ¢e se u trenutku kada pritisnemo tipkalo. Tada ¢e stanje iz visokog prije¢i u nisko.Rastu¢i brid signala na pinu PD1 javit ¢e se u trenutku kada otpustimo tipkalo. Tada ¢e stanjeiz niskog prije¢i u visoko. Za detekciju padaju¢eg brida koristimo funkciju isFalling_edge, aza detekciju rastu¢eg brida funkciju isRising_edge. Obje funkcije vra¢aju bool vrijednost nasljede¢i na£in:

• funkcija isFalling_edge vratit ¢e true ako se na pinu pojavio padaju¢i brid, a false akose brid nije pojavio,

• funkcija isRising_edge vratiti ¢e true ako se na pinu pojavio rastu¢i brid, a false akose brid nije pojavio.

Funkcije isFalling_edge i isRising_edge primaju dva argumenta:

• oznaku porta ulaznog pina £iji brid signala ºelite ispitati (PB, PC, PD, PE, PF),

• poziciju ulaznog pina £iji brid signala ºelite ispitati (npr. PD1).

Denicije funkcija isFalling_edge i isRising_edge nalaze se u datoteci avrvub.cpp.Znatiºeljni £itatelj detaljno ¢e prou£iti na£in rada ovih funkcija, kao i deklariranu varijablu(polje podataka) u kojoj se £uvaju stare vrijednosti ulaznog signala kako bi se mogao detektiratibrid signala.

Pro²irite niz naredbi while petlje tako da se stanje zelene LED diode promijeni na padaju¢ibrid signala tipkala spojenog na pin PF6, a stanje plave LED diode na rastu¢i brid signala tipkalaspojenog na pin PF7.

Prevedite datoteku vjezba425.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba425.cpp i onemogu¢ite prevoenje ove datoteke.

4.2 Digitalni ulazi mikroupravlja£a ATmega32U4 55

Vjeºba 4.2.6

Napravite program kojim ¢e se na razvojnom okruºenju s mikroupravlja£em ATmega32U4uklju£iti crvena LED dioda ako je pritisnuto tipkalo spojeno na pin PD0, uklju£iti ºuta LED diodaako je pritisnuto tipkalo spojeno na pin PD1 (ltrirati istitravanje tipkala), promijeniti stanjezelene LED diode na padaju¢i brid signala tipkala spojenog na pin PF6 te promijeniti stanjeplave LED diode na rastu¢i brid signala tipkala spojenog na pin PF7. Implementaciju rje²enjapotrebno je izvesti pomo¢u biblioteke DigitalIO.h i klasa DigitalOutput i DigitalInput.Sheme spajanja tipkala i LED dioda na mikroupravlja£ ATmega32U4 prikazane su na slikama4.1 i 4.5.

U projektnom stablu otvorite datoteku vjezba426.cpp. Omogu¢ite samo prevoenjedatoteke vjezba426.cpp. Po£etni sadrºaj datoteke vjezba426.cpp prikazan je programskimkodom 4.23.

Programski kod 4.23: Po£etni sadrºaj datoteke vjezba426.cpp

#include "AVR VUB/avrvub.h"

#include "DigitalIO/DigitalIO.h"

#include <avr/io.h>

#include <util/delay.h>

int main(void)

// instance objekata digitalnih izlaza

DigitalOutput plava(B7); // stvori objekt plava za diodu na pinu PB7

DigitalOutput zelena(B6); // stvori objekt zelena za diodu na pinu PB6

DigitalOutput zuta(B5); // stvori objekt zuta za diodu na pinu PB5

DigitalOutput crvena(B4); // stvori objekt crvena za diodu na pinu PB4

// instance objekata digitalnih ulaza

DigitalInput tipkalo1(D0); // stvori objekt za tipkalo na pinu PD0

// instancirati ostale digitalne ulaze

tipkalo1.pullup_on (); //uklju£i pull up za pin PD0

//uklju£iti ostale pull up otpornike

while (1)

// napraviti funkcionalnost zadanu zadatkom

return 0;

Autor je za manipulaciju digitalnim izlazima i ulazima izradio biblioteku DigitalIO.h ukojoj se nalaze klase DigitalOutput i DigitalInput. Biblioteka DigitalIO.h u programskomje kodu 4.23 uklju£ena pomo¢u naredbe #include "DigitalIO/DigitalIO.h". Ovaj pristupkonguracije i manipulacije digitalnim izlazima i ulazima sli£an je implementaciji u Arduinorazvojnom okruºenju s kojim ste se moºda ve¢ susreli.

U ovom zadatku koriste se klase DigitalOutput i DigitalInput. Klasa DigitalOutputdetaljno je opisana u vjeºbi 4.1.8. U nastavku ¢emo opisati klasu DigitalInput. U klasiDigitalInput denirana su tri preoptere¢ena konstruktora. Dva konstruktora bitna su zastvaranje objekata koji ¢e se koristiti kao digitalni ulazi. Stvaranje objekata koji su digitalniulazi mogu¢e je na dva na£ina:

• DigitalInput tipkalo1(D0); - objekt se inicijalizira konstantom Xi (X = B, C, D, E,F; i = 0,1,2,3,4,5,6,7) gdje X ozna£ava port, a i pin na portu. Npr. za pin 0 na portu D

56 Digitalni izlazi i ulazi

koristit ¢emo konstantu D0, a za pin 3 na portu B koristit ¢emo konstantu B3.

• DigitalInput tipkalo1(PD, PD0); - objekt se inicijalizira konstantama X i Xi (X =PB, PC, PD, PE, PF; i = 0,1,2,3,4,5,6,7) gdje X ozna£ava port, a Xi pin na portu. Npr.za pin 6 na portu F koristit ¢emo konstante (PF, PF6), a za pin 1 na portu D koristit¢emo konstante (PD, PD1).

Tipkala su redom spojena na pinove PD0, PD1, PF6 i PF7. Instanciranje objekata zadigitalne ulaze na koje su spojena tipkala prikazano je programskim kodom 4.24. Taj kodpotrebno je napisati u main() funkciji nakon dijela programskog koda kojim su instanciraneLED diode.

Programski kod 4.24: Instanciranje objekata za digitalne ulaze na koje su spojena tipkala

// instance objekata digitalnih ulaza

DigitalInput tipkalo1(D0); // stvori objekt za tipkalo na pinu PD0

DigitalInput tipkalo2(D1); // stvori objekt za tipkalo na pinu PD1

DigitalInput tipkalo3(F6); // stvori objekt za tipkalo na pinu PF6

DigitalInput tipkalo4(F7); // stvori objekt za tipkalo na pinu PF7

Primijetite kako u ovom pristupu nema inicijalizacijske funkcije inicijalizacija(). Razlogtome je taj ²to se objekti trebaju tretirati kao i varijable jer egzistiraju samo u bloku u kojemsu denirani. Dakle, objekti tipkalo1, tipkalo2, tipkalo3, tipkalo4 dohvatljivi su samo umain() funkciji.

Klasa DigitalInput ima brojne metode (funkcije klase) koje se mogu pozvati nad objektima:

• pullup_on() - metoda uklju£uje pritezni otpornik na pinu,

• pullup_off() - metoda isklju£uje pritezni otpornik na pinu,

• state() - metoda vra¢a bool stanje ulaznog digitalnog pina objekta,

• isRising_edge() - metoda sluºi za detekciju rastu¢eg brida. Vra¢a vrijednost true ako sena pinu pojavio rastu¢i brid, a false ako se brid nije pojavio.

• isFalling_edge() - metoda sluºi za detekciju padaju¢eg brida. Vra¢a vrijednost true akose na pinu pojavio padaju¢i brid, a false ako se brid nije pojavio.

• filtered_state(bool stanje, uint16_t T) - metoda koja provjerava je li na pinustanje (prvi argument metode) 90 % vremena T deniranog drugim argumentom metode.Ova metoda omogu¢uje ltriranje istitravanja tipkala.

Metode se nad objektima pozivaju operatorom . pa se stanje objekta tipkalo1 moºedohvatiti naredbom tipkalo1.state();.

Da bi stanja tipkala bila ispravno detektirana, potrebno je uklju£iti pritezne otpornike nadigitalnim ulazima na koje su spojena tipkala. Uklju£ivanje priteznog otpornika za digitalneulaze na koje su spojena tipkala prikazano je programskim kodom 4.25. Taj kod potrebno jenapisati u main() funkciji nakon instanciranja objekata za tipkala.

Programski kod 4.25: Uklju£ivanje priteznog otpornika za digitalne ulaze na koje su spojenatipkala

tipkalo1.pullup_on (); // ukljuci pull up za pin PD0

tipkalo2.pullup_on (); // ukljuci pull up za pin PD1

tipkalo3.pullup_on (); // ukljuci pull up za pin PF6

tipkalo4.pullup_on (); // ukljuci pull up za pin PF7

4.2 Digitalni ulazi mikroupravlja£a ATmega32U4 57

Funkcionalnost zadana zadatkom denirana je u beskona£noj petlji programskim kodom 4.26.Objasnimo sada pozive metoda nad objektima ulaznih pinova:

• if (tipkalo1.state()== false) - provjeravanje je li pritisnuto tipkalo na pinu PD0. Akoje pritisnuto, stanje tipkala ¢e biti false.

• if (tipkalo2.filtered_state(false, 25)== false) - provjeravanje je li pritisnutotipkalo na pinu PD1 90 % vremena od 25 ms.

• if (tipkalo3.isFalling_edge()) - provjeravanje je li se pojavio padaju¢i brid na tipkaluspojenom na pin PF6.

• if (tipkalo4.isRising_edge()) - provjeravanje je li se pojavio rastu¢i brid na tipkaluspojenom na pin PF7.

U while(1) petlju prepi²ite programski kod 4.26.

Programski kod 4.26: Funkcionalnost zadana zadatkom u beskona£noj petlji

if (tipkalo1.state() == false)

crvena.on();

else

crvena.off();

if (tipkalo2.filtered_state(false , 25) == false)

zuta.on();

else

zuta.off();

if (tipkalo3.isFalling_edge ())

zelena.toggle ();

if (tipkalo4.isRising_edge ())

plava.toggle ();

Prevedite datoteku vjezba426.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba426.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

58 Digitalni izlazi i ulazi

4.2.2 Zadaci - digitalni ulazi mikroupravlja£a ATmega32U4

Zadatak 4.2.1

Napravite program koji ¢e na razvojnom okruºenju s mikroupravlja£em ATmega32U4 uklju£iticrvenu i zelenu LED diodu ako je pritisnuto tipkalo spojeno na pin PD1. Sheme spajanja tipkalai LED dioda na mikroupravlja£ ATmega32U4 prikazane su na slikama 4.1 i 4.5.

Zadatak 4.2.2

Napravite program kojim ¢e se na razvojnom okruºenju s mikroupravlja£em ATmega32U4uklju£iti plava LED dioda ako je pritisnuto tipkalo spojeno na pin PD0, zelena LED dioda akoje pritisnuto tipkalo spojeno na pin PD1, ºuta LED dioda ako je pritisnuto tipkalo spojeno napin PF6 i crvena LED dioda ako je pritisnuto tipkalo spojeno na pin PF7. Sheme spajanjatipkala i LED dioda na mikroupravlja£ ATmega32U4 prikazane su na slikama 4.1 i 4.5.

Zadatak 4.2.3

Napravite program kojim ¢e se na razvojnom okruºenju s mikroupravlja£em ATmega32U4uklju£iti plava LED dioda ako je pritisnuto tipkalo spojeno na pin PD0, zelena LED dioda akoje pritisnuto tipkalo spojeno na pin PD1, ºuta LED dioda ako je pritisnuto tipkalo spojenona pin PF6 i crvena LED dioda ako je pritisnuto tipkalo spojeno na pin PF7. Za provjerustanja ulaznog pina koristite makronaredbu get_pin. Sheme spajanja tipkala i LED dioda namikroupravlja£ ATmega32U4 prikazane su na slikama 4.1 i 4.5.

Zadatak 4.2.4

Napravite program kojim ¢e se na razvojnom okruºenju s mikroupravlja£em ATmega32U4uklju£iti plava LED dioda ako je pritisnuto tipkalo spojeno na pin PD0, zelena LED dioda akoje pritisnuto tipkalo spojeno na pin PD1, ºuta LED dioda ako je pritisnuto tipkalo spojeno napin PF6 i crvena LED dioda ako je pritisnuto tipkalo spojeno na pin PF7. Za provjeru stanjaulaznog pina koristite funkciju filtered_pin_state. Funkcija filtered_pin_state moºeltrirati smetnje koje se javljaju zbog istitravanja tipkala. Sheme spajanja tipkala i LED diodana mikroupravlja£ ATmega32U4 prikazane su na slikama 4.1 i 4.5.

Zadatak 4.2.5

Napravite program kojim ¢e se na razvojnom okruºenju s mikroupravlja£em ATmega32U4promijeniti stanje plave LED diode na rastu¢i brid signala tipkala spojenog na pin PD0, zeleneLED diode na padaju¢i brid signala tipkala spojenog na pin PD1, ºute LED diode na rastu¢ibrid signala tipkala spojenog na pin PF6 i crvene LED diode na padaju¢i brid signala tipkalaspojenog na pin PF7. Za detekciju padaju¢eg brida koristite funkciju isFalling_edge, a zadetekciju rastu¢eg brida funkciju isRising_edge. Sheme spajanja tipkala i LED dioda namikroupravlja£ ATmega32U4 prikazane su na slikama 4.1 i 4.5.

4.2 Digitalni ulazi mikroupravlja£a ATmega32U4 59

Zadatak 4.2.6

Napravite program kojim ¢e se na razvojnom okruºenju s mikroupravlja£em ATmega32U4uklju£iti plava LED dioda ako nije pritisnuto tipkalo spojeno na pin PD0, uklju£iti zelena LEDdioda ako je pritisnuto tipkalo spojeno na pin PD1 (ltrirati istitravanje tipkala), promijenitistanje ºute LED diode na rastu¢i brid signala tipkala spojenog na pin PF6 te promijeniti stanjecrvene LED diode na padaju¢i brid signala tipkala spojenog na pin PF7. Implementaciju rje²enjapotrebno je izvesti pomo¢u biblioteke DigitalIO.h i klasa DigitalOutput i DigitalInput.Sheme spajanja tipkala i LED dioda na mikroupravlja£ ATmega32U4 prikazane su na slikama4.1 i 4.5.

60 Digitalni izlazi i ulazi

Poglavlje 5

LCD displej

LCD displej koristi se za prikazivanje varijabli sustava koje mogu biti temperatura, vlagazraka, brzina vrtnje, broj proizvedenih proizvoda i drugo. esto se koristi za izbornikkojim se moºe napraviti pregled i izmjena parametara sustava. Na razvojnom okruºenju smikroupravlja£em ATmega32U4 prikazanom na slici 3.1 nalazi se konektor za LCD displejGDM1602E. On ima mogu¢nost prikaza dvaju redaka sa 16 znakova u jednom retku. U pojediniredak mogu¢e je zapisati 40 znakova, no samo ih je 16 vidljivo. LCD displej posjeduje funkcije zapomicanje teksta ulijevo i udesno te tako moºemo prikazati ukupno 40 znakova u jednom retku.On ima vlastiti mikroupravlja£ koji se brine o dekodiranju podataka koji pristiºu na njegoveulazne pinove. Znakovi koje LCD displej prikazuje nalaze se u njegovu memorijskom prostoru.Za prikaz na LCD displeju dostupni su svi znakovi engleske abecede, dok se slova kao ²to su £,¢, , ² i º mogu denirati i pohraniti u njegovu memoriju. Detalje o LCD displeju GDM1602Emoºete prona¢i u literaturi [2].

5.1 Vjeºbe - LCD displej

+5V

GND

100n

10k

+5V

1uF

22p

22p

GND

GND

+5V

+5V

+5V

GND

10k

UGND

+5V

GND

GND

VSSVDDV0RSRWE

D4D5D6D7AK

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2

12345678910111213141516

LCD

C12

C13

134 2

S5

21

Q1

AE

SPOT2

RESET

MISOMOSI

RXTX

AREF

D-D+

VUSB

SCK

PD6

PD6

PC7

PC7

PE6

PD7PD7PC6

PC6

PF1

PF1

PF0

PF0

SS

Slika 5.1: Shema spajanja LCD displeja na mikroupravlja£ ATmega32U4

62 LCD displej

Na slici 5.1 prikazana je shema spajanja LCD displeja na mikroupravlja£ ATmega32U4. Novakomponenta u ovoj vjeºbi bit ¢e LCD displej koji ima mogu¢nost prijenosa podataka pomo¢u4-bitne i 8-bitne podatkovne sabirnice. Mi ¢emo koristiti 4-bitnu podatkovnu sabirnicu radiu²tede digitalnih pinova potrebnih za komunikaciju s LCD displejom. U 4-bitnom na£inu radamikroupravlja£ je potrebno spojiti na pinove LCD displeja D4, D5, D6 i D7. Bilo koja £etiripina mikroupravlja£a moºemo spojiti na pinove D4, D5, D6 i D7. Na razvojnom okruºenju smikroupravlja£em ATmega32U4 4-bitna podatkovna sabirnica LCD displeja spojena je na pinovePC7, PC6, PD7 i PD6. Pinovi RS i E na LCD displeju upravlja£ki su pinovi te su spojeni napinove PF0 i PF1 (slika 5.1). Na LCD displej mogu¢e je zapisivati podatke i £itati podatke. Narazvojnom okruºenju s mikroupravlja£em ATmega32U4 omogu¢eno je samo zapisivanje podatakana LCD displej, ²to je sasvim dovoljno za svaku primjenu. Pin R/W spojen je na masu kakobi na LCD displeju bilo omogu¢eno samo zapisivanje podataka. Pinovi LCD displeja D4, D5,D6, D7, RS i E mogu se spojiti na bilo koji dostupni digitalni pin mikroupravlja£a, ²to ovisi ozauze¢u ostalih pinova. U ve¢ini slu£ajeva odluka o spajanju LCD displeja na digitalne pinovemikroupravlja£a dolazi na kraju, kada se na mikroupravlja£ spoje senzori i aktuatori koji koristenamjenske pinove mikroupravlja£a. Potenciometar POT2 na slici 5.1 spojen je na pin V0 na LCDdispleju, a sluºi za promjenu kontrasta LCD displeja.

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku LCD display.zip. Naradnoj povr²ini stvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢ipritom dijakriti£ke znakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢ete stvoritizvat ¢e se Ivica Ivic. Datoteku LCD display.zip raspakirajte u novostvorenu datoteku naradnoj povr²ini. Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini te dvostrukimklikom pokrenite VUB mikroracunala.atsln u datoteci \\LCD display\vjezbe. U otvorenomprojektu nalaze se sve vjeºbe koje ¢emo obraditi u poglavlju LCD displej. Vjeºbe ¢emo pisati udatoteke s ekstenzijom *.cpp.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koja moºete koristiti za provjeru ispravnostiprogramskih zadataka.

Neposredno prije nego ²to po£nemo ispisivati tekst na LCD displej pomo¢u mikroupravlja£aATmega32U4, potrebno je kongurirati pinove mikroupravlja£a koji se koriste za komunikacijus LCD displejom. U otvorenom projektu nalazi se mapa LCD u kojoj se nalazi zaglavlje lcd.h.Otvorite zaglavlje lcd.h.

Programski kod 5.1: Konguracija pinova LCD displeja u zaglavlju lcd.h

// ---------------------------------------------------------------------------

// korisnik mijenja samo konfiguraciju displeja pri kori²tenju ove biblioteke

// konfiguracija LCD displeja

#define LCD_D4_PORT PORTC // port za 4 bitnu komunikaciju - D4 na LCD -u

#define LCD_D5_PORT PORTC // port za 4 bitnu komunikaciju - D5 na LCD -u

#define LCD_D6_PORT PORTD // port za 4 bitnu komunikaciju - D6 na LCD -u

#define LCD_D7_PORT PORTD // port za 4 bitnu komunikaciju - D7 na LCD -u

#define LCD_D4_PIN PC7 // pin za 4 bitnu komunikaciju - D4 na LCD -u

#define LCD_D5_PIN PC6 // pin za 4 bitnu komunikaciju - D5 na LCD -u

#define LCD_D6_PIN PD7 // pin za 4 bitnu komunikaciju - D6 na LCD -u

#define LCD_D7_PIN PD6 // pin za 4 bitnu komunikaciju - D7 na LCD -u

#define LCD_RS_PORT PORTF // port za odabir registra - RS na LCD -u

#define LCD_RS_PIN PF0 // pin za odabir registra - RS na LCD -u

#define LCD_E_PORT PORTF // port za odobrenje upisa - EN naLCD -u

#define LCD_E_PIN PF1 // pin za odobrenje upisa - EN na LCD -u

#define LCD_LINES 2 // broj vidljivih linija na LCD -u

#define LCD_DISP_LENGTH 16 // broj vidljivih znakova po liniji LCD -u

// kraj konfiguracije LCD displeja

// ---------------------------------------------------------------------------

5.1 Vjeºbe - LCD displej 63

U programskom kodu 5.1 prikazana je konguracija pinova LCD displeja u zaglavlju lcd.h.Konguracija pinova mikroupravlja£a neizostavna je ako ºelite da LCD displej radi ispravno.U programskom kodu 5.1 nalaze se denicije koje se koriste u datoteci lcd.c u kojoj se nalazedenicije svih funkcija potrebnih za rad s LCD displejom. Komunikacija izmeu mikroupravlja£ai LCD displeja 4-bitna je. Podatkovna sabirnica kongurira se na sljede¢i na£in:

• #define LCD_D4_PORT PORTx, (x = A, B, C, D) - port mikroupravlja£a na kojem je spojenpin LCD displeja D4,

• #define LCD_D5_PORT PORTx, (x = A, B, C, D) - port mikroupravlja£a na kojem je spojenpin LCD displeja D5,

• #define LCD_D6_PORT PORTx, (x = A, B, C, D) - port mikroupravlja£a na kojem je spojenpin LCD displeja D6,

• #define LCD_D7_PORT PORTx, (x = A, B, C, D) - port mikroupravlja£a na kojem je spojenpin LCD displeja D7,

• #define LCD_D4_PIN Pxi, (x = A, B, C, D; i = 0,1,...,7) - pozicija pina mikroupravlja£akoji je spojen na pin LCD displeja D4,

• #define LCD_D5_PIN Pxi, (x = A, B, C, D; i = 0,1,...,7) - pozicija pina mikroupravlja£akoji je spojen na pin LCD displeja D5,

• #define LCD_D6_PIN Pxi, (x = A, B, C, D; i = 0,1,...,7) - pozicija pina mikroupravlja£akoji je spojen na pin LCD displeja D6,

• #define LCD_D7_PIN Pxi, (x = A, B, C, D; i = 0,1,...,7) - pozicija pina mikroupravlja£akoji je spojen na pin LCD displeja D7.

Upravlja£ki pinovi konguriraju se na sljede¢i na£in:

• #define LCD_RS_PORT PORTx, (x = A, B, C, D) - port mikroupravlja£a na kojem je spojenpin LCD displeja RS,

• #define LCD_RS_PIN Pxi, (x = A, B, C, D; i = 0,1,...,7) - pozicija pina mikroupravlja£akoji je spojen na pin LCD displeja RS,

• #define LCD_E_PORT PORTx, (x = A, B, C, D) - port mikroupravlja£a na kojem je spojenpin LCD displeja E,

• #define LCD_E_PIN Pxi, (x = A, B, C, D; i = 0,1,...,7) - pozicija pina mikroupravlja£akoji je spojen na pin LCD displeja E.

Broj redaka LCD displeja i broj znakova u jednom retku konguriraju se na sljede¢i na£in:

• #define LCD_LINES x - broj vidljivih redaka LCD displeja (naj£e²¢e je x = 1, 2, 4),

• #define LCD_DISP_LENGTH y - broj vidljivih znakova u jednom retku LCD displeja(naj£e²¢e je y = 10, 16, 20).

Na slici 5.2 prikazan je primjer spajanja LCD displeja GDM2004E na mikroupravlja£ATmega32U4.

64 LCD displej

Slika 5.2: Primjer LCD displeja GDM2004E spojenog na proizvoljan mikroupravlja£ s portom A

Ovaj LCD displej ima 4 vidljiva retka i 20 vidljivih znakova u jednom retku. Svi pinoviLCD displeja (podatkovni i upravlja£ki) spojeni su na port A mikroupravlja£a prema slici 5.2.Za ovako spojen LCD displej na mikroupravlja£ potrebno je napraviti konguraciju pinova uzaglavlju lcd.h. Konguracija pinova mikroupravlja£a spojenih na LCD displej prikazana je uprogramskom kodu 5.2.

Programski kod 5.2: Konguracija pinova LCD displeja prikazanog na slici 5.2 u zaglavljulcd.h

// ---------------------------------------------------------------------------

// korisnik mijenja samo konfiguraciju displeja pri kori²tenju ove biblioteke

// konfiguracija LCD displeja

#define LCD_D4_PORT PORTA // port za 4 bitnu komunikaciju - D4 na LCD -u

#define LCD_D5_PORT PORTA // port za 4 bitnu komunikaciju - D5 na LCD -u

#define LCD_D6_PORT PORTA // port za 4 bitnu komunikaciju - D6 na LCD -u

#define LCD_D7_PORT PORTA // port za 4 bitnu komunikaciju - D7 na LCD -u

#define LCD_D4_PIN PA3 // pin za 4 bitnu komunikaciju - D4 na LCD -u

#define LCD_D5_PIN PA4 // pin za 4 bitnu komunikaciju - D5 na LCD -u

#define LCD_D6_PIN PA5 // pin za 4 bitnu komunikaciju - D6 na LCD -u

#define LCD_D7_PIN PA6 // pin za 4 bitnu komunikaciju - D7 na LCD -u

#define LCD_RS_PORT PORTA // port za odabir registra - RS na LCD -u

#define LCD_RS_PIN PA1 // pin za odabir registra - RS na LCD -u

#define LCD_E_PORT PORTA // port za odobrenje upisa - EN na LCD -u

#define LCD_E_PIN PA2 // pin za odobrenje upisa - EN na LCD -u

#define LCD_LINES 4 // broj vidljivih linija na LCD displeju

#define LCD_DISP_LENGTH 20 // broj vidljivih znakova po liniji na LCD displeju

// kraj konfiguracije LCD displeja

// ---------------------------------------------------------------------------

5.1 Vjeºbe - LCD displej 65

Vjeºba 5.1.1

Napravite program koji ¢e na LCD displeju na po£etku prvog retka ispisati Va²e ime, a napo£etku drugog retka Va²e prezime bez dijakriti£kih znakova. Postavite ka²njenje u programuod dvije sekunde pa ispi²ite tekst Veleuciliste u Bjelovaru pravilno rasporeen u dva retkaLCD displeja. Ponovno postavite ka²njenje u programu od dvije sekunde. Navedene ispise naLCD displeju neprestano izmjenjujte. Shema spajanja LCD displeja na razvojno okruºenje smikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

U projektnom stablu otvorite datoteku vjezba511.cpp. Omogu¢ite samo prevoenjedatoteke vjezba511.cpp. Po£etni sadrºaj datoteke vjezba511.cpp prikazan je programskimkodom 5.3.

Programski kod 5.3: Po£etni sadrºaj datoteke vjezba511.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

int main(void)

inicijalizacija ();

while (1)

lcd_clrscr ();

lcd_home ();

lcd_print("Ivica\nIvic");

_delay_ms (2000);

lcd_clrscr ();

lcd_home ();

lcd_gotoxy (0,1);

lcd_print("Veleuciliste u");

lcd_gotoxy (1,3);

lcd_print("Bjelovaru");

_delay_ms (2000);

return 0;

Funkcije koje se koriste za ispisivanje teksta na LCD displej denirane su u zaglavljulcd.h. Naredba kojom uklju£ujemo zaglavlje lcd.h u datoteku koja se prevodi jest#include "LCD/lcd.h". U programskom kodu 5.3 nalazi se niz naredbi koje sluºe za rad sLCD displejom:

• lcd_init - funkcija koja inicijalizira postavke LCD displeja. U ovoj se funkciji kongurirajupodatkovni i upravlja£ki pinovi mikroupravlja£a koji komuniciraju s LCD displejom.Osim konguracije, funkcija lcd_init namje²ta 4-bitnu komunikaciju, bri²e LCD displej ipostavlja kursor u prvi redak i prvi stupac LCD displeja.

• lcd_clrscr - funkcija kojom se bri²e tekst na LCD displeju.

66 LCD displej

• lcd_home - funkcija kojom se kursor postavlja u prvi redak i prvi stupac LCD displeja.

• lcd_gotoxy - funkcija koja prima dva argumenta. Prvi argument postavlja kursor u redakx, a drugi argument postavlja kursor u stupac y. Prvi redak ima indeks x = 0, a prvistupac ima indeks y = 0.

• lcd_print - funkcija koja sluºi za ispis teksta na LCD displej. Sintaksa funkcije lcd_printidenti£na je sintaksi funkcije printf koja je standardna funkcija programskog jezika C.

Sve funkcije inicijalizacije mikroupravlja£a uvijek ¢emo pozivati u funkciji inicijalizacijau kojoj se nalazi i funkcija za inicijalizaciju LCD displeja lcd_init.

Prevedite datoteku vjezba511.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Promijenite ispis imena i prezimena na sredinu LCD displeja, a tekst Veleuciliste uBjelovaru poravnajte desno na LCD displeju.

Prevedite datoteku vjezba511.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba511.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 5.1.2

Napravite program koji ¢e na LCD displeju na po£etku prvog retka ispisatiproizvoljan cijeli broj tipa int, a na po£etku drugog retka proizvoljan realan broj tipafloat na dva decimalna mjesta. Postavite ka²njenje u programu od dvije sekunde, a zatim napo£etku prvog retka ispi²ite proizvoljan cijeli broj tipa int32_t, a na po£etku drugog retkaproizvoljan cijeli broj tipa uint32_t. Ponovno postavite ka²njenje u programu od dvije sekunde.Navedene ispise na LCD displeju neprestano izmjenjujte. Shema spajanja LCD displeja narazvojno okruºenje s mikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

U projektnom stablu otvorite datoteku vjezba512.cpp. Omogu¢ite samo prevoenjedatoteke vjezba512.cpp. Po£etni sadrºaj datoteke vjezba512.cpp prikazan je programskimkodom 5.4.

Programski kod 5.4: Po£etni sadrºaj datoteke vjezba512.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

int main(void)

inicijalizacija ();

// deklaracija podataka

int a = -123;

float b = 3.14;

lcd_clrscr ();

lcd_home ();

lcd_print("int: %d \n", a);

5.1 Vjeºbe - LCD displej 67

lcd_print("float: %0.2f ", b);

return 0;

U programskom kodu 5.4 prikazan je dio programskog koda koji samo jednom na LCD displeju gornjem retku ispi²e cijeli broj -123, a u donjem retku realan broj 3.14. Primijetite da funkcijalcd_print prima iste argumente kao i funkcija printf u programskom jeziku C. Tipovi podatakakoji se koriste u programskom razvojnom okruºenju Atmel Studio 7 (tablica 5.1) razlikuju se odtipova podataka koji se koriste na standardnim ra£unalima s operacijskim sustavom Windows.Na primjer, cjelobrojni podatak tipa int na standardnim ra£unalima ²irine je 32 bita, dok je naAVR mikroupravlja£ima ²irine 16 bitova. U programskom razvojnom okruºenju Atmel Studio7 postoje denirani tipovi podataka koji su izvedeni iz standardnih tipova podataka (tablica5.1). Na primjer, int8_t cijeli je broj s predznakom ²irine 8 bitova, dok je uint16_t cijelibroj bez predznaka ²irine 16 bitova. U tablici 5.1 prikazani su svi denirani i standardni tipovipodataka s brojem bitova koje zauzimaju u podatkovnoj memoriji, minimalnim i maksimalnimvrijednostima te formatom za ispis pomo¢u funkcije lcd_print.

Tablica 5.1: Tipovi podataka koji se koriste u programskom razvojnom okruºenjuAtmel Studio 7

Denirani tip Standardni BrojMin. Max.

printfpodatka tip podatka bitova format

- char 8 -128 127 %cint8_t signed char 8 -128 127 %duint8_t unsigned char 8 0 255 %u

int16_tint

16 -32768 32767 %dsigned int

uint16_t unsigned int 16 0 65535 %u

int32_tlong int

32 -2147483648 2147483647 %ldsigned long int

uint32_t unsigned long int 32 0 4294967295 %lu- float 32 1.175494× 10−38 3.402823× 1038 %f- double 32 1.175494× 10−38 3.402823× 1038 %f

U programski kod 5.4 ubacite while petlju u kojoj ¢e se svake dvije sekunde izmjenjivatiispis na LCD displeju prema sljede¢im uputama:

• na po£etku prvog retka ispisati proizvoljan cijeli broj tipa int, a na po£etku drugog retkaispisati proizvoljan realan broj tipa float na dva decimalna mjesta,

• postavite ka²njenje u programu od dvije sekunde,

• na po£etku prvog retka ispisati proizvoljan cijeli broj tipa int32_t, a na po£etku drugogretka ispisati proizvoljan cijeli broj tipa uint32_t,

• postavite ka²njenje u programu od dvije sekunde.

Pri izvedbi ove vjeºbe drºite se deniranih tipova podataka i printf formata iz tablice 5.1.

Prevedite datoteku vjezba512.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Ukoliko pri ispisu brojeva s posmi£nim zarezom (engl. oating point) pomo¢u funkcije lcd_printna LCD displeju umjesto ºeljenog broja dobijete ?, potrebno je omogu¢iti ispis brojeva sposmi£nim zarezom. U programskom okruºenju Atmel Studio 7 po£etne su postavke takve da

68 LCD displej

je onemogu¢en ispis brojeva s posmi£nim zarezom u funkcijama koje pozivaju funkcije sprintf(kao ²to je lcd_print) ili printf radi u²tede programske memorije mikroupravlja£a. Ako jenuºan ispis brojeva s posmi£nim zarezom, tada je potrebno napraviti sljede¢e korake:

• u programskom okruºenju Atmel Studio 7 odaberite izbornik Project → LCD Properties...ili pritisnite Alt+F7 (slika 5.3),

• u otvorenom prozoru LCD odaberite (slika 5.4):

1. Toolchain,2. General u AVR/GNU Linker,

3. ozna£ite Use vprintf librabry(-Wl,-u,vfprintf).

• u Toolchain i AVR/GNU Linker (slika 5.5):

1. odaberite Miscellaneous ,2. u tekstualni okvir Other Linker Flags upi²ite -lprintf_flt.

• snimite nove postavke programskog okruºenju Atmel Studio 7.

Slika 5.3: Printanje brojeva s posmi£nim zarezom (engl. oating point) na AVRmikroupravlja£ima u programskom okruºenju Atmel Studio 7 (1)

Slika 5.4: Printanje brojeva s posmi£nim zarezom (engl. oating point) na AVRmikroupravlja£ima u programskom okruºenju Atmel Studio 7 (2)

5.1 Vjeºbe - LCD displej 69

Slika 5.5: Printanje brojeva s posmi£nim zarezom (engl. oating point) na AVRmikroupravlja£ima u programskom okruºenju Atmel Studio 7 (3)

Ponovno prevedite datoteku vjezba512.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4 iprovjerite imate li ispravan ispis brojeva s posmi£nim zarezom.

Promijenite tipove podataka za ispis te ponovno prevedite datoteku vjezba512.cpp u strojnikod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenjus mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba512.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 5.1.3

Napravite program koji ¢e u prvom retku LCD displeja svaku sekundu ispisivati slova engleskeabecede redom A, B, C, ..., Z, A, B, ... . U drugom je retku LCD displeja po istom principupotrebno ispisivati mala slova engleske abecede svaku sekundu. Shema spajanja LCD displejana razvojno okruºenje s mikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

U projektnom stablu otvorite datoteku vjezba513.cpp. Omogu¢ite samo prevoenjedatoteke vjezba513.cpp. Po£etni sadrºaj datoteke vjezba513.cpp prikazan je programskimkodom 5.5.

Programski kod 5.5: Po£etni sadrºaj datoteke vjezba513.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

void inicijalizacija ()

70 LCD displej

int main(void)

inicijalizacija ();

char a = 'A';

while (1)

lcd_clrscr ();

lcd_home ();

lcd_print("Veliko slovo: %c\n", a);

lcd_print("Malo slovo: ");

_delay_ms (1000);

if (++a > 'Z')

a = 'A';

return 0;

U programskom kodu 5.5 nedostaje inicijalizacija LCD displeja u funkcijiinicijalizacija(). Inicijalizirajte LCD displej. Takoer, potrebno je uklju£iti zaglavljelcd.h u kojem su denirane sve funkcije za rad s LCD displejom.

U while petlji u programskom kodu 5.5 ispisuju se velika slova engleske abecede u prvomretku, dok se u drugom retku ispisuje samo tekst Malo slovo:. Nadopunite argument funkcijelcd_print("Malo slovo: "); tako da se u drugom retku ispisuju mala slova engleske abecede.Imajte na umu da su mala slova od velikih slova po ASCII kodu udaljena za 32 (npr. ASCII kodvelikog slova A je 65, a malog slova a je 97).

Engleska abeceda sadrºi 26 slova. Naredbom if (++a > 'Z') a = 'A'; provjerava se jeli ASCII kod sljede¢eg znaka ve¢i od ASCII koda slova Z. Ako je uvjet zadovoljen, varijablaa u kojoj se izmjenjuju znakovi postavlja se na vrijednost slova A. Na taj na£in ostvarili smoneprestano ispisivanje svih slova engleske abecede.

Prevedite datoteku vjezba513.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba513.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 5.1.4

Napravite program koji ¢e u prvom retku LCD displeja svaku sekundu ispisivati kut od0 do 180 , a u drugom retku sinus tog kuta na tri decimalna mjesta. Shema spajanja LCDdispleja na razvojno okruºenje s mikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

U projektnom stablu otvorite datoteku vjezba514.cpp. Omogu¢ite samo prevoenjedatoteke vjezba514.cpp. Po£etni sadrºaj datoteke vjezba514.cpp prikazan je programskimkodom 5.6.

Programski kod 5.6: Po£etni sadrºaj datoteke vjezba514.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

#include <math.h>

5.1 Vjeºbe - LCD displej 71

#define PI 3.14159

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

int main(void)

inicijalizacija ();

uint8_t kut = 0;

while (1)

lcd_clrscr ();

lcd_home ();

// ispis kuta i sinusa kuta

_delay_ms (1000);

if(++ kut >= 180)

kut = 0;

return 0;

Kada se u programu koriste matemati£ke funkcije kao ²to su sinus, kosinus, logaritam i drugo,tada je u programski kod potrebno uklju£iti standardno zaglavlje math.h. Matemati£ka funkcijasinus prima argument kuta u radijanima pa je kut u stupnjevima potrebno pretvoriti u radijane.Varijablu kut deklarirali smo kao cjelobrojnu varijablu bez predznaka ²irine 8 bitova. Ispodfunkcije lcd_home u programskom kodu 5.6 upi²ite sljede¢e tri naredbe:

• lcd_print("Kut:%u%c", kut, 223); - ispis kuta od 0 do 180 . U argumentu funkcijelcd_print pojavljuje se varijabla kut i broj 223. Broj 223 predstavlja ASCII kod znaka

na LCD displeju.

• lcd_gotoxy(1,0); - funkcija koja novi ispis postavlja na po£etak drugog retka.

• lcd_print("Sinus kuta:%.3f", sin(PI*kut/180)); - ispis sinusa kuta na tri decimalnamjesta. Pretvorba stupnjeva u radijane postignuta je relacijom π·kut

180 .

Na razli£itim LCD displejima mogu¢i su razli£iti ASCII kodovi za znak . Najjednostavnijina£in za pronalaºenje znaka jest pro¢i kroz sve ASCII znakove LCD displeja koriste¢i naredbulcd_print("ASCII:%u %c", znak, znak++); u petlji. Na ovaj na£in prezentirate sve ASCIIkodove i znakove koji su dostupni na LCD displeju.

Prevedite datoteku vjezba514.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Promijenite preciznost ispisa na vi²e decimalnih mjesta (ne vi²e od sedam). Ograni£itepromjenu kuta od 30 do 90 . Prevedite datoteku vjezba514.cpp u strojni kod i snimite ga namikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£emATmega32U4.

Zatvorite datoteku vjezba514.cpp i onemogu¢ite prevoenje ove datoteke.

72 LCD displej

Vjeºba 5.1.5

Napravite program koji ¢e na LCD displeju prikazivati sekunde, minute i sate od trenutkauklju£enja mikroupravlja£a. Svake sekunde promijenite stanje plave LED diode. Kada se pritisnetipkalo spojeno na pin PD0, neka se isklju£i plava LED dioda, a sekunde, minute i sati nekase postave na nulu. Shema spajanja LCD displeja na razvojno okruºenje s mikroupravlja£emATmega32U4 prikazana je na slici 5.1.

U projektnom stablu otvorite datoteku vjezba515.cpp. Omogu¢ite samo prevoenjedatoteke vjezba515.cpp. Po£etni sadrºaj datoteke vjezba515.cpp prikazan je programskimkodom 5.7.

Programski kod 5.7: Po£etni sadrºaj datoteke vjezba515.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

void inicijalizacija ()

output_port(DDRB ,PB7); //pin PB7 postavljen kao izlaz

input_port(DDRD ,PD0); //pin PD0 postavljen kao ulaz

set_port(PORTD ,PD0 ,1); // uklju£en pritezni otpornik na PD0

lcd_init (); // inicijalizacija LCD displeja

int main(void)

inicijalizacija ();

uint8_t sec = 0;

uint8_t min = 0;

uint16_t sat = 0;

while (1)

lcd_clrscr ();

lcd_home ();

lcd_print("%dh:%dm:%ds", sat ,min ,sec);

_delay_ms (1000);

toggle_port(PORTB ,PB7);

if(++ sec >= 60)

sec = 0;

min ++;

// napravite niz naredbi koje ¢e ra£unati minute i sate

if(get_pin(PIND ,PD0) == 0)

sec = 0;

min = 0;

sat = 0;

set_port(PORTB ,PB7 ,0);

5.1 Vjeºbe - LCD displej 73

return 0;

Cilj je ove vjeºbe napraviti prikaz vremena rada mikroupravlja£a u satima, minutama isekundama. U vjeºbi se koriste plava LED dioda i tipkalo spojeno na pin PD0, pa je uprogramskom kodu 5.7 u funkciji inicijalizacija() napravljena konguracija pinova. NaLCD displeju potrebno je prikazivati sekunde, minute i sate. Prora£un sekundi, minuta i satovamorat ¢emo napraviti na temelju ka²njenja while petlje. U while petlji postavili smo ka²njenjeod jedne sekunde. Pretpostavimo da se ostali niz naredbi u while petlji izvodi u vremenu kojeje zanemarivo naspram jedne sekunde. Svaki ¢e prolaz kroz while petlju tada trajati jednusekundu. U svakom prolazu kroz while petlju varijablu sec uve¢avamo za jedan i mijenjamostanje plave LED diode makronaredbom toggle_port. Kada broj sekundi u varijabli sec dosegne60, varijablu sec postavljamo na nulu, a varijablu min uve¢amo za jedan. Dovr²ite niz naredbikoje ¢e, kada varijabla min dosegne 60, varijablu min postaviti na nulu, a varijablu sat uve¢atiza jedan. Koliko je maksimalno vrijeme koje se moºe prikazati na LCD displeju? Za²to?

Stanje tipkala spojenog na pin PD0 provjeravamo makronaredbom get_pin. Akomakronaredba vrati vrijednost 0 (slu£aj kada je tipkalo pritisnuto), tada ¢e se isklju£iti plavaLED dioda, a varijable sec, min i sat postaviti u vrijednost 0.

Prevedite datoteku vjezba515.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba515.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 5.1.6

Napravite program koji ¢e na LCD displeju ispisivati dijakriti£ke znakove £, ¢, , ² i º. Znakovi sena LCD displeju deniraju pozivom funkcije lcd_define_char. Za deniranje znakova potrebnoje koristiti aplikaciju LCD konverter dostupnu na mreºnoj stranici www.vub.hr/mikroracunala.Shema spajanja LCD displeja na razvojno okruºenje s mikroupravlja£em ATmega32U4 prikazanaje na slici 5.1.

U projektnom stablu otvorite datoteku vjezba516.cpp. Omogu¢ite samo prevoenjedatoteke vjezba516.cpp. Po£etni sadrºaj datoteke vjezba516.cpp prikazan je programskimkodom 5.8.

Programski kod 5.8: Po£etni sadrºaj datoteke vjezba516.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

lcd_define_char (); // definiranje novih znakova

int main(void)

inicijalizacija ();

lcd_clrscr ();

lcd_home ();

lcd_char (0x00);

lcd_print("%c%c%c%c%c%c%c", 0x01 ,0x02 ,0x03 ,0x04 ,0x05 ,0x06 ,0x07);

return 0;

74 LCD displej

LCD displej ima slobodan memorijski prostor za deniranje osam vlastitih znakova. Tiznakovi nalaze se na prvih osam memorijskih lokacija LCD displeja s adresama od 0x00 do 0x07.Broj memorijske lokacije znaka na LCD displeju odgovara ASCII kodu tog znaka. Funkcijalcd_print na LCD displej ²alje putem ASCII kodova adrese memorijskih lokacija znakova kojetrebaju biti prezentirane u nekom polju LCD displeja.

U programskom kodu 5.8 nalazi se funkcija lcd_define_char. Ova funkcija denira znakovena LCD displeju odmah nakon inicijalizacije LCD displeja. Jednom kad denirate znakove uLCD displeju, oni tamo ostaju pohranjeni bez obzira na napajanje LCD displeja.

Iznad funkcije lcd_define_char pritisnite desni gumb mi²a i odaberite Goto Implementation.Otvorit ¢e se datoteka lcd.cpp u kojoj se nalazi denicija funkcije lcd_define_char. Nasamom po£etku denicije funkcije lcd_define_char nalazi se dvodimenzionalno polje prikazanoprogramskim kodom 5.9.

Programski kod 5.9: Dvodimenzionalno polje za deniranje znakova

const uint8_t symbol [8][8] = // definirajte 8 znakova

/* 0x00 */ 0x0A , 0x04 , 0x0E , 0x11 , 0x10 , 0x11 , 0x0E , 0x00 , //£

/* 0x01 */ 0x02 , 0x04 , 0x0E , 0x11 , 0x10 , 0x11 , 0x0E , 0x00 , //¢

/* 0x02 */ 0x0A , 0x04 , 0x0E , 0x10 , 0x0E , 0x01 , 0x1E , 0x00 , //²

/* 0x03 */ 0x02 , 0x07 , 0x02 , 0x0E , 0x12 , 0x12 , 0x0E , 0x00 , //

/* 0x04 */ 0x0A , 0x04 , 0x1F , 0x02 , 0x04 , 0x08 , 0x1F , 0x00 , //º

/* 0x05 */ 0x02 , 0x05 , 0x04 , 0x04 , 0x04 , 0x14 , 0x08 , 0x00 , // integral

/* 0x06 */ 0x15 , 0x1B , 0x11 , 0x0E , 0x0F , 0x0E , 0x11 , 0x1F , //£ negativ

/* 0x07 */ 0x15 , 0x1B , 0x11 , 0x0F , 0x11 , 0x1E , 0x01 , 0x1F , //² negativ

;

U programskom kodu 5.9 blok komentarima ozna£ene su memorijske lokacije deniranihznakova. Svaki je znak jedan redak u dvodimenzionalnom polju. Ako ºelite denirativlastiti znak, potrebno je koristiti aplikaciju LCD konverter dostupnu na stranici www.vub.hr/mikroracunala. Skinite aplikaciju i pokrenite ju. Aplikacija LCD konverter prikazana je na slici5.6.

Slika 5.6: Aplikacija LCD konverter

Matrica za izradu znakova na aplikaciji LCD konverter dimenzijom odgovara znaku na LCDdispleju. Aplikacija LCD konverter stvara 8 bajtova podataka u heksadecimalnom zapisu kojeje potrebno kopirati u dvodimenzionalno polje koje se nalazi u tijelu funkcije lcd_define_char(slika 5.7) u jedan od osam redaka. Kada kopiramo novi znak u funkciju lcd_define_char, mo¢i

5.1 Vjeºbe - LCD displej 75

¢emo ga koristiti pomo¢u indeksa memorijske lokacije koji je jednak indeksu retka u koji je znakkopiran.

Slika 5.7: Deniranje novog znaka

Denirane znakove moºemo ispisivati na LCD displej pomo¢u dviju funkcija:

• lcd_char(char adresa) - funkcija koja ¢e na trenutnu poziciju kursora LCD displejaispisati znak na memorijskoj lokaciji adresa.

• lcd_print("%c%c...", adresa1, adresa2, ...); - funkcija koja ¢e na LCD displejispisati znakove koji su na memorijskoj lokaciji adresa1, adresa2, ... .

Napomenuli smo da funkcija lcd_print ima istu sintaksu kao standardna funkcija printfprogramskog jezika C. Tekst koji kreira funkcija lcd_print niz je ASCII kodova koji seprosljeuju na LCD displej. U programskom jeziku C svaki je niz znakova (engl. string)zaklju£an tzv. null znakom £iji je ASCII kod jednak 0x00. Iz tog se razloga jedino memorijskalokacija 0x00 ne moºe koristiti u funkciji lcd_print jer bi prevoditelj znak s ASCII kodom 0x00shvatio kao kraj teksta koji ispisuje. Zbog toga se znak na adresi 0x00 mora ispisivati pomo¢ufunkcije lcd_char.

Pretpostavimo da je slovo £ denirano na memorijskoj lokaciji 0x01. Ako pozovemofunkciju lcd_print("Mikrora%cunala", 0x01);, na LCD dipleju ispisat ¢e se tekstMikrora£unala jer se na mjesto specikatora %c ispisuje znak koji se nalazi na adresi 0x01.

Prevedite datoteku vjezba516.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Denirajte osam vlastitih znakova, pohranite ih u dvodimenzionalno polje u funkcijilcd_define_char te ponovno prevedite datoteku vjezba516.cpp u strojni kod i snimite ga namikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£emATmega32U4.

Zatvorite datoteku vjezba516.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 5.1.7

Napravite program koji ¢e na LCD displeju svake dvije sekunde izmjenjivati tekstoveVeleu£ili²te u Bjelovaru, Stru£ni studij Mehatronika i Stru£ni studij Ra£unarstvo.Znakovi se na LCD displeju deniraju pozivom funkcije lcd_define_char. Zadeniranje znakova potrebno je koristiti aplikaciju LCD konverter dostupnu na straniciwww.vub.hr/mikroracunala. Shema spajanja LCD displeja na razvojno okruºenje smikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

76 LCD displej

U projektnom stablu otvorite datoteku vjezba517.cpp. Omogu¢ite samo prevoenjedatoteke vjezba517.cpp. Po£etni sadrºaj datoteke vjezba517.cpp prikazan je programskimkodom 5.10.

Programski kod 5.10: Po£etni sadrºaj datoteke vjezba517.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

lcd_define_char (); // definiranje novih znakova

int main(void)

inicijalizacija ();

while (1)

lcd_clrscr ();

lcd_home ();

// nastavite ...

return 0;

Na po£etku vjeºbe prvo denirajte znakove koji se koriste u ispisu tekstova Veleu£ili²teu Bjelovaru, Stru£ni studij Mehatronika i Stru£ni studij Ra£unarstvo na LCD displej.Ukoliko neki od kori²tenih znakova denirate na lokaciji 0x00, za ispis tog znaka koristite funkcijulcd_char.

U programskom kodu 5.10 potrebno je nastaviti niz naredbi koje ¢e na LCD displeju svakedvije sekunde izmjenjivati tekstove Veleu£ili²te u Bjelovaru, Stru£ni studij Mehatronikai Stru£ni studij Ra£unarstvo.

Prevedite datoteku vjezba517.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Proizvoljno ispi²ite tekst koji sadrºi dijakriti£ke znakove na LCD displej te ponovno preveditedatoteku vjezba517.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajteprogram na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba517.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 5.1.8

Napravite program koji ¢e na LCD displeju u gornjem retku ispisati tekst Materijali senalaze na web stranici:, a u donjem retku www.vub.hr/mikroracunala. Tekst je potrebnosvaku sekundu pomaknuti za jedno mjesto ulijevo. Shema spajanja LCD displeja na razvojnookruºenje s mikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

U projektnom stablu otvorite datoteku vjezba518.cpp. Omogu¢ite samo prevoenjedatoteke vjezba518.cpp. Po£etni sadrºaj datoteke vjezba518.cpp prikazan je programskimkodom 5.11.

5.1 Vjeºbe - LCD displej 77

Programski kod 5.11: Po£etni sadrºaj datoteke vjezba518.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

int main(void)

inicijalizacija ();

lcd_clrscr ();

lcd_home ();

lcd_print("Materijali se nalaze na web stranici :\n");

lcd_print("www.vub.hr/mikroracunala");

while (1)

lcd_instr(LCD_ENTRY_INC_SHIFT);

lcd_instr(LCD_MOVE_DISP_LEFT);

_delay_ms (1000);

return 0;

Tekstovi Materijali se nalaze na web stranici: i www.vub.hr/mikroracunala imajuvi²e od 16 znakova, ²to izlazi iz vidnog podru£ja LCD displeja GMD1602E. Svaki redak moºepohraniti najvi²e 40 znakova koje moºemo pomicati ulijevo ili udesno. U programskom kodu 5.11u while petlji nalaze se naredbe koje omogu¢uju pomicanje teksta i odreuju smjer pomicanja.U svrhu pomicanja teksta kori²tena je funkcija lcd_instr koja ²alje instrukcije na LCD displej.Instrukcija LCD_ENTRY_INC_SHIFT omogu¢uje pomicanje teksta na LCD displeju, dok instrukcijaLCD_MOVE_DISP_LEFT odreuje smjer pomicanja teksta ulijevo. Popis instrukcija koje se mogukoristiti za rad LCD displeja nalaze se u zaglavlju lcd.h.

Prevedite datoteku vjezba518.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba518.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

78 LCD displej

5.1.1 Zadaci - LCD displej

Zadatak 5.1.1

Napravite program u while petlji koji ¢e na LCD displeju u prvom retku desno poravnatoispisati Va²e ime, a u drugom retku desno poravnato Va²e prezime bez dijakriti£kih znakova.Postavite ka²njenje u programu od tri sekunde pa ispi²ite tekst Polozit cemo Mikroracunalapravilno rasporeen u dva retka LCD displeja. Ponovno postavite ka²njenje u programu od trisekunde. Shema spajanja LCD displeja na razvojno okruºenje s mikroupravlja£em ATmega32U4prikazana je na slici 5.1.

Zadatak 5.1.2

Napravite program koji ¢e na LCD displeju na po£etku prvog retka ispisati proizvoljan cijelibroj tipa int8_t, a na po£etku drugog retka proizvoljan realan broj tipa double na £etiridecimalna mjesta. U programu postavite ka²njenje od dvije sekunde, a zatim na po£etku prvogretka ispisati proizvoljan cijeli broj tipa int16_t, a na po£etku drugog retka proizvoljan cijelibroj tipa uint16_t. Ponovno postavite ka²njenje u programu od dvije sekunde. Navedene ispisena LCD displeju neprestano izmjenjujte. Shema spajanja LCD displeja na razvojno okruºenje smikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

Zadatak 5.1.3

Napravite program koji ¢e u prvom retku LCD displeja svake sekunde ispisivati znakovedostupne na LCD displeju. To su znakovi s ASCII kodom od 0 do 255. U drugom je retku LCDdispleja potrebno ispisati ASCII kod znaka iz prvog retka. ASCII kod ispisujte printf formatom%u. Shema spajanja LCD displeja na razvojno okruºenje s mikroupravlja£em ATmega32U4prikazana je na slici 5.1.

Zadatak 5.1.4

Napravite program koji ¢e u prvom retku LCD displeja svake sekunde ispisivati kut od0 do 180 , a u drugom retku kosinus tog kuta na dva decimalna mjesta. Shema spajanja LCDdispleja na razvojno okruºenje s mikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

Zadatak 5.1.5

Napravite program koji ¢e na LCD displeju prikazivati desetinke sekunde, sekunde, minute i sateod trenutka uklju£enja mikroupravlja£a. Svake sekunde promijenite stanje zelene LED diode.Ukoliko se pritisne tipkalo spojeno na pin PF6, neka se isklju£i zelena LED dioda, a desetinkesekunde, sekunde, minute i sati neka se postave na nulu. Shema spajanja LCD displeja narazvojno okruºenje s mikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

5.1 Vjeºbe - LCD displej 79

Zadatak 5.1.6

Napravite program koji ¢e na LCD displeju ispisivati proizvoljne znakove denirane pomo¢uaplikacije LCD konverter dostupne na mreºnoj stranici www.vub.hr/mikroracunala. Znakovi sena LCD displeju deniraju pozivom funkcije lcd_define_char. Shema spajanja LCD displejana razvojno okruºenje s mikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

Zadatak 5.1.7

Napravite program koji ¢e na LCD displeju svake dvije sekunde izmjenjivati tekstoveMIKRORAUNALO ATmega32U4 i /VJEBA.. Znakovi se na LCD displeju deniraju pozivomfunkcije lcd_define_char. Za deniranje znakova potrebno je koristiti aplikaciju LCDkonverter dostupnu na mreºnoj stranici www.vub.hr/mikroracunala. Shema spajanja LCDdispleja na razvojno okruºenje s mikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

Zadatak 5.1.8

Napravite program koji ¢e na LCD displeju u gornjem retku ispisati tekst Veleu£ili²teu Bjelovaru, a u donjem retku Stru£ni studiji Mehatronika i Ra£unarstvo. Tekst jepotrebno svake sekunde pomaknuti za jedno mjesto ulijevo. Shema spajanja LCD displeja narazvojno okruºenje s mikroupravlja£em ATmega32U4 prikazana je na slici 5.1.

80 LCD displej

Poglavlje 6

EEPROM memorija

EEPROM memorija (engl. Electrically Erasable Programmable Read-Only Memory) vrsta jetrajne memorije koja za £uvanje pohranjenih podataka ne treba elektri£no napajanje. Naj£e²¢e sekoristi za pohranu parametara sustava koji se mogu mijenjati tijekom rada sustava. Na primjer,PI regulator sustava ima dva parametra koji se u adaptivnom algoritmu regulacije mijenjaju.Ti se parametri ne smiju izgubiti bez obzira na gubitak napajanja u sustavu i bez obzira naprivremeni prestanak rada sustava. U sloºenijim se sustavima u EEPROM memoriju snimajusloºene konguracije sustava koje moraju biti dostupne prilikom inicijalizacije sustava.

6.1 Vjeºbe - EEPROM memorija

U mikroupravlja£u ATmega32U4 nalazi se EEPROM memorija veli£ine 1024 bajta. Radnije vijek EEPROM memorije do najvi²e 100 000 ciklusa pisanja i £itanja. EEPROMmemorija u mikroupravlja£u ATmega32U4 odvojena je memorija koja nije u sklopu arhitekturemikroupravlja£a ATmega32U4 te se zbog toga za adresiranje podataka koristi poseban EEPROMregistar [1].

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku EEPROM memorija.zip. Naradnoj povr²ini stvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢ipritom dijakriti£ke znakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢ete stvoritizvat ¢e se Ivica Ivic. Datoteku EEPROM memorija.zip raspakirajte u novostvorenu datotekuna radnoj povr²ini. Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini te dvostrukimklikom pokrenite VUB mikroracunala.atsln u datoteci \\EEPROM memorija\vjezbe. Uotvorenom projektu nalaze se sve vjeºbe koje ¢emo obraditi u poglavlju EEPROM memorija.Vjeºbe ¢emo pisati u datoteke s ekstenzijom *.cpp.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koje moºete koristiti za provjeru ispravnostiprogramskih zadataka.

Vjeºba 6.1.1

Napravite program u kojem ¢e se cijeli brojevi tipa int8_t, int16_t i int32_t te jedan realanbroj tipa float spremati u EEPROM memoriju na padaju¢i brid tipkala spojenog na pin PD0.Nad navedenim brojevima potrebno je izvr²iti proizvoljne jednostavne matemati£ke operacije.Brojeve je potrebno prikazivati na LCD displeju. Prilikom uklju£enja mikroupravlja£a brojevetipa int8_t, int16_t, int32_t i float inicijalizirajte £itanjem iz EEPROM memorije.

82 EEPROM memorija

U projektnom stablu otvorite datoteku vjezba611.cpp. Omogu¢ite samo prevoenjedatoteke vjezba611.cpp. Po£etni sadrºaj datoteke vjezba611.cpp prikazan je programskimkodom 6.1.

Programski kod 6.1: Po£etni sadrºaj datoteke vjezba611.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <avr/eeprom.h>

int8_t cijeli8_t;

int16_t cijeli16_t;

int32_t cijeli32_t;

float realan;

void inicijalizacija ()

input_port(DDRD ,PD0);

set_port(PORTD ,PD0 ,1);

cijeli8_t = eeprom_read_byte(addr_byte (0x00));

cijeli16_t = eeprom_read_word(addr_word (0x01));

cijeli32_t = eeprom_read_dword(addr_dword (0x03));

realan = eeprom_read_float(addr_float (0x07));

lcd_init ();

int main(void)

inicijalizacija ();

while (1)

cijeli8_t ++;

cijeli16_t +=2;

cijeli32_t +=3;

realan = 1.1 * cijeli8_t;

// ispitivanje padaju¢eg brida na PD0

if(isFalling_edge(PD , PD0) == true)

eeprom_write_byte(addr_byte (0x00),cijeli8_t);

eeprom_write_word(addr_word (0x01),cijeli16_t);

eeprom_write_dword(addr_dword (0x03),cijeli32_t);

eeprom_write_float(addr_float (0x07),realan);

lcd_clrscr ();

lcd_home ();

lcd_print("C8: %d,C16: %d", cijeli8_t , cijeli16_t);

lcd_print("\nC32: %ld ,R: %.2f", cijeli32_t , realan);

_delay_ms (1000);

return 0;

Za £itanje podataka iz EEPROM memorije i pisanje podataka u EEPROM memoriju koristese sljede¢e funkcije:

• uint8_t eeprom_read_byte(addr_byte(x)) - funkcija koja £ita cijeli broj ²irine 8 bitovas adrese x.

6.1 Vjeºbe - EEPROM memorija 83

• uint16_t eeprom_read_word(addr_word(x)) - funkcija koja £ita cijeli broj ²irine 16bitova s adrese x.

• uint32_t eeprom_read_dword(addr_dword(x)) - funkcija koja £ita cijeli broj ²irine 32bita s adrese x.

• float eeprom_read_float(addr_float(x)) - funkcija koja £ita realan broj ²irine 32 bitas adrese x.

• eeprom_write_byte(addr_byte(x), data) - funkcija koja zapisuje cijeli broj data ²irine8 bitova na adresu x.

• eeprom_write_word(addr_word(x), data) - funkcija koja zapisuje cijeli broj data ²irine16 bitova na adresu x.

• eeprom_write_dword(addr_dword(x), data) - funkcija koja zapisuje cijeli broj data²irine 32 bita na adresu x.

• eeprom_write_float(addr_float(x), data)- funkcija koja zapisuje realan broj data²irine 32 bita na adresu x.

Navedene funkcije denirane su u standardnom zaglavlju eeprom.h. Zaglavlje eeprom.hu programski je kod 6.1 uklju£eno naredbom #include <avr/eeprom.h>. Za kreiranje adresakojima se pristupa u EEPROM memoriji koriste se makronaredbe koje se nalaze u zaglavljuavrvub.h:

• addr_byte(x) - makro naredba koja inicijalizira pokaziva£ tipa uint8_t na adresu x,

• addr_word(x) - makro naredba koja inicijalizira pokaziva£ tipa uint16_t na adresu x,

• addr_dword(x) - makro naredba koja inicijalizira pokaziva£ tipa uint32_t na adresu x,

• addr_float(x) - makro naredba koja inicijalizira pokaziva£ tipa float na adresu x.

U programskom kodu 6.1 deklarirali smo tri cijela broja tipa int8_t, int16_t i int32_tte jedan realan broj tipa float. Ovi brojevi deklarirani su kao globalne varijable kako bibili dostupni svim funkcijama u datoteci vjezba611.cpp. U funkciji inicijalizacija() izEEPROM memorije £itamo podatke.

Na padaju¢i brid signala tipkala spojenog na pin PD0 trenutne vrijednosti tri cijela brojatipa int8_t, int16_t i int32_t te jednog realnog broj tipa float spremaju se u EEPROMmemoriju. Prilikom £itanja podatka i zapisivanja podatka u EEPROM memoriju moramo voditira£una o veli£ini podatka koji £itamo, odnosno zapisujemo. Jedna memorijska lokacija EEPROMmemorije ²irine je 8 bitova (1 bajt). Na primjer, ako na memorijsku lokaciju 0x01 zapisujemocijeli broj ²irine 16 bitova, tada taj broj zauzima memorijske lokacije 0x01 i 0x02 (slika 6.1).Sljede¢a slobodna lokacija za zapisivanje podataka jest 0x03. Ako na memorijsku lokaciju 0x03zapisujemo cijeli broj ²irine 32 bita, tada taj broj zauzima memorijske lokacije 0x03, 0x04, 0x05 i0x06 (slika 6.1). Sljede¢a slobodna lokacija za zapisivanje podataka jest 0x07. Podatke moramo£itati s onih memorijskih lokacija na koje smo ih zapisali. Pri tome je potrebno voditi brigu oveli£ini podatka koji £itamo.

84 EEPROM memorija

Slika 6.1: EEPROM meomorija - zauze¢e memorije

Prevedite datoteku vjezba611.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4tako da u jednom trenutku pritisnete tipkalo spojeno na pin PD0. Nakon toga isklju£ite napajanjemikroupravlja£a ATmega32U4 te ga ponovno uklju£ite. Jesu li podaci ostali sa£uvani bez obzirana nestanak napajanja?

Zatvorite datoteku vjezba611.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

6.1.1 Zadaci - EEPROM memorija

Zadatak 6.1.1

Napravite program u kojem ¢e se cijeli brojevi tipa uint8_t, uint16_t, int8_t, int16_ti uint32_t te jedan realan broj tipa double spremati u EEPROM memoriju na padaju¢ibrid tipkala spojenog na pin PD1. Nad navedenim brojevima potrebno je izvr²iti proizvoljnejednostavne matemati£ke operacije. Brojeve je potrebno prikazivati na LCD displeju. Prilikomuklju£enja mikroupravlja£a brojeve tipa uint8_t, uint16_t, int8_t, int16_t, uint32_t idouble inicijalizirajte £itanjem iz EEPROM memorije.

Poglavlje 7

Analogno-digitalna pretvorba

Analogno-digitalna pretvorba koristi se za prezentaciju analognih veli£ina s analognih senzorau mikroupravlja£u. Analogni senzori mjerni su ureaji koji naj£e²¢e neelektri£ne veli£inepretvaraju u elektri£ne (npr. temperaturu u napon, tlak u napon, vlagu u napon i drugo).Izlazni signal s analognih senzora £esto je napon u rasponu 0 - 5 V ili 0 - 10 V. Taj je naponpotrebno mjeriti i prezentirati u mikroupravlja£u. Podatak o mjerenoj veli£ini koristi se priupravljanju i nadzoru sustava. Mikroupravlja£i u pravilu imaju pinove koji se mogu koristiti zaanalogno-digitalnu pretvorbu.

U prakti£noj primjeni £esto se koriste sljede¢i analogni senzori:

• potenciometar - koristi se za mjerenje pozicije ili za namje²tanje referentnih veli£ina,

• NTC otpornik - koristi se za mjerenje temperature,

• LM35 - koristi se za mjerenje temperature s visokom precizno²¢u,

• ACS712 - koristi se za mjerenje struje,

• termopar K tipa - koristi se za mjerenje temperature,

• HR202 - koristi se za mjerenje tlaka ukoliko je poznata temperatura.

7.1 Vjeºbe - analogno-digitalna pretvorba

Mikroupravlja£ ATmega32U4 ima 12 analognih ulaza rasporeenih na sljede¢e pinove: ADC0(PF0), ADC1 (PF1), ADC4 (PF4), ADC5 (PF5), ADC6 (PF6), ADC7 (PF7), ADC8 (PD4),ADC9 (PD6), ADC10 (PD7), ADC11 (PB4), ADC12 (PB5) i ADC13 (PB6).

Kao ²to moºemo primijetiti, svi navedeni pinovi vi²enamjenski su jer osim ²to se mogu koristitikao digitalni, mogu se koristiti i kao analogni. Analogno-digitalni pretvornik u mikroupravlja£uATmega32U4 pretvara analognu vrijednost napona u digitalnu rije£ ²irine 10 bitova metodomsukcesivne aproksimacije [3]. Brzina analogno-digitalne pretvorbe moºe biti od 65 do 260 µs.Shema spajanja analognih senzora na mikroupravlja£ ATmega32U4 prikazana je na slici 7.1.Analogni senzori spojeni na mikroupravlja£ ATmega32U4 jesu potenciometar, NTC otpornik itemperaturni senzor LM35. Potenciometar je preko kratkospojnika JP1 (izmeu trnova 2 i 3)spojen na pin PF5 (ADC5), a NTC otpornik je preko kratkospojnika JP2 (izmeu trnova 1 i2) spojen na pin PF4 (ADC4). Temeraturni senzor LM35 spojen je na pin PF5 (ADC5) prekokratkospojnika JP1 (izmeu trnova 1 i 2), a koristit ¢e se u budu¢im vjeºbama.

86 Analogno-digitalna pretvorba

+5V

GND

100n

10k

+5V

1uF

10k

4k7

+5V

GND

+5V

GND

22p

22p

GND

GND

GND

+5V

330

+5V

UGND

+5V

LM35CAZ

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2

AE

SPOT1

12

NTC

R17

C12

C13

+ -

BUZZ

134 2

S5

R56

21

Q1

1 2 3

JP1

1 2 3

JP2

+VS1

GND3

VOUT 2

U1

RESET

MISOMOSI

RXTX

AREF

D-D+

VUSB

SCK

PD6

PC7

PE6

PD7

PC6

PF5

PF5

PF4

PF4

PF1PF0

SS

Slika 7.1: Shema spajanja analognih senzora na mikroupravlja£ ATmega32U4

Analogno-digitalni pretvornik ima odvojeno napajanje od mikroupravlja£a. Napajanje zanjega dovodi se na pinove mikroupravlja£a GND i AVCC (slika 7.1). Razlika napajanja naAVCC pinu i VCC pinu (napajanje mikroupravlja£a) ne smije biti ve¢a od ± 0,3 V. Na razvojnomokruºenja sa slike 3.1 napajanje mikroupravlja£a i analogno-digitalnog pretvornika isto je i iznosi5 V.

Analogno-digitalni pretvornik za pretvaranje napona u digitalnu rije£ koristireferentni naponski izvor napona VREF . Prema tome, analogna vrijednost napona urasponu [0, VREF ·(1 - 2−10)] V pretvara se u digitalnu rije£ u rasponu [0, 1023]. Za referentninaponski izvor VREF moºe biti izabran:

• napon napajanja analogno-digitalnog pretvornika AVCC,

• unutarnji napon 2,56 V,

• vanjski napon na AREF pinu mikroupravlja£a ATmega32U4.

Ako je referentni naponski izvor izabran kao AVCC ili unutarnji 2,56 V, tada senapon referentnog naponskog izvora prosljeuje na AREF pin mikroupravlja£a ATmega32U4.Referentni naponski izvor odabire se u registru ADMUX prema tablici 24-3 u literaturi [1].

Rezultat analogno-digitalne pretvorbe na pinu ADCi prikazan je relacijom 7.1:

ADCi =UADCi · 1023

VREF(7.1)

gdje je:

• ADCi - cjelobrojni rezultat analogno-digitalne pretvorbe na pinu ADCi,

• UADCi - napon na pinu ADCi,

• VREF - referentni naponski izvor.

7.1 Vjeºbe - analogno-digitalna pretvorba 87

Pretpostavimo da napon napajanja analogno-digitalnog pretvornika iznosi 5 V i da je zareferentni naponski izvor izabran napon napajanja analogno-digitalnog pretvornika AVCC (VREF= 5 V). Neka napon analognog senzora spojenog na pin ADC2 iznosi 2,14 V (UADC2 = 2,14 V).Prema relaciji (7.1), cjelobrojni rezultat analogno-digitalne pretvorbe na pinu PA2 iznosi:

ADC2 =UADC2 · 1023

5= 438. (7.2)

Pogre²ka kod prora£una digitalne rije£i ADC2 moºe biti ± 1. Analogni senzor mjeri nekuzikalnu veli£inu i na svom izlazu daje analognu vrijednost napona koji mjeri pin ADCi. Naponna pinu ADCi na temelju rezultata analogno-digitalne pretvorbe na pinu ADCi moºemo dobitipomo¢u relacije 7.3:

UADCi =ADCi · VREF

1023. (7.3)

Pretpostavimo da napon napajanja analogno-digitalnog pretvornika iznosi 5 V i da je zareferentni naponski izvor izabran napon napajanja analogno-digitalnog pretvornika AVCC (VREF= 5 V). Neka cjelobrojni rezultat analogno-digitalne pretvorbe na pinu ADC2 iznosi 765 (ADC2

=765). Prema relaciji (7.3), napon analognog senzora spojenog na pin ADC2 iznosi:

UADC2 =ADC2 · 5 V

1023= 3.739 V. (7.4)

Kada znamo napon UADCi, vrijednost zikalne veli£ine moºemo izra£unati na temeljutehni£kih specikacija analognog senzora. Frekvencija rada analogno-digitalne pretvorbe odabirese u registru ADCSRA prema tablici 24-5 u literaturi [1].

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku ADC.zip. Na radnoj povr²inistvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢i pritom dijakriti£keznakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢ete stvoriti zvat ¢e seIvica Ivic. Datoteku ADC.zip raspakirajte u novostvorenu datoteku na radnoj povr²ini.Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini te dvostrukim klikom pokreniteVUB mikroracunala.atsln u datoteci \\ADC\vjezbe. U otvorenom projektu nalaze se sve vjeºbekoje ¢emo obraditi u poglavlju Analogno-digitalna pretvorba. Vjeºbe ¢emo pisati u datotekes ekstenzijom *.cpp.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koja moºete koristiti za provjeru ispravnostiprogramskih zadataka.

Neposredno prije rada s analogno-digitalnim pretvornikom potrebno je konguriratianalogno-digitalnu pretvorbu u zaglavlju adc.h koje se nalazi u datoteci ADC. Otvoritezaglavlje adc.h. U programskom kodu 7.1 prikazan je odabir referentnog iznosa naponaanalogno-digitalne pretvorbe. Denirane su tri maske koje se dodjeljuju konstantiADC_REFERENCE. Prema programskom kodu 7.1, za referentni iznos napona odabran je naponnapajanja analogno-digitalnog pretvornika AVCC.

Programski kod 7.1: Odabir referentnog iznosa napona u zaglavlju adc.h

// definirane konstante za odabir referentnog iznosa napona

#define ADC_REFERENCE_AREF ((0 << REFS1) | (0 << REFS0)) // AREF pin

#define ADC_REFERENCE_AVCC ((0 << REFS1) | (1 << REFS0)) // AVCC pin

#define ADC_REFERENCE_RSVD ((1 << REFS1) | (0 << REFS0)) // Rezervirana

#define ADC_REFERENCE_256V ((1 << REFS1) | (1 << REFS0)) // REF je 2.56 V

// odabir referentnog iznosa napona od prethodna tri mogu¢a

#define ADC_REFERENCE ADC_REFERENCE_AVCC

88 Analogno-digitalna pretvorba

Ukoliko ºelite promijeniti referentni iznos napona na unutarnjih 2,56 V, konstantiADC_REFERENCE dodijelite konstantu ADC_REFERENCE_256V.

U programskom kodu 7.2 prikazan je odabir frekvencije rada analogno-digitalne pretvorbe.Denirano je sedam maski koje predstavljaju djelitelje frekvencije mikroupravlja£a. Maskese dodjeljuju konstanti ADC_PRESCALE. to je ve¢i djelitelj frekvencije, frekvencija je radaanalogno-digitalne pretvorbe manja, a rezultat je analogno-digitalne pretvorbe pouzdaniji.Prema programskom kodu 7.2, za djelitelj frekvencije odabran je 128.

Programski kod 7.2: Odabir frekvencije rada analogno-digitalne pretvorbe u zaglavlju adc.h

// definirani djelitelji frekvencije

#define ADC_PRESCALE_DIV2 ((0 << ADPS2) | (0 << ADPS1) | (1 << ADPS0))

#define ADC_PRESCALE_DIV4 ((0 << ADPS2) | (0 << ADPS1) | (0 << ADPS0))

#define ADC_PRESCALE_DIV8 ((0 << ADPS2) | (1 << ADPS1) | (1 << ADPS0))

#define ADC_PRESCALE_DIV16 ((1 << ADPS2) | (0 << ADPS1) | (0 << ADPS0))

#define ADC_PRESCALE_DIV32 ((1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0))

#define ADC_PRESCALE_DIV64 ((1 << ADPS2) | (0 << ADPS1) | (0 << ADPS0))

#define ADC_PRESCALE_DIV128 ((1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0))

// odabir djelitelja frkevencije

#define ADC_PRESCALE ADC_PRESCALE_DIV128

Ukoliko ºelite pove¢ati frekvenciju rada analogno-digitalne pretvorbe za dva puta, konstantiADC_PRESCALE dodijelite konstantu ADC_PRESCALE_DIV64.

Vjeºba 7.1.1

Napravite program koji ¢e na po£etku prvog retka LCD displeja ispisati rezultatanalogno-digitalne pretvorbe na pinu ADC5 (PF5), a na po£etku drugog retka naponkoji se trenutno mjeri na pinu ADC5. Analogno-digitalnu pretvorbu provodite jednom usekundi. Na pinu ADC5 spojen je potenciometar prema shemi prikazanoj na slici 7.1. Nazivnavrijednost otpora potenciometra jest 10 kΩ.

U projektnom stablu otvorite datoteku vjezba711.cpp. Omogu¢ite samo prevoenjedatoteke vjezba711.cpp. Po£etni sadrºaj datoteke vjezba711.cpp prikazan je programskimkodom 7.3.

Programski kod 7.3: Po£etni sadrºaj datoteke vjezba711.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

#include "ADC/adc.h"

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

adc_init (); // inicijalizacija AD pretvorbe

int main(void)

inicijalizacija ();

uint16_t ADC_5;

float U_ADC5; // napon na pinu ADC5

const float V_REF = 5.0; // AVCC je referentni napon

7.1 Vjeºbe - analogno-digitalna pretvorba 89

while (1)

ADC_5 = adc_read(ADC5); // ADC na kanalu ADC5

U_ADC5 = ADC_5 * V_REF / 1023; // pretvorba u napon

lcd_clrscr ();

lcd_home ();

lcd_print("ADC5 = %d", ADC_5);

lcd_print("\nUADC5 = %.2fV", U_ADC5);

_delay_ms (1000);

return 0;

Funkcije koje se koriste za analogno-digitalnu pretvorbu denirane su u zaglavljuadc.h. Naredba kojom uklju£ujemo zaglavlje adc.h u datoteku koja se prevodi jest#include "ADC/adc.h".

U programskom kodu 7.3 nalazi se niz naredbi koje sluºe za rad s analogno-digitalnimpretvornikom:

• adc_init - funkcija koja inicijalizira analogno-digitalnu pretvorbu. U ovoj sefunkciji konguriraju referentni napon analogno-digitalne pretvorbe i frekvencija radaanalogno-digitalne pretvorbe na temelju konstanti ADC_REFERENCE i ADC_PRESCALE kojesmo odabrali u zaglavlju adc.h te se omogu¢uje analogno-digitalna pretvorba.

• adc_read(uint8_t ch) - funkcija koja kao argument prima kanal analogno-digitalnepretvorbe ch na kojem ºelite napraviti analogno-digitalnu pretvorbu. Dostupnikanali istoimeni su alternativnim nazivima pinova mikroupravlja£a ATmega32U4:ADC0, ADC1, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, ADC10, ADC11, ADC12, ADC13.Povratna je vrijednost funkcije adc_read vrijednost analogno-digitalne pretvorbe na pinuADCi. Povratna je vrijednost ²irine 10 bitova. Na primjer, ako ºelimo pro£itati analognuvrijednost s pina ADC2, pozvat ¢emo funkciju adc_read(ADC2).

Za referentni iznos napona odabran je napon napajanja analogno-digitalnog pretvornikaAVCC. Taj napon spojen je i na potenciometar nazivne vrijednosti 10 kΩ. U programskomkodu 7.3 deklarirane su sljede¢e varijable:

• uint16_t ADC_5 - varijabla koja se koristi za spremanje rezultata analogno-digitalnepretvorbe na pinu ADC5,

• float U_ADC5 - napon na pinu ADC5,

• const float V_REF - referentni iznos napona AVCC = 5 V.

Sve funkcije inicijalizacije mikroupravlja£a uvijek ¢emo pozivati u funkciji inicijalizacijau kojoj se nalazi i funkcija za inicijalizaciju analogno-digitalne pretvorbe adc_init.

Funkcija adc_read(ADC5) vra¢a rezultat analogno-digitalne pretvorbe na pinu ADC5.Vrijednost napona na pinu ADC5 dobivena je pomo¢u relacije (7.3) i ispisana na LCD displej napreciznost od dva decimalna mjesta. U while petlji postavljeno je ka²njenje od jedne sekunde,²to svake sekunde osigurava novo mjerenje na pinu ADC5.

Prevedite datoteku vjezba711.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.to je sve potrebno napraviti ako ºelimo da referentni iznos napona bude unutarnjih 2,56 V?Moºe li se uop¢e prema shemi 7.1 koristiti unutarnji referentni napon iznosa 2,56 V?

Zatvorite datoteku vjezba711.cpp i onemogu¢ite prevoenje ove datoteke.

90 Analogno-digitalna pretvorba

Vjeºba 7.1.2

Napravite program koji ¢e na po£etku prvog retka LCD displeja ispisati srednju vrijednost 10uzoraka analogno-digitalne pretvorbe na pinu ADC5 uzetih u vremenu od jedne sekunde. Napo£etku drugog retka LCD displeja ispi²ite srednju vrijednost napona na pinu ADC5. Na pinuADC5 spojen je potenciometar prema shemi prikazanoj na slici 7.1. Nazivna vrijednost otporapotenciometra jest 10 kΩ.

U projektnom stablu otvorite datoteku vjezba712.cpp. Omogu¢ite samo prevoenjedatoteke vjezba712.cpp. Po£etni sadrºaj datoteke vjezba712.cpp prikazan je programskimkodom 7.4.

Programski kod 7.4: Po£etni sadrºaj datoteke vjezba712.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

// inicijalizacija AD pretvorbe

int main(void)

inicijalizacija ();

uint16_t ADC_5;

float U_ADC5; // napon na pinu ADC5

const float V_REF = 5.0; // AVCC je referentni napon

while (1)

ADC_5 = 0;

for(uint8_t i = 0; i < 10; i++)

// zbroj 10 mjerenja na pinu ADC5 u 1000 ms

_delay_ms (100);

ADC_5 = ADC_5 / 10;

// srednja vrijednost napona na pinu ADC5

lcd_clrscr ();

lcd_home ();

lcd_print("ADC5 = %d", ADC_5);

lcd_print("\nUADC5 = %.2fV", U_ADC5);

return 0;

Usrednjavanje mjernih uzoraka najjednostavniji je na£in ltriranja mogu¢ih poreme¢aja kojise mogu pojaviti na izlazu mjernih senzora. U ovoj vjeºbi napravit ¢emo usrednjavanje 10 mjernihuzoraka uzetih u jednoj sekundi.

U programskom kodu 7.4 nedostaje inicijalizacija analogno-digitalne pretvorbe u funkcijiinicijalizacija(). Inicijalizirajte analogno-digitalnu pretvorbu. Uklju£ite zaglavlja kojanedostaju.

7.1 Vjeºbe - analogno-digitalna pretvorba 91

U programskom kodu 7.4 nalazi se for petlja koja se izvodi 10 puta. U bloku naredbi forpetlje potrebno je sumirati 10 mjerenja na pinu ADC5 u jednoj sekundi. Prema tome, u jednojiteraciji for petlje potrebno je ostvariti ka²njenje od 100 ms. Po£etna vrijednost varijable ADC_5u koju ¢e se sumirati 10 mjerenja jest 0.

U for petlju upi²ite naredbu ADC_5 = ADC_5 + adc_read(ADC5); te naredbu koja ¢e u forpetlji ostvariti ka²njenje od 100 ms. Nakon ²to for petlja izvr²i 10 iteracija, u varijabli ADC_5nalazi se suma od 10 mjerenja u digitalnom zapisu. Srednju vrijednost 10 mjerenja dobit ¢emotako da vrijednost varijable ADC_5 podijelimo s 10. Prema relaciji (7.3) izra£unajte srednjuvrijednost napona na pinu ADC5 ispod naredbe ADC_5 = ADC_5 / 10;. Vrijednosti varijableADC_5 i srednje vrijednosti napona ispisuju se na LCD displej.

Prevedite datoteku vjezba712.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Promijenite broj mjerenih uzoraka u jednoj sekundi te ponovno prevedite datotekuvjezba712.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte programna razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba712.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 7.1.3

Napravite program koji ¢e na po£etku prvog retka LCD displeja ispisati vrijednost dobivenupomo¢u digitalnog ltra prvog reda:

y [k] = 0.2y [k − 1] + 0.8ADC5 [k]

gdje je:

• y[k] - ltrirana vrijednost analogno-digitalne pretvorbe u koraku k,

• y[k − 1] - ltrirana vrijednost analogno-digitalne pretvorbe u koraku k − 1 (ltriranavrijednost analogno-digitalne pretvorbe iz prethodnog mjerenja),

• ADC5[k] - rezultat analogno-digitalne pretvorbe na pinu ADC5 u koraku k.

Po£etna vrijednost digitalnog ltra prvog reda jest y[−1] = 0. Vrijeme izmeu uzimanjauzoraka k i k − 1 neka bude 100 ms. Na po£etku drugog retka ispi²ite napon dobiven natemelju ltrirane vrijednosti analogno-digitalne pretvorbe na pinu ADC5. Dodatno, napravitesignalizaciju LED diodama na sljede¢i na£in:

• ako je napon manji od 1,25 V, neka je uklju£ena samo plava LED dioda,

• ako je napon ve¢i i jednak 1,25 V i manji od 2,5 V, neka su uklju£ene plava i zelena LEDdioda,

• ako je napon ve¢i i jednak 2,5 V i manji od 3,75 V, neka su uklju£ene plava, zelena i ºutaLED dioda,

• ako je napon ve¢i i jednak 3,75 V, neka su uklju£ene sve LED diode.

Na pinu ADC5 spojen je potenciometar prema shemi prikazanoj na slici 7.1. Nazivnavrijednost otpora potenciometra je 10 kΩ.

U projektnom stablu otvorite datoteku vjezba713.cpp. Omogu¢ite samo prevoenjedatoteke vjezba713.cpp. Po£etni sadrºaj datoteke vjezba713.cpp prikazan je programskimkodom 7.5.

92 Analogno-digitalna pretvorba

Programski kod 7.5: Po£etni sadrºaj datoteke vjezba713.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

#include "ADC/adc.h"

void inicijalizacija ()

// pinovi PB7 , PB6 , PB5 i PB4 postavljeni kao izlazni

lcd_init (); // inicijalizacija LCD displeja

adc_init (); // inicijalizacija AD pretvorbe

int main(void)

inicijalizacija ();

uint16_t ADC_5;

float U_ADC5; // napon na pinu ADC5

const float V_REF = 5.0; // AVCC je referentni napon

float y[2] = 0, 0; // y[k-1], y[k]

uint8_t k = 1;

while (1)

ADC_5 = adc_read(ADC5);

y[k] = 0.2 * y[k - 1] + 0.8 * ADC_5;

U_ADC5 = y[k] * V_REF / 1023.0;

lcd_clrscr ();

lcd_home ();

lcd_print("ADC5 = %d", ADC_5);

lcd_print("\nUADC5 = %.2fV", U_ADC5);

_delay_ms (100);

y[k-1] = y[k];

if(U_ADC5 < 1.25)

set_port(PORTB ,PB4 ,1);

set_port(PORTB ,PB5 ,0);

set_port(PORTB ,PB6 ,0);

set_port(PORTB ,PB7 ,0);

if(U_ADC5 >= 1.25 && U_ADC5 < 2.5)

set_port(PORTB ,PB4 ,1);

set_port(PORTB ,PB5 ,1);

set_port(PORTB ,PB6 ,0);

set_port(PORTB ,PB7 ,0);

// nastavite za vi²e napone

return 0;

Digitalni ltar prvog reda moºe ltrirati poreme¢aje koji se pojavljuju na izlazu mjernogsenzora spojenog na analogni ulaz mikroupravlja£a. U ovoj vjeºbi koriste se LED diode za

7.1 Vjeºbe - analogno-digitalna pretvorba 93

signalizaciju. U funkciji inicijalizacija() u programskom kodu 7.5 kongurirajte izlaznepinove PB4, PB5, PB6 i PB7.

U while petlji najprije se izvr²i analogno-digitalna pretvorba na pinu ADC5. Rezultatpretvorbe sprema se u varijablu ADC_5. Nakon toga potrebno je izra£unati ltriranu vrijednostanalogno-digitalne pretvorbe pomo¢u relacije y [k] = 0.2y [k − 1] + 0.8ADC5 [k]. Napon koji¢emo prezentirati na LCD displeju dobiven je temeljem ltrirane vrijednosti analogno-digitalnepretvorbe y[k]. Napon se izra£unava pomo¢u relacije (7.3) i sprema se u varijablu U_ADC5. NaLCD displej ispisuje se ltrirana vrijednost analogno-digitalne pretvorbe y[k] i napon U_ADC5.

Ka²njenje izmeu dvaju uzorka y[k] i y[k − 1] iznosi 100 ms. Nakon ovog ka²njenja korak kpove¢ao se za jedan te vrijednost y[k] postaje y[k − 1]. U programskom kodu 7.5 to zna£i daelement polja y[k-1] poprima prethodnu vrijednost elementa polja y[k].

U nastavku programskog koda 7.5 izvedena je signalizacija pomo¢u LED dioda. Zavr²ite niznaredbi za signalizaciju LED diodama za slu£ajeve kada je napon ve¢i i jednak 2,5 V.

Prevedite datoteku vjezba713.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba713.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 7.1.4

Potenciometrom spojenim na pin ADC5 simulirajte izlazni napon senzora tlaka £ija se ovisnostnapona o tlaku moºe pro£itati s grakona na slici 7.2.

Slika 7.2: Ovisnost napona o tlaku koji djeluje na senzor

Napraviti program koji ¢e na po£etku prvog retka LCD displeja ispisati izlazni naponsenzora tlaka, a u drugom retku tlak koji se trenutno mjeri senzorom tlaka. Napinu ADC5 spojen je potenciometar prema shemi prikazanoj na slici 7.1. Nazivnavrijednost otpora potenciometra jest 10 kΩ.

U projektnom stablu otvorite datoteku vjezba714.cpp. Omogu¢ite samo prevoenjedatoteke vjezba714.cpp. Po£etni sadrºaj datoteke vjezba714.cpp prikazan je programskimkodom 7.6.

94 Analogno-digitalna pretvorba

Programski kod 7.6: Po£etni sadrºaj datoteke vjezba714.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

#include "ADC/adc.h"

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

adc_init (); // inicijalizacija AD pretvorbe

int main(void)

inicijalizacija ();

uint16_t ADC_5; // vrijednost AD pretvorbe na pinu ADC5

float U_ADC5; // napon na pinu ADC5

const float V_REF = 5.0; // AVCC je referentni napon

float u, p; // napon i tlak

while (1)

// odredite ADC_5 i U_ADC5

u = U_ADC5;

if (u <= 2.0)

p = 9 * u / 2 + 1;

else

p = 5 * u / 3 + 20.0 / 3;

//ispi²ite napon i tlak na 3 decimalna mjesta

return 0;

Ovisnost napona o tlaku koji djeluje na senzor prikazana je na slici 7.2. Pretpostavimo da jeova ovisnost denirana tehni£kim specikacijama senzora tlaka. Kao ²to se moºe vidjeti na slici7.2, ovisnost napona o tlaku aproksimacija je pravcima. Mogu se uo£iti dva slu£aja:

• 1. slu£aj: - napon se u ovisnosti o tlaku mijenja po zakonitosti pravca kroz to£keA(1 bar, 0 V) i B(10 bar, 2 V),

• 2. slu£aj: - napon se u ovisnosti o tlaku mijenja po zakonitosti pravca kroz to£keB(10 bar, 2 V) i C(15 bar, 5 V).

Kako bismo prora£unali ovisnost napona o tlaku, koristit ¢emo jednadºbu pravca kroz dvijeto£ke. Za 1. slu£aj vrijedi jednadºba pravca kroz to£ke A i B:

u− 0 =2− 0

10− 1(p− 1). (7.5)

Nakon sreivanja relacija (7.6) dobije se:

u =2

9p− 2

9. (7.6)

Prilikom mjerenja napona na mjernom senzoru tlaka nepoznanica nam je tlak. Tlak se za 1.

7.1 Vjeºbe - analogno-digitalna pretvorba 95

slu£aj moºe dobiti sreivanjem relacije (7.6):

p =9

2u+ 1. (7.7)

Za 2. slu£aj vrijedi jednadºba pravca kroz to£ke B i C:

u− 2 =5− 2

15− 10(p− 10). (7.8)

Nakon sreivanja relacija (7.8) dobije se:

u =3

5p− 4. (7.9)

Prilikom mjerenja napona na mjernom senzoru tlaka, nepoznanica nam je tlak. Tlak se za 2.slu£aj moºe dobiti sreivanjem relacije (7.9):

p =5

3u+

20

3. (7.10)

Izveli smo jednadºbe pravca koje nam daju ovisnost tlaka o naponu jer je tlak ono ²tonas zanima. Napon je samo posredna veli£ina preko koje analogno-digitalnom pretvorbomizra£unavamo tlak. U programskom kodu 7.6 odredite rezultat analogno-digitalne pretvorbena pinu ADC5 (varijabla ADC_5) pozivom funkcije adc_read. Odredite napon na pinu ADC5(varijabla U_ADC5) prema relaciji 7.1.

U uvjetnom if bloku provjeravamo je li napon na ADC5 pinu manji i jednak 2 V. Ako jenapon manji i jednak 2 V, tada tlak ra£unamo prema relaciji (7.7). Ako napon nije manji ijednak 2 V, tada tlak ra£unamo prema relaciji (7.10).

Ispi²ite na LCD displej u prvom retku napon, a u drugom retku tlak na tri decimalna mjesta.Na kraju postavite proizvoljno ka²njenje u while petlji kako bi osigurali £itljivost podataka naLCD displeju.

Prevedite datoteku vjezba714.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba714.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 7.1.5

Napravite program koji ¢e na po£etku prvog retka LCD displeja ispisati temperaturu u C kojumjeri NTC otpornik. Ovisnost otpora NTC otpornika o temperaturi u njegovoj okolini prikazanaje relacijom (7.11):

RT = RNeB(

1T− 1

TN

)(7.11)

gdje su:

• RT - otpor NTC otpornika na temperaturi T , [Ω],

• RN = 10 kΩ - otpor NTC otpornika na nazivnoj temperaturi TN , [Ω],

• T - temperatura okoline NTC otpornika, [K],

• TN = 25 C = 298,15 K - nazivna temperatura okoline NTC otpornika, [K],

• B = 3435 K - konstanta ovisna o materijalu NTC otpornika, [K].

96 Analogno-digitalna pretvorba

U programu napravite dio koda za signalizaciju LED diodama na sljede¢i na£in:

• ako je temperatura manja od 25 C, neka je uklju£ena samo plava LED dioda,

• ako je temperatura ve¢a i jednaka 25 C i manja od 27,5 C, neka su uklju£ene plava izelena LED dioda,

• ako je temperatura ve¢a i jednaka 27,5 C i manja od 30 C, neka su uklju£ene plava, zelenai ºuta LED dioda,

• ako je temperatura ve¢a i jednaka 30 C, neka su uklju£ene sve LED diode.

NTC otpornik spojen je u naponskom djelilu s otporom R = 4,7 kΩ prema shemi prikazanojna slici 7.1. Pad napona na NTC otporniku mjeri se pomo¢u pina ADC4.

U projektnom stablu otvorite datoteku vjezba715.cpp. Omogu¢ite samo prevoenjedatoteke vjezba715.cpp. Po£etni sadrºaj datoteke vjezba715.cpp prikazan je programskimkodom 7.7.

Programski kod 7.7: Po£etni sadrºaj datoteke vjezba715.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

#include "ADC/adc.h"

void inicijalizacija ()

// pinovi PB7 , PB6 , PB5 i PB4 postavljeni kao izlazni

lcd_init (); // inicijalizacija LCD displeja

adc_init (); // inicijalizacija AD pretvorbe

int main(void)

inicijalizacija ();

uint16_t ADC_4; // vrijednost AD pretvorbe na pinu ADC4

float T; // temperatura

while (1)

ADC_4 = adc_read(ADC4);

// dodajte relaciju za temperaturu NTC otpornika

lcd_clrscr ();

lcd_home ();

lcd_print("T = %0.2f%cC\n", T, 223);

// signalizacija po istom principu kao u datoteci vjezba713.c

_delay_ms (1000);

return 0;

Svojstvo NTC (engl. Negative Temperature Coecient) otpornika jest da se porastomtemperature u okolini NTC otpornika njegov otpor smanjuje, a smanjenjem temperature njegov

7.1 Vjeºbe - analogno-digitalna pretvorba 97

se otpor pove¢ava. NTC otpornici £esto se koriste u praksi za mjerenje temperature jer im jecijena niska. Ovisnost otpora NTC otpornika o temperaturi u njegovoj okolini eksponencijalnaje. Temperatura se u relaciji (7.11) nalazi u nazivniku eksponenta. Cilj nam je temperaturu urelaciji (7.11) izraziti preko otpora NTC otpornika.

NTC otpornik spojen je u djelilu napona s otpornikom R = 4,7 kΩ prema slici 7.3.

AREF

(5 V)

R

TR4ADCUNTC

Slika 7.3: NTC otpornik spojen u djelilu napona s otpornikom R = 4.7 kΩ

Napon UADC4 na pinu ADC4 prema slici 7.3 jedanak je:

UADC4 =RT

RT +R5 (7.12)

Iz relacije (7.11) potrebno je izraziti temperaturu T preko otpora NTC otpornika. Akorelaciju (7.11) logaritmiramo prirodnim logaritmom ln, dobit ¢emo sljede¢u relaciju:

RT = RNeB(

1T− 1

TN

)/ : RN ⇒

RTRN

= eB(

1T− 1

TN

)/ ln ()⇒

ln

(RTRN

)= B

(1

T− 1

TN

)⇒ B

T= ln

(RTRN

)+

B

TN.

(7.13)

Napravimo sada recipro£nu vrijednost izvedene relacije (7.13) i pomnoºimo ju s B:

T =B

ln(RTRN

)+ B

TN

. (7.14)

Relacija (7.14) predstavlja funkcijsku ovisnost temperature o otporu NTC otpornika koji jejedina nepoznanica u ovoj relaciji. Izrazimo sada vrijednost otpora NTC otpornika iz relacije(7.12):

UADC4 =RT

RT +R5/ · (RT +R)⇒ (RT +R)UADC4 = RT 5

RT =UADC4

5− UADC4R

(7.15)

Napon UADC4 moºemo izra£unati pomo¢u analogno-digitalne pretvorbe prema relaciji (7.3).Vrijednost napona od 5 V u relaciji (7.15) prema relaciji (7.3) zamijenit ¢emo digitalnomvrijedno²¢u 1023. Prema tome, relaciju (7.15) moºemo zapisati u sljede¢em obliku:

RT =ADC4

1023−ADC4R. (7.16)

98 Analogno-digitalna pretvorba

Otpor NTC otpornika iz relacije (7.16) uvrstit ¢emo u relaciju (7.14):

T =B

ln(

ADC41023−ADC4

RRN

)+ B

TN

. (7.17)

Pravilima logaritmiranja1 moºemo pojednostavniti relaciju (7.17):

T =B

ln(

ADC41023−ADC4

)+ ln

(RRN

)+ B

TN

. (7.18)

Pojednostavljena relacija (7.19) manje je zahtjevna za izra£un u mikroupravlja£u jer smodio prora£una napravili ru£no. U praksi se preporu£uje pojednostavljenje matemati£kih relacijakako bi mikroupravlja£ brºe prora£unao te relacije. U relaciji (7.19) potrebno je uvrstiti poznateparametre, a to su otpor naponskog djelila R = 4,7 kΩ, nazivni otpor NTC otpornika RN = 10kΩ, nazivna temperatura TN = 298,15 K i konstanta B = 3435 K:

T =3435

ln(

ADC41023−ADC4

)+ 10, 861

. (7.19)

Dobivena temperatura u relaciji (7.19) izraºena je u K. Temperatura u C prikazana jerelacijom (7.20).

T =3435

ln(

ADC41023−ADC4

)+ 10, 861

− 273, 15 (7.20)

Relacija (7.20) kona£na je i potrebno ju je zapisati u sintaksi programskog jezika C/C++ uprogramski kod 7.7. Funkcija koja u programskom jeziku C ra£una prirodni logaritam ln() jestlog(double). U programskom je kodu napisana naredba za analogno-digitalnu pretvorbu napinu ADC4, a rezultat pretvorbe sprema se u varijablu ADC_4.

esto se u prakti£noj primjeni senzora najprije mora provesti prora£un koji ¢e nam omogu¢itiprezentaciju zikalne veli£ine koju senzor mjeri. Prethodni prora£un najbolji je primjer toga.

Za signalizaciju LED diodama potrebno je kongurirati izlaze PB4, PB5, PB6 i PB7.Napravite niz naredbi koje ¢e LED diodama signalizirati vrijednost temperature prema uputamaiz vjeºbe. Signalizacija je sli£na onoj u vjeºbi 7.1.3. Nakon signalizacije, ostvarili smo ka²njenjeprograma od jedne sekunde.

Prevedite datoteku vjezba715.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba715.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

1Logaritam umno²ka dvaju operanada jednak je sumi logaritama tih dvaju operanada, ln(ab) = ln a+ ln b.

7.1 Vjeºbe - analogno-digitalna pretvorba 99

7.1.1 Zadaci - analogno-digitalna pretvorba

Zadatak 7.1.1

Napravite program koji ¢e na po£etku prvog retka LCD displeja ispisati rezultatanalogno-digitalne pretvorbe na pinu ADC5, a na po£etku drugog retka otpor potenciometraspojenog na pin ADC5. Nazivna vrijednost otpora potenciometra jest 10 kΩ. Analogno-digitalnupretvorbu provodite jednom u sekundi. Na pinu ADC5 spojen je potenciometar prema shemiprikazanoj na slici 7.1.

Zadatak 7.1.2

Napravite program koji ¢e na po£etku prvog retka LCD displeja ispisati srednju vrijednost²est uzoraka analogno-digitalne pretvorbe na pinu ADC5 uzetih u vremenu od 900 ms. Napo£etku drugog retka LCD displeja ispi²ite srednju vrijednost napona na pinu ADC5. Na pinuADC5 spojen je potenciometar prema shemi prikazanoj na slici 7.1. Nazivna vrijednost otporapotenciometra jest 10 kΩ.

Zadatak 7.1.3

Napravite program koji ¢e na po£etku prvog retka LCD displeja ispisati vrijednost dobivenupomo¢u digitalnog ltra drugog reda:

y [k] = 0.2y [k − 1] + 0.1y [k − 2] + 0.7ADC5 [k]

gdje je:

• y[k] - ltrirana vrijednost analogno-digitalne pretvorbe u koraku k,

• y[k − 1] - ltrirana vrijednost analogno-digitalne pretvorbe u koraku k − 1,

• y[k − 2] - ltrirana vrijednost analogno-digitalne pretvorbe u koraku k − 2,

• ADC5[k] - rezultat analogno-digitalne pretvorbe na pinu ADC5 u koraku k.

Po£etne vrijednosti digitalnog ltra drugog reda jesu y[−1] = 0 i y[−2] = 0. Vrijeme izmeuuzimanja uzoraka k i k−1 neka bude 200 ms. Na po£etku drugog retka ispi²ite napon dobiven natemelju ltrirane vrijednosti analogno-digitalne pretvorbe na pinu ADC5. Dodatno, napravitesignalizaciju LED diodama na sljede¢i na£in:

• ako je napon manji od 1,25 V, neka je uklju£ena samo crvena LED dioda,

• ako je napon ve¢i i jednak 1,25 V i manji od 2,5 V, neka su uklju£ene crvena i ºuta LEDdioda,

• ako je napon ve¢i i jednak 2,5 V i manji od 3,75 V, neka su uklju£ene crvena, ºuta i zelenaLED dioda,

• ako je napon ve¢i i jednak 3,75 V, neka su uklju£ene sve LED diode.

100 Analogno-digitalna pretvorba

Na pinu ADC5 spojen je potenciometar prema shemi prikazanoj na slici 7.1. Nazivnavrijednost otpora potenciometra jest 10 kΩ.

Zadatak 7.1.4

Potenciometrom spojenim na pin ADC5 simulirajte izlazni napon senzora tlaka £ija se ovisnostnapona o tlaku moºe pro£itati s grakona na slici 7.4.

Slika 7.4: Ovisnost napona o tlaku koji djeluje na senzor

Napravite program koji ¢e na po£etku prvog retka LCD displeja ispisati izlazni napon senzoratlaka, a u drugom retku tlak koji se trenutno mjeri senzorom tlaka. Na pinu ADC5 spojen jepotenciometar prema shemi prikazanoj na slici 7.1. Nazivna vrijednost otpora potenciometrajest 10 kΩ.

Zadatak 7.1.5

Napravite program koji ¢e na po£etku prvog retka LCD displeja ispisati temperaturu u K kojumjeri NTC otpornik, a na po£etku drugog retka otpor NTC otpornika. Ovisnost otpora NTCotpornika o temperaturi u njegovoj okolini prikazana je relacijom (7.21):

RT = RNeB(

1T− 1

TN

)(7.21)

gdje su:

• RT - otpor NTC otpornika na temperaturi T , [Ω],

• RN = 1kΩ - otpor NTC otpornika na nazivnoj temperaturi TN , [Ω],

• T - temperatura okoline NTC otpornika, [K],

• TN = 25 C = 298,15 K - nazivna temperatura okoline NTC otpornika, [K],

• B = 3435 K - konstanta ovisna o materijalu NTC otpornika, [K].

NTC otpornik spojen je u naponskom djelilu s otporom R = 10 kΩ prema shemi prikazanojna slici 7.1. Pad napona na NTC otporniku mjeri se pomo¢u pina ADC4.

Poglavlje 8

Tajmeri i broja£i

Tajmer (engl. timer) vaºan je dio svakog mikroupravlja£a i ve¢ina mikroupravlja£a imajedan ili vi²e tajmera s rezolucijom od 8 i/ili 16 bitova [4]. Primjena tajmera ²iroka je, a naj£e²¢ese koriste za sinkronizaciju dogaaja u mikroupravlja£u, generiranje periodi£nih valnih oblika,uzimanje mjernih uzoraka u to£nim vremenskim trenucima i u digitalnoj izvedbi PID regulatora.Tajmer je u osnovi broja£ (engl. counter) koji pove¢ava ili smanjuje svoj iznos za 1 na svaki k-ti1

impuls radnog takta. Tajmer i broja£ na hardverskoj su razini isti sklop koji se moºe konguriratiili kao tajmer ili kao broja£. Ako je izvor impulsa k-ti impuls radnog takta, onda je ovaj sklopkonguriran kao tajmer, a ako je izvor impulsa vanjski ureaj, tada je ovaj sklop kongurirankao broja£.

Rezolucija tajmera i broja£a jest broj bitova u registru koji se koriste za brojanje impulsas izvora impulsa. Ako je rezolucija tajmera i broja£a n, tada se vrijednosti registra u kojem sebroje impulsi kre¢u u rasponu [0, 2n - 1]. Na primjer, ako je rezolucija tajmera i broja£a 8, tadase vrijednosti njihova registra kre¢u u rasponu od [0, 255]. Na svaki impuls s izvora impulsavrijednost se u registru pove¢ava ili smanjuje za 1. Ako je vrijednost registra tajmera 255 injegova se vrijednost pove¢ava sa svakim impulsom, tada ¢e nakon sljede¢eg impulsa njegovavrijednost biti 0. U prijelazu iz 255 u 0 dogodio se preljev (engl. overow) jer broj 256 ne staneu registar ²irine 8 bitova. Tajmeri u ve¢ini mikroupravlja£a generiraju prekid u trenutku kadase dogodi preljev. Prekid (engl. interrupt) je mehanizam mikroupravlja£a koji omogu¢ava da sena neke dogaaje odgovori u trenutku kada se oni dogode iako se u glavnom programu izvodiprogramski kod. Generiranje prekida u trenutku preljeva omogu¢uje da se dio programskog kodaizvodi u jednakim vremenskim razmacima.

Poziv prekidne rutine u trenutku kada se dogodio prekid ilustriran je slikom 8.1. U glavnomprogramu u beskona£noj while petlji izvodi se dio programskog koda koji na LCD displejuprikazuje tlak i napon senzora tlaka spojenog na pin PA5. Prekid se moºe dogoditi u bilo kojemtrenutku izvoenja beskona£ne while petlje. im se dogodi prekid, poziva se prekidna rutinau kojoj se nalazi dio programskog koda. Nakon ²to se izvede programski kod prekidne rutine,mikroupravlja£ nastavlja izvoditi programski kod na mjestu gdje je prekidna rutina pozvana (slika8.1). Mikroupravlja£i imaju vi²e izvora prekida. Ukoliko se istovremeno dogodi vi²e prekida srazli£itih izvora, prekidi se izvode prema prioritetu.

Tajmeri u mikroupravlja£u mogu mjeriti vrijeme jer broje impulse dobivene na temelju radnogtakta £ija je frekvencija poznata. Radni takt mogu¢e je sklopovski podijeliti brojem k, (k = 1,2, 8, 32, 64, 128, 256, 1024). Ukoliko je radni takt sklopovski podijeljen brojem k, tada sevrijednost registra u tajmeru pove¢ava ili smanjuje za 1 na svaki k-ti impuls radnog takta. Sklopza dijeljenje frekvencije radnog takta zove se djelitelj frekvencije radnog takta (engl. prescaler).

1Broj k ovisi o mikroupravlja£u, a naj£e²¢e je k = 1, 2, 8, 32, 64, 128, 256, 1024.

102 Tajmeri i broja£i

Glavni program

(beskonačna petlja)

Prekidna rutina

Točka u kojoj se dogodio prekid

Slika 8.1: Poziv prekidne rutine u trenutku kada se dogodio prekid

Mikroupravlja£ ATmega32U4 ima £etiri tajmera i broja£a od kojih ¢emo tri dolje navedenakoristiti u svrhu vjeºbi:

• Timer/Counter0 - tajmer i broja£ rezolucije 8 bitova s rasponom brojanja od [0, 255],

• Timer/Counter1 - tajmer i broja£ rezolucije 16 bitova s rasponom brojanja od [0, 65535],

• Timer/Counter3 - tajmer i broja£ rezolucije 16 bitova s rasponom brojanja od [0, 65535].

Rad tajmera i broja£a objasnit ¢emo na sklopu Timer/Counter0. U nastavku teksta tajmeri broja£ s indeksom 0 zvat ¢emo izvornim imenom Timer/Counter0 iz literature [1]. Na slici 8.2prikazana je blokovska shema za sklop Timer/Counter0 rezolucije 8 bitova.

Sklop Timer/Counter0 ima pet registara sa sljede¢im funkcijama [1]:

• TCNT0 - (engl. Timer/Counter Register), registar ²irine 8 bitova u kojem se vrijednostuve¢ava ili smanjuje za 1. Raspon vrijednosti u registru jest od [0, 255]. Mogu¢e ga jeprogramski £itati i u njega zapisivati vrijednosti putem podatkovne sabirnice.

• OCR0A, OCR0B - (engl. Output Compare Register), registri ²irine 8 bitova £ije se vrijednostimogu usporeivati s registrom TCNT0. Raspon vrijednosti u registru jest od [0, 255]. Mogu¢ega je programski £itati i u njega zapisivati vrijednosti putem podatkovne sabirnice.

• TCCR0A, TCCR0B - (engl. Timer/Counter Control Register), registri kojim se kongurirarad sklopa Timer/Counter0.

103

Slika 8.2: Blokovska shema za sklop Timer/Counter0 rezolucije 8 bitova

Na blokovskoj shemi sklopa Timer/Counter0 nalaze se sljede¢i signali:

• broji - uve¢aj ili smanji vrijednost registra TCNT0 za 1,

• o£isti - postavi vrijednost registra TCNT0 na 0,

• smjer - uve¢avaj ili smanjuj za 1,

• taktT0 - izvor impulsa na temelju kojih se vrijednost registra TCNT0 uve¢ava ili smanjujeza 1,

• DNO - (engl. BOTTOM) signalizira da je vrijednost registra TCNT0 0x00, a koristi se zageneriranje prekida kada se dogodi preljev,

• VRH - (engl. TOP) signalizira da je vrijednost registra TCNT0 postigla maksimalnu vrijednostkoja moºe biti 255 ili vrijednost koja se nalazi u registru OCR0A.

Sklop Timer/Counter0 generira dvije vrste prekida:

• TOV0 - prekid koji se generira kada registar TCNT0 prelazi iz vrijednosti 255 u 0,

• OC0A, OC0B - prekidi koji se generiraju kada je vrijednost registra TCNT0 jednakavrijednosti registara OCR0A, OCR0B.

104 Tajmeri i broja£i

Registri kojima se kongurira rad sklopa Timer/Counter0 prikazani su na slikama 8.3 i 8.4.Svaki bit u registrima TCCR0A i TCCR0B ima svoju funkciju i odreuje rad sklopa Timer/Counter0.

Bit 7 6 5 4 3 2 1 0

Registar TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 WGM01 WGM00

Slika 8.3: Registar TCCR0A

Bit 7 6 5 4 3 2 1 0

Registar TCCR0B FOC0A FOC0B WGM02 CS02 CS01 CS00

Slika 8.4: Registar TCCR0B

Na slici 8.2 prikazan je blok Izbor izvora impulsa. Izvor impulsa mogu biti ili impulsinakon djelitelj frekvencije radnog takta ili impulsi koji se dovode na pin PD7 (T0). Ponovnomoºemo primijetiti da pin PD7 ima alternativnu funkciju. Izvor impulsa odabire se u registruTCCR0B namje²tanjem bitova CS02, CS01 i CS00 prema tablici 8.1. Prvih ²est redaka u tablici8.1 konguriraju sklop Timer/Counter0 kao tajmer, a zadnja dva retka konguriraju sklopTimer/Counter0 kao broja£. Radni takt deniran je Fuse bitovima i konstantom F_CPU.

Tablica 8.1: Izbor izvora impulsa sklopa Timer/Counter0 [1]

CS02 CS01 CS00 Izvor impulsa

0 0 0 Nema impulsa, Timer/Counter0 isklju£en

0 0 1 F_CPU

0 1 0 F_CPU/8

0 1 1 F_CPU/64

1 0 0 F_CPU/256

1 0 1 F_CPU/1024

1 1 0 Na padaju¢i brid signala pina T0, uve¢aj TCNT0 za 1

1 1 1 Na rastu¢i brid signala pina T0, uve¢aj TCNT0 za 1

etiri su osnovna na£ina rada tajmera:

• normalan na£in rada,

• CTC (engl. Clear Timer on Compare Match) na£in rada,

• Fast PWM (engl. Pulse Width Modulation) na£in rada,

• Phase Correct PWM na£in rada.

U vjeºbama ¢emo koristiti normalan na£in rada, Fast PWM i Phase Correct PWM na£in radate ¢emo ih detaljnije opisati u nastavku. Opis preostalih na£ina rada nalazi se u literaturi [1] nastranici 98. Na£in rada sklopa Timer/Counter0 odabire se pomo¢u bitova WGM02, WGM01 i WGM00u registrima TCCR0A i TCCR0B prema tablici 8.2. Navedenu tablicu koristit ¢emo za konguriranjena£ina rada tajmera.

8.1 Vjeºbe - Normalan na£in rada tajmera 105

Tablica 8.2: Odabir na£ina rada tajmera

WGM02 WGM01 WGM00 Na£in rada Vr²na vrijednost broja£a

0 0 0 Normalni na£in rada 0xFF

0 0 1 Phase Correct na£in rada 0xFF

0 1 0 CTC na£in rada OCR0A

0 1 1 Fast PWM na£in rada 0xFF

1 0 0 Rezervirano

1 0 1 Phase Correct na£in rada OCR0A

1 1 0 Rezervirano

1 1 1 Fast PWM na£in rada OCR0A

8.1 Vjeºbe - Normalan na£in rada tajmera

Normalan na£in rada tajmera najjednostavniji je na£in rada. U ovom na£inu rada uvijek sevrijednost registra TCNT0 pove¢ava za 1. Kada vrijednost u registru TCNT0 prelazi iz 255 u 0,generira se prekid TOV0 koji poziva prekidnu rutinu.

Prekidne se rutine u razvojnom programskom okruºenju Atmel Studio 7 pozivajumakronaredbom ISR(vector) (engl. Interrupt Service Routines). Ova makronaredba zahtijevauklju£enje zaglavlja #include <avr/interrupt.h>. Makronaredba ISR kao argument primaprekidni vektor koji je deniran tablicom 9-1 u literaturi [1]. Prekidni vektor za preljev uregistru TCNT0 naziva se TIMER0_OVF_vect. Da bi se prekid mogao generirati potrebno jeglobalno omogu¢iti prekide te omogu¢iti svaki prekid zasebno. Globalno se prekidi omogu¢ujumakronaredbom sei(), a onemogu¢uju makronaredbom cli(). Takoer, ako koristite zaglavljekoje je pripremio autor (#include "Interrupt/interrupt.h" ), globalno se prekidi moguomogu¢iti funkcijom interrupt_enable(), a onemogu¢iti funkcijom interrupt_disable().

Generiranje prekida za preljev u registru TCNT0 moºemo omogu¢iti u registru TIMSK0 takoda bit 0 (konstanta za bit 0 je TOIE0) postavimo u 1. Primjer konguracije tajmera prikazan jeu programskom kodu 8.1.

Programski kod 8.1: Konguracija tajmera za normalan na£in rada

sei(); // globalno omogu¢en prekid

TIMSK0 |= (1 << TOIE0); // omogu¢enje prekida za timer0

TCCR0A |= (0 << WGM01) | (0 << WGM00); // Normalan na£in rada

TCCR0B |= (0 << WGM02); // Normalan na£in rada

TCCR0B |= (1 << CS02) | (0 << CS01) | (0 << CS00); // F_CPU /256

Makronaredbom sei() globalno smo omogu¢ili prekide, a naredbomTIMSK0 |=(1<<TOIE0); prekid koji se generira kada se u registru TCNT0 dogodi preljev. Normalanna£in rada tajmera omogu¢ili smo naredbama TCCR0A |= (0 << WGM01)| (0 << WGM00); iTCCR0B |= (0 << WGM02); prema tablici 8.2. Pretpostavimo da je frekvencija radnog takta 16MHz. Kada ne bi bilo dijeljenja frekvencije radnog takta, registar TCNT0 svoju bi vrijednostuve¢ao za 1 ukupno 16 milijuna puta u jednoj sekundi i generirao 62500 prekida preljevomregistra TCNT0. U registar TCCR0B na mjesto zadnjih triju bitova upisana je vrijednost 0x04naredbom TCCR0B |= (1 << CS02)| (0 << CS01)| (0 << CS00);. Prema tablici 8.1, za ovukombinaciju bitova CS02, CS01 i CS00 djelitelj frekvencije radnog takta je 256. Registar TCNT0u ovom slu£aju svoju vrijednost uve¢ava za jedan na svaki 256. impuls radnog takta. Na tajna£in registar TCNT0 svoju ¢e vrijednost uve¢ati za 1 samo 16000000/256 = 62500 puta u jednoj

106 Tajmeri i broja£i

sekundi i generirati 244 prekida. Vrijeme izmeu dvaju prekida bilo bi 1 s/244 = 0.0041 s = 4.1ms, a ono se op¢enito moºe izra£unati pomo¢u sljede¢e relacije (vrijedi za tajmer rezolucije 8bitova):

tT0 =PRESCALER

F_CPU· (256− TCNT00) (8.1)

gdje je:

• tT0 - vrijeme izmeu dvaju prekida, [s],

• PRESCALER - djelitelj frekvencije radnog takta,

• F_CPU - frekvencija radnog takta mikroupravlja£a,

• 256 - 28 gdje broj 8 predstavlja rezoluciju sklopa Timer/Counter0 (za Timer/Counter1 iTimer/Counter3 umjesto 256 potrebno je staviti 216 = 65536),

• TCNT00 - po£etna vrijednost registra TCNT0. Razlika 256 - TCNT00 odgovara brojuimpulsa koji na frekvenciji radnog takta uz zadani djelitelj frekvencije radnog takta trajetT0 vremena.

U normalnom na£inu rada tajmer uve¢ava svoju vrijednost za 1 na svaki impuls koji dolazis djelitelja frekvencije radnog takta. Ako vrijeme izmeu dvaju prekida traje 100 impulsa, tadapo£etna vrijednost registra TCNT0 nije 100, ve¢ 256 - 100 = 156. Budu¢i da tajmer uve¢ava svojuvrijednost za 1, tada ¢e od po£etne vrijednosti registra TCNT0 ( TCNT00 = 156) do prelaska iz255 u 0 (preljev) pro¢i to£no 100 impulsa. Kada je po£etna vrijednost registra TCNT0 jednaka 0,vrijeme izmeu dvaju prekida traje 256 impulsa.

Primjena ove vrste prekida jest pozivanje prekidne rutine svakih tT0 vremena (npr. potrebnoje mjeriti temperaturu pe¢i na kruta goriva svakih 10 ms). Varijable u relaciji (8.1) koje moºemomijenjati jesu PRESCALER, F_CPU i TCNT00. Frekvenciju radnog takta u pravilu nemijenjamo, ve¢ ju ksiramo na samom po£etku razvoja programskog rje²enja. Ono ²to moºemomijenjati jesu varijable PRESCALER i TCNT00. Kako bismo dobili ºeljeno vrijeme izmeudvaju prekida, potrebno je iz relacije (8.1) izra£unati TCNT00:

TCNT00 = 256− tT0 ·F_CPU

PRESCALER. (8.2)

U relaciji (8.2) potrebno je prona¢i najmanji djelitelj frekvencije radnog takta za koji ¢evrijediti da po£etna vrijednost registra TCNT0 nije manja od 0. Pretpostavimo da je frekvencijaradnog takta 16 MHz. Poku²ajmo u relaciju (8.2) uvrstiti PRESCALER = 256 (tT0 = 10 ms= 0,01 s):

TCNT00 = 256− 0, 01 · 16000000

256= −369. (8.3)

Po£etna vrijednost registra TCNT0 prema (8.3) manja je od 0 pa je potrebno poku²ati s ve¢imdjeliteljem frekvencije radnog takta (npr. PRESCALER = 1024):

TCNT00 = 256− 0, 01 · 16000000

1024= 99, 75 ≈ 100. (8.4)

Po£etna vrijednost registra TCNT0 prema (8.4) ve¢a je od 0 pa je prora£un gotov. Uprogramskom kodu 8.1 sada moramo zamijeniti naredbu za namje²tanje djelitelj frekvencijeradnog takta s naredbom TCCR0B |= (1 << CS02)| (0 << CS01)| (1 << CS00); prema tablici

8.1 Vjeºbe - Normalan na£in rada tajmera 107

(8.1). Rezultat nije cijeli broj pa ga je potrebno zaokruºiti na najbliºi cijeli broj. Uvrstimo urelaciju 8.1 po£etnu vrijednost registra TCNT0 koju smo izra£unali:

tT0 =1024

16000000· (256− 100) = 9, 98ms. (8.5)

Stvarno vrijeme izmeu dvaju prekida ne¢e biti 10 ms, ve¢ 9,98 ms. Razlog tome jestnedovoljna rezolucija sklopa Timer/Counter0. U programskom kodu 8.2 prikazana je prekidnarutina za prekidni vektor TIMER0_OVF_vect. U ovoj prekidnoj rutini svakih se 20 ms mjeritemperatura pe¢i na kruta goriva. Prekid se javlja onog trenutka kada doe do preljeva uregistru TCNT0, odnosno kada vrijednost registra TCNT0 prelazi iz 255 u 0. im doe do preljeva,poziva se prekidna rutina ISR(TIMER0_OVF_vect) u kojoj se po£etna vrijednost registra TCNT0softverski postavlja u prora£unatu vrijednost 100. Registar TCNT0 prilikom brojanja impulsa uovom slu£aju poprima vrijednosti 100, 101 ,.., 253, 254, 255, (0) → 100, 101,... .

Programski kod 8.2: Prekidna rutina za prekidni vektor TIMER0_OVF_vect

ISR(TIMER0_OVF_vect)

TCNT0 = 100;

// niz naredbi koje mjere temperaturu pe¢i na kruta goriva

U vjeºbama ¢e biti prikazan niz funkcija koje su napisane za konguriranje tajmera, a kojese nalaze u biblioteci timer.h.

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku Timer.zip. Na radnojpovr²ini stvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢i pritomdijakriti£ke znakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢ete stvoriti zvat ¢ese Ivica Ivic. Datoteku Timer.zip raspakirajte u novostvorenu datoteku na radnoj povr²ini.Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini te dvostrukim klikom pokrenite VUBmikroracunala.atsln u datoteci \\Timer\vjezbe. U otvorenom projektu nalaze se sve vjeºbekoje ¢emo obraditi u poglavlju Tajmeri i broja£i. Vjeºbe ¢emo pisati u datoteke s ekstenzijom*.cpp.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koja moºete koristiti za provjeru ispravnostiprogramskih zadataka.

Vjeºba 8.1.1

Napravite program u kojem ¢ete pomo¢u sklopa Timer/Counter0 mijenjati stanje crvene LEDdiode svakih 15 ms. Crvena LED dioda spojena je na pin PB4. Istovremeno je na LCD displejupotrebno ispisivati vrijeme rada mikroupravlja£a u minutama. Minute generirajte tako dapostavite ka²njenje while petlje od 60 s.

U projektnom stablu otvorite datoteku vjezba811.cpp. Omogu¢ite samo prevoenjedatoteke vjezba811.cpp. Po£etni sadrºaj datoteke vjezba811.cpp prikazan je programskimkodom 8.3.

Programski kod 8.3: Po£etni sadrºaj datoteke vjezba811.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

#include "Interrupt/interrupt.h"

108 Tajmeri i broja£i

// prekidna rutina za timer0

ISR(TIMER0_OVF_vect)

TCNT0 = 0; // po£etna vrijednost registra

toggle_port(PORTB , PB4);

void inicijalizacija ()

DDRB |= (1 << PB4); // PB4 izlazni pin

// inicijalizacija za timer0

timer0_set_normal_mode ();

timer0_set_prescaler(TIMER0_PRESCALER_1024);

timer0_interrupt_OVF_enable ();

lcd_init (); // inicijalizacija LCD displeja

// interrupt_enable (); // globalno omogu¢i prekide //sei();

TCNT0 = 0; // po£etna vrijednost registra

int main(void)

inicijalizacija ();

uint16_t minute = 0;

while (1)

lcd_clrscr ();

lcd_home ();

lcd_print("ON : %u min", minute ++);

_delay_ms (60000); // ka²njenje 60 s

return 0;

Funkcije koje se koriste za inicijalizaciju tajmera deklarirane su u zaglavljutimer.h. Naredba kojom uklju£ujemo zaglavlje timer.h u datoteku koja se prevodijest #include "Timer/timer.h". U ovoj vjeºbi koristit ¢emo sklop Timer/Counter0kao tajmer u normalnom na£inu rada. Ovaj na£in koristi prekide pomo¢u kojihse prekidna rutina poziva u jednakim vremenskim razmacima. Kada se koristeprekidi, u programski kod potrebno je uklju£iti zaglavlje interrupt.h pomo¢u naredbe#include <avr/interrupt.h>. Autor je pripremio vlastito zaglavlje interrupt.h koje seuklju£uje naredbom #include "Interrupt/interrupt.h", a unutar kojeg se nalazi pozivnaredbe #include <avr/interrupt.h>.

U programskom kodu 8.3 u funkciji inicijalizacija() nalaze se sljede¢e funkcije:

• timer0_set_normal_mode() - funkcija kojom se sklop Timer/Counter0 postavlja unormalan na£in rada prema tablici 8.2,

• timer0_set_prescaler(TIMER0_PRESCALER_1024) - funkcija kojom se kongurira djeliteljfrekvencije radnog takta,

• timer0_interrupt_OVF_enable() - funkcija kojom se omogu¢uje prekid sklopaTimer/Counter0 kada doe do preljeva registra TCNT0.

Funkcija timer0_set_prescaler(uint8_t prescaler) kao argument (uint8_t prescaler)prima predenirane konstante koje se nalaze u zaglavlju timer.h i prikazane su programskimkodom 8.4. Na primjer, ako ºelimo postaviti djelitelj frekvencije radnog takta na iznos 256, tada¢emo pozvati funkciju timer0_set_prescaler(TIMER0_PRESCALER_256). Argument pozvanefunkcije jest TIMER0_PRESCALER_256, a on prema tablici 8.1 i deniciji u programskom kodu 8.4odgovara dijeljenju radnog takta s 256.

8.1 Vjeºbe - Normalan na£in rada tajmera 109

Programski kod 8.4: Odabir djelitelj frekvencije radnog takta u datoteci timer.h

// djelitelji frekvencije za timer0

#define TIMER0_PRESCALER_OFF ((0 << CS02) | (0 << CS01) | (0 << CS00))

#define TIMER0_PRESCALER_1 ((0 << CS02) | (0 << CS01) | (1 << CS00))

#define TIMER0_PRESCALER_8 ((0 << CS02) | (1 << CS01) | (0 << CS00))

#define TIMER0_PRESCALER_64 ((0 << CS02) | (1 << CS01) | (1 << CS00))

#define TIMER0_PRESCALER_256 ((1 << CS02) | (0 << CS01) | (0 << CS00))

#define TIMER0_PRESCALER_1024 ((1 << CS02) | (0 << CS01) | (1 << CS00))

#define TIMER0_EXTERNAL_FALL_EDGE ((1 << CS02) | (1 << CS01) | (0 << CS00))

#define TIMER0_EXTERNAL_RISI_EDGE ((1 << CS02) | (1 << CS01) | (1 << CS00))

U funkciji inicijalizacija() potrebno je pozvati funkciju interrupt_enable() kojaglobalno omogu¢uje prekide. Ispod poziva funkcije interrupt_enable() potrebno je postavitipo£etnu vrijednost registra TCNT0. Trenutna po£etna vrijednost jest 0, ²to ¢emo kasnijepromijeniti.

Uvijek kada se dogodi preljev registra TCNT0, poziva se prekidna rutina prikazanaprogramskim kodom 8.5.

Programski kod 8.5: Prekidna rutina koja se poziva kada se dogodi preljev registra TCNT0

ISR(TIMER0_OVF_vect)

TCNT0 = 0; // po£etna vrijednost registra

toggle_port(PORTB , PB4);

Kada se pozove prekidna rutina, potrebno je postaviti po£etnu vrijednost registra TCNT0kako bi sljede¢i poziv prekidne rutine nastupio nakon ºeljenog vremena. U tu svrhu koristit¢emo relaciju (8.2). U datoteci timer.h odabran je djelitelj frekvencije radnog takta 1024. Uvjeºbi je prekidnu rutinu potrebno pozivati svakih 15 ms, pa vrijedi da je tT0 = 0,015 s. Po£etnuvrijednost registra TCNT0 moºemo izra£unati prema relaciji (8.2):

TCNT00 = 256− tT0 ·F_CPU

PRESCALER= 256− 0, 015 · 16000000

1024= 22. (8.6)

Po£etnu vrijednost registra TCNT0 upi²ite u funkciju inicijalizacija() i u prekidnu rutinuISR(TIMER0_OVF_vect). U prekidnoj se rutini mijenja stanje crvene LED diode makronaredbomtoggle_port.

U while petlji na LCD displej ispisuje se vrijeme rada mikroupravlja£a u minutama.Primijetite da smo u while petlji postavili ka²njenje od 60 s. Zbog tog ka²njenja mikroupravlja£u while petlji 60 sekundi ni²ta ne radi. Prekidna se rutina poziva bez obzira na ka²njenje uwhile petlji i to je velika korist prekidnih rutina uop¢e.

Prevedite datoteku vjezba811.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Ukoliko crvena LED dioda ne izmjenjuje stanje, izbri²ite komentar ispred funkcijeinterrupt_enable(); u funkciji inicijalizacija(). Budu¢i da prekidi nisu bili omogu¢eni naglobalnoj razini, prekidna rutina ISR(TIMER0_OVF_vect) ne¢e biti pozvana. Ponovno preveditedatoteku vjezba811.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajteprogram na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

U nastavku vjeºbe izbrisat ¢emo funkcije timer0_set_normal_mode(),timer0_set_prescaler(TIMER0_PRESCALER_1024) i timer0_interrupt_OVF_enable() izfunkcije inicijalizacija() te napisati niz naredbi iz programskog koda 8.6.

U programskom kodu 8.6 direktno smo kongurirali bitove registara TCCR0A i TCCR0B prematablicama 8.1 i 8.2 te slikama 8.3 i 8.4. U registru TIMSK0 omogu¢ili smo prekid koji se dogaaprilikom preljeva registra TCNT0. Prevedite datoteku vjezba811.cpp u strojni kod i snimite ga na

110 Tajmeri i broja£i

mikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£emATmega32U4.

Programski kod 8.6: Konguracija sklopa Timer/Counter0 direktnom konguracijom registara

// postaviti normalna na£in rada za timer0

TCCR0A |= (0 << WGM01) | (0 << WGM00);

TCCR0B |= (0 << WGM02);

// postaviti djelitelj frekvencije na 1024

TCCR0B |= (1 << CS02) | (0 << CS01) | (1 << CS00);

// omogu¢iti prekid za timer0 - overflow

TIMSK0 |= (1 << TOIE0);

U zaglavlju avrvub.h nalaze se makronaredbe koje omogu¢uju postavljanje bitova uregistrima u vrijednosti 0 i 1:

• set_bit_reg(reg, bit) - makronaredba koja prima argument reg koji predstavljaregistar u kojem ¢e se na poziciji argumenta bit postaviti 1,

• reset_bit_reg(reg, bit) - makronaredba koja prima argument reg koji predstavljaregistar u kojem ¢e se na poziciji argumenta bit postaviti 0.

U programskom kodu 8.7 konguraciju sklopa Timer/Counter0 napravili smo pomo¢umakronaredbi set_bit_reg i reset_bit_reg prema tablicama 8.1 i 8.2 te slikama 8.3 i 8.4.Ovaj na£in konguracije sklopa Timer/Counter0 jednostavan je, a daje jasan pregled stanjabitova u registrima sklopa Timer/Counter0.

Programski kod 8.7: Konguracija sklopa Timer/Counter0 pomo¢u makronaredbiset_bit_reg i reset_bit_reg

// postaviti normalna na£in rada za timer0

reset_bit_reg(TCCR0A , WGM00); //WGM00 = 0

reset_bit_reg(TCCR0A , WGM01); //WGM01 = 0

reset_bit_reg(TCCR0B , WGM02); //WGM02 = 0

// postaviti djelitelj frekvencije na 1024

set_bit_reg(TCCR0B , CS00); // CS00 = 1

reset_bit_reg(TCCR0B , CS01);// CS01 = 0

set_bit_reg(TCCR0B , CS02);// CS02 = 1

// omogu¢iti prekid za timer0 - overflow

set_bit_reg(TIMSK0 , TOIE0);// TOIE0 = 1

Kongurirajte sklop Timer/Counter0 pomo¢u niza naredbi u programskom kodu 8.7, a zatimprevedite datoteku vjezba811.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4.Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba811.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 8.1.2

Napravite program u kojem ¢ete pomo¢u sklopa Timer/Counter1 mijenjati stanje ºute LEDdiode svakih 200 ms. uta LED dioda spojena je na pin PB5. Istovremeno je na LCDdispleju potrebno ispisivati vrijeme rada mikroupravlja£a u minutama. Minute generirajte takoda postavite ka²njenje while petlje od 60 s.

U projektnom stablu otvorite datoteku vjezba812.cpp. Omogu¢ite samo prevoenjedatoteke vjezba812.cpp. Po£etni sadrºaj datoteke vjezba812.cpp prikazan je programskimkodom 8.8.

8.1 Vjeºbe - Normalan na£in rada tajmera 111

Programski kod 8.8: Po£etni sadrºaj datoteke vjezba812.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

#include "Interrupt/interrupt.h"

// prekidna rutina za timer1

ISR(TIMER1_OVF_vect)

TCNT1 = 0; // po£etna vrijednost registra

toggle_port(PORTB , PB5);

void inicijalizacija ()

DDRB |= (1 << PB5); // PB5 izlazni pin

// inicijalizacija za timer1 - prvi na£in

timer1_set_normal_mode ();

timer1_set_prescaler(TIMER1_PRESCALER_64);

timer1_interrupt_OVF_enable ();

lcd_init (); // inicijalizacija LCD displeja

interrupt_enable (); // globalno omogu¢i prekide //sei();

TCNT1 = 0; // po£etna vrijednost registra

int main(void)

inicijalizacija ();

uint16_t minute = 0;

while (1)

lcd_clrscr ();

lcd_home ();

lcd_print("ON : %u min", minute ++);

_delay_ms (60000); // ka²njenje 60 s

return 0;

U ovoj vjeºbi koristit ¢emo sklop Timer/Counter1 kao tajmer u normalnom na£inu rada.Rezolucija sklopa Timer/Counter1 jest 16 bitova pa se raspon vrijednosti u registru u kojem sebroje impulsi kre¢e od [0, 65535]. Registar u kojem se broje impulsi zove se TCNT1. Primijetiteda se ime registra sklopa Timer/Counter1 od imena registra sklopa Timer/Counter0 razlikujesamo u indeksu (0 je zamijenjena s 1).

Konguracija sklopa Timer/Counter1 izvr²ava se pomo¢u dvaju registara: TCCR1A i TCCR1B.Detalje o konguraciji sklopa Timer/Counter1 pogledajte u literaturi [1] u tablicama 14-1 do14-5.

U programskom kodu 8.8 u funkciji inicijalizacija() nalaze se sljede¢e funkcije:

• timer1_set_normal_mode() - funkcija kojom se sklop Timer/Counter1 postavlja unormalan na£in rada prema tablici 14-4 u literaturi [1],

• timer1_set_prescaler(TIMER1_PRESCALER_64) - funkcija kojom se kongurira djeliteljfrekvencije radnog takta,

• timer1_interrupt_OVF_enable() - funkcija kojom se omogu¢uje prekid sklopaTimer/Counter1 kada doe do preljeva registra TCNT1.

112 Tajmeri i broja£i

Funkcija timer1_set_prescaler(uint8_t prescaler) kao argument (uint8_t prescaler)prima predenirane konstante koje se nalaze u zaglavlju timer.h i prikazane su programskimkodom 8.9. Na primjer, ako ºelimo postaviti djelitelj frekvencije radnog takta na iznos 8,tada ¢emo pozvati funkciju timer1_set_prescaler(TIMER1_PRESCALER_8). Argument pozvanefunkcije jest TIMER1_PRESCALER_8, a on prema tablici 14-5 u literaturi [1] i deniciji uprogramskom kodu 8.9 odgovara dijeljenju radnog takta s 8.

Programski kod 8.9: Odabir djelitelj frekvencije radnog takta u datoteci timer.h

// djelitelji frekvencije za timer1

#define TIMER1_PRESCALER_OFF ((0 << CS12) | (0 << CS11) | (0 << CS10))

#define TIMER1_PRESCALER_1 ((0 << CS12) | (0 << CS11) | (1 << CS10))

#define TIMER1_PRESCALER_8 ((0 << CS12) | (1 << CS11) | (0 << CS10))

#define TIMER1_PRESCALER_64 ((0 << CS12) | (1 << CS11) | (1 << CS10))

#define TIMER1_PRESCALER_256 ((1 << CS12) | (0 << CS11) | (0 << CS10))

#define TIMER1_PRESCALER_1024 ((1 << CS12) | (0 << CS11) | (1 << CS10))

#define TIMER1_EXTERNAL_FALL_EDGE ((1 << CS12) | (1 << CS11) | (0 << CS10))

#define TIMER1_EXTERNAL_RISI_EDGE ((1 << CS12) | (1 << CS11) | (1 << CS10))

Prema funkcijama za inicijalizaciju sklopa Timer/Counter1 koje su pozvane u funkcijiinicijalizacija(), sklop Timer/Counter1 konguriran je kao tajmer u normalnom na£inu radas djeliteljem frekvencije radnog takta 64. Prekid koji izaziva preljev u registru TCNT1 omogu¢ujese upisivanjem broja 1 na mjesto bita TOIE1 u registru TIMSK1. Za globalno omogu¢avanjeprekida pozvana je funkcija interrupt_enable().

Vrijeme izmeu dvaju poziva prekidne rutine mora biti 200 ms (tT1 = 0,2 s). Po£etnuvrijednost registra TCNT1 izra£unat ¢emo pomo¢u korigirane relacije (8.2):

TCNT10 = 65536− tT1 ·F_CPU

PRESCALER= 65536− 0, 2 · 16000000

64= 15536. (8.7)

Spomenuli smo ranije da je kod sklopa Timer/Counter1 u relaciji (8.2) broj 256 potrebnozamijeniti brojem 65536. Po£etna vrijednost registra TCNT1 jest 15536. Upi²ite tu vrijednost naodgovaraju¢a mjesta u programskom kodu 8.8.

Prekidna rutina ISR, koja se poziva kada se dogodi preljev registra TCNT1, prima prekidnivektor TIMER1_OVF_vect. U prekidnoj rutini postavlja se po£etna vrijednost registra TCNT1 tese mijenja stanje ºute LED diode makronaredbom toggle_port.

U while petlji na LCD displej ispisuje se vrijeme rada mikroupravlja£a u minutama.Primijetite da smo u while petlji postavili ka²njenje od 60 s. Zbog tog ka²njenja mikroupravlja£u while petlji 60 sekundi ni²ta ne radi. Prekidna rutina poziva se bez obzira na ka²njenje uwhile petlji.

Prevedite datoteku vjezba812.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

U programskom kodu 8.10 konguraciju sklopa Timer/Counter1 napravili smo pomo¢umakronaredbi set_bit_reg i reset_bit_reg prema tablicama 14-4 i 14-5 u literaturi [1].Zamijenite sada konguraciju sklopa Timer/Counter1 u programskom kodu 8.8 programskimkodom 8.10.

Programski kod 8.10: Konguracija sklopa Timer/Counter1 pomo¢u makronaredbiset_bit_reg i reset_bit_reg

// postaviti normalna nacin rada za timer1

reset_bit_reg(TCCR1A , WGM10); //WGM10 = 0

reset_bit_reg(TCCR1A , WGM11); //WGM11 = 0

reset_bit_reg(TCCR1B , WGM12); //WGM12 = 0

reset_bit_reg(TCCR1B , WGM13); //WGM13 = 0

8.1 Vjeºbe - Normalan na£in rada tajmera 113

// postaviti djelitelj frekvencije na 64

set_bit_reg(TCCR1B , CS10); // CS10 = 1

set_bit_reg(TCCR1B , CS11);// CS11 = 1

reset_bit_reg(TCCR1B , CS12);// CS12 = 0

// omoguciti prekid za timer1 - overflow

set_bit_reg(TIMSK1 , TOIE1);// TOIE1 = 1

Prevedite datoteku vjezba812.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Promijenite vrijeme izmeu poziva prekidne rutine u 500 ms. Ponovno prevedite datotekuvjezba812.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte programna razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba812.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 8.1.3

Napravite program u kojem ¢ete pomo¢u sklopa Timer/Counter3 mijenjati stanje zelene LEDdiode svakih 1000 ms. Zelena LED dioda spojena je na pin PB6. Istovremeno je na LCDdispleju potrebno ispisivati vrijeme rada mikroupravlja£a u minutama. Minute generirajte takoda postavite ka²njenje while petlje od 60 s.

U projektnom stablu otvorite datoteku vjezba813.cpp. Omogu¢ite samo prevoenjedatoteke vjezba813.cpp. Po£etni sadrºaj datoteke vjezba813.cpp prikazan je programskimkodom 8.11.

Programski kod 8.11: Po£etni sadrºaj datoteke vjezba813.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

#include "Interrupt/interrupt.h"

// prekidna rutina za timer3

ISR(TIMER3_OVF_vect)

TCNT3 = 0; // po£etna vrijednost registra

toggle_port(PORTB , PB6);

void inicijalizacija ()

DDRB |= (1 << PB6); // PB6 izlazni pin

// inicijalizacija za timer3

timer3_set_normal_mode ();

timer3_set_prescaler(TIMER3_PRESCALER_256);

timer3_interrupt_OVF_enable ();

lcd_init (); // inicijalizacija LCD displeja

interrupt_enable (); // globalno omogu¢i prekide //sei();

TCNT3 = 0; // po£etna vrijednost registra

int main(void)

inicijalizacija ();

uint16_t minute = 0;

while (1)

114 Tajmeri i broja£i

lcd_clrscr ();

lcd_home ();

lcd_print("ON : %u min", minute ++);

_delay_ms (60000); // ka²njenje 60 s

return 0;

U ovoj vjeºbi koristit ¢emo sklop Timer/Counter3 kao tajmer u normalnom na£inu rada.Rezolucija sklopa Timer/Counter3 jest 16 bitova pa se raspon vrijednosti u registru u kojem sebroje impulsi kre¢e od [0, 65535]. Registar u kojem se broje impulsi zove se TCNT3.

Konguracija sklopa Timer/Counter3 izvr²ava se pomo¢u dvaju registara: TCCR3A i TCCR3B.Detalje o konguraciji sklopa Timer/Counter3 pogledajte u literaturi [1] u tablicama 14-1 do14-5.

U programskom kodu 8.11 u funkciji inicijalizacija() nalaze se sljede¢e funkcije:

• timer3_set_normal_mode() - funkcija kojom se sklop Timer/Counter3 postavlja unormalan na£in rada prema tablici 14-4 u literaturi [1],

• timer3_set_prescaler(TIMER3_PRESCALER_256) - funkcija kojom se kongurira djeliteljfrekvencije radnog takta,

• timer3_interrupt_OVF_enable() - funkcija kojom se omogu¢uje prekid sklopaTimer/Counter3 kada doe do preljeva registra TCNT3.

Funkcija timer3_set_prescaler(uint8_t prescaler) kao argument (uint8_t prescaler)prima predenirane konstante koje se nalaze u zaglavlju timer.h i prikazane su programskimkodom 8.12.

Programski kod 8.12: Odabir djelitelj frekvencije radnog takta u datoteci timer.h

// djelitelji frekvencije za timer1

#define TIMER3_PRESCALER_OFF ((0 << CS32) | (0 << CS31) | (0 << CS30))

#define TIMER3_PRESCALER_1 ((0 << CS32) | (0 << CS31) | (1 << CS30))

#define TIMER3_PRESCALER_8 ((0 << CS32) | (1 << CS31) | (0 << CS30))

#define TIMER3_PRESCALER_64 ((0 << CS32) | (1 << CS31) | (1 << CS30))

#define TIMER3_PRESCALER_256 ((1 << CS32) | (0 << CS31) | (0 << CS30))

#define TIMER3_PRESCALER_1024 ((1 << CS32) | (0 << CS31) | (1 << CS30))

#define TIMER3_EXTERNAL_FALL_EDGE ((1 << CS32) | (1 << CS31) | (0 << CS30))

#define TIMER3_EXTERNAL_RISI_EDGE ((1 << CS32) | (1 << CS31) | (1 << CS30))

Prema funkcijama za inicijalizaciju sklopa Timer/Counter3 koje su pozvane u funkcijiinicijalizacija(), sklop Timer/Counter3 konguriran je kao tajmer u normalnom na£inu radas djeliteljem frekvencije radnog takta 256. Prekid koji izaziva preljev u registru TCNT3 omogu¢ujese upisivanjem broja 1 na mjesto bita TOIE3 u registru TIMSK3. Za globalno omogu¢avanje prekidapozvana je funkcija interrupt_enable().

Vrijeme izmeu dvaju poziva prekidne rutine mora biti 1000 ms (tT3 = 1,0 s). Po£etnuvrijednost registra TCNT3 izra£unat ¢emo pomo¢u korigirane relacije (8.2):

TCNT30 = 65536− tT3 ·F_CPU

PRESCALER= 65536− 1, 0 · 16000000

256= 3036. (8.8)

Kod sklopa Timer/Counter3 u relaciji (8.2) broj 256 potrebno je zamijeniti brojem 65536jer je registar TCNT3 ²irine 16 bitova. Po£etna vrijednost registra TCNT3 jest 3036. Upi²ite tuvrijednost na odgovaraju¢a mjesta u programskom kodu 8.11.

8.1 Vjeºbe - Normalan na£in rada tajmera 115

Prekidna rutina ISR, koja se poziva kada se dogodi preljev registra TCNT3, prima prekidnivektor TIMER3_OVF_vect. U prekidnoj rutini postavlja se po£etna vrijednost registra TCNT3 tese mijenja stanje zelene LED diode makronaredbom toggle_port.

U while petlji na LCD displej ispisuje se vrijeme rada mikroupravlja£a u minutama.Primijetite da smo u while petlji postavili ka²njenje od 60 s. Zbog tog ka²njenja mikroupravlja£u while petlji 60 sekundi ni²ta ne radi. Prekidna rutina poziva se bez obzira na ka²njenje uwhile petlji.

Prevedite datoteku vjezba813.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Promijenite vrijeme izmeu poziva prekidne rutine u 1500 ms. Ponovno prevedite datotekuvjezba813.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte programna razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba813.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 8.1.4

Napravite program u kojem ¢ete pomo¢u sklopa Timer/Counter0 mijenjati stanje crvene LEDdiode svakih 300 ms, pomo¢u sklopa Timer/Counter1 mijenjati stanje ºute LED diode svakih300 ms, a pomo¢u sklopa Timer/Counter3 mijenjati stanje zelene LED diode svakih 300 ms.Crvena LED dioda spojena je na pin PB4, ºuta LED dioda spojena je na pin PB5, a zelenaLED dioda spojena je na pin PB6. Istovremeno je na LCD displeju potrebno ispisivati vrijemerada mikroupravlja£a u minutama. Minute generirajte tako da postavite ka²njenje while petljeod 60 s.

U projektnom stablu otvorite datoteku vjezba814.cpp. Omogu¢ite samo prevoenjedatoteke vjezba814.cpp. Po£etni sadrºaj datoteke vjezba814.cpp prikazan je programskimkodom 8.13.

Programski kod 8.13: Po£etni sadrºaj datoteke vjezba814.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

#include "Interrupt/interrupt.h"

// umetnite programski kod 8.14

// prekidna rutina za timer1

ISR(TIMER1_OVF_vect)

TCNT1 = 0; // po£etna vrijednost registra

toggle_port(PORTB , PB5);

// prekidna rutina za timer3

ISR(TIMER3_OVF_vect)

TCNT3 = 0; // po£etna vrijednost registra

toggle_port(PORTB , PB6);

void inicijalizacija ()

DDRB |= (1 << PB4) | (1 << PB5) | (1 << PB6); // PB4 , PB5 i PB6 izlazni pinovi

// inicijalizacija za timer0

116 Tajmeri i broja£i

timer0_set_normal_mode ();

// timer0_set_prescaler(TIMER0_PRESCALER_);

timer0_interrupt_OVF_enable ();

// inicijalizacija za timer1

timer1_set_normal_mode ();

// timer1_set_prescaler(TIMER1_PRESCALER_);

timer1_interrupt_OVF_enable ();

// inicijalizacija za timer3

timer3_set_normal_mode ();

// timer3_set_prescaler(TIMER3_PRESCALER_);

timer3_interrupt_OVF_enable ();

lcd_init (); // inicijalizacija LCD displeja

interrupt_enable (); // globalno omogu¢i prekide //sei();

TCNT0 = 0; // pocetna vrijednost registra za timer0

TCNT1 = 0; // pocetna vrijednost registra za timer1

TCNT3 = 0; // pocetna vrijednost registra za timer3

int main(void)

inicijalizacija ();

uint16_t minute = 0;

while (1)

lcd_clrscr ();

lcd_home ();

lcd_print("ON : %u min", minute ++);

_delay_ms (60000); // ka²njenje 60 s

return 0;

U programskom kodu 8.13 u funkciji inicijalizacija() nalaze se funkcije koje kongurirajurad sklopova Timer/Counter0, Timer/Counter1 i Timer/Counter3 u normalnom na£inu rada.Omogu¢en je i prekid za sve tajmere. Da bi se ostvarila zadana izmjena stanja crvene, ºute izelene LED diode svakih 300 ms, potrebno je prora£unati po£etna stanja registara TCNT0, TCNT1i TCNT3 te odrediti djelitelje frekvencije radnog takta za sve tajmere.

Vrijeme izmeu dvaju poziva prekidne rutine ISR(TIMER0_OVF_vect) mora biti 300 ms(tT0 = 0,3 s). Po£etnu vrijednost registra TCNT0 izra£unat ¢emo pomo¢u relacije (8.2):

TCNT00 = 256− tT0 ·F_CPU

PRESCALER_0= 256− 0, 3 · 16000000

1024= −4431, 5. (8.9)

Po£etna vrijednost registra TCNT0 dobivena relacijom (8.9) manja je od 0. To zna£i da snajve¢im djeliteljem frekvencije radnog takta nije mogu¢e ostvariti vrijeme izmeudvaju poziva prekidne rutine od 300 ms. Maksimalno vrijeme izmeu dvaju poziva prekidnerutine ISR(TIMER0_OVF_vect) jest ono vrijeme za koje po£etna vrijednost registra TCNT0 iznosi0:

tT0 =PRESCALER

F_CPU· (256− TCNT00) =

1024

16000000· (256− 0) = 16, 384ms. (8.10)

Prema relaciji (8.10), vremena izmeu dvaju poziva prekidne rutine mogu se podesiti takoda budu manja od 16,384 s. Kako sada ipak ostvariti izmjenu stanja crvene LED diode svakih

8.1 Vjeºbe - Normalan na£in rada tajmera 117

300 ms? Za ovaj problem postoji rje²enje koje ¢emo prikazati u nastavku. Na primjer, pozivizmeu dviju prekidnih rutina u vremenskom razmaku od 300 ms moºemo podijeliti na 20 pozivaprekidne rutine u vremenskom razmaku od 15 ms. Stanje crvene LED diode u prekidnoj rutinitada ¢emo mijenjati u svakom dvadesetom pozivu prekidne rutine.

Izra£unajmo novu po£etnu vrijednost registra TCNT0 za dvadesetinu vremena od 300 ms:

TCNT00 = 256− tT020· F_CPUPRESCALER_0

= 256− 0, 015 · 16000000

1024= 21, 625 ≈ 22. (8.11)

U programski kod 8.13 napi²ite prekidnu rutinu ISR(TIMER0_OVF_vect) prikazanuprogramskim kodom 8.14.

Programski kod 8.14: Prekidna rutina koja se poziva kada se dogodi preljev registra TCNT0

uint8_t prazan_hod_timer0 = 0;

// prekidna rutina za timer0

ISR(TIMER0_OVF_vect)

TCNT0 = 0; // pocetna vrijednost registra

if(++ prazan_hod_timer0 == 20)

toggle_port(PORTB , PB4);

prazan_hod_timer0 = 0;

U programskom kodu 8.14 deklarirana je globalna varijabla prazan_hod_timer0. Ovavarijabla koristi se kao broja£ poziva prekidne rutine ISR(TIMER0_OVF_vect). U svakomdvadesetom pozivu prekidne rutine mijenjamo stanje crvene LED diode. Vrijeme izmeu dvajupoziva prekidne rutine jest 15 ms te se stanje crvene LED diode mijenja svakih 300 ms (15 ms ·20 = 300 ms).

Upi²ite po£etnu vrijednost registra TCNT0, uklonite komentar funkcijetimer0_set_prescaler te dodijelite argument funkciji timer0_set_prescaler kojim ¢ese kongurirati djelitelj frekvencije radnog takta iznosa 1024.

Vrijeme izmeu dvaju poziva prekidne rutine ISR(TIMER1_OVF_vect) mora biti 300 ms(tT1 = 0,3 s). Po£etnu vrijednost registra TCNT1 izra£unat ¢emo pomo¢u korigirane relacije(8.2):

TCNT10 = 65536− tT1 ·F_CPU

PRESCALER_1= 65536− 0, 3 · 16000000

256= 46786. (8.12)

Upi²ite po£etnu vrijednost registra TCNT1, uklonite komentar funkcijetimer1_set_prescaler te dodijelite argument funkciji timer1_set_prescaler kojim ¢ese kongurirati djelitelj frekvencije radnog takta iznosa 256.

Vrijeme izmeu dvaju poziva prekidne rutine ISR(TIMER3_OVF_vect) mora biti 300 ms(tT3 = 0,3 s). Po£etnu vrijednost registra TCNT3 izra£unat ¢emo pomo¢u relacije (8.2):

TCNT30 = 65536− tT3 ·F_CPU

PRESCALER_3= 65536− 0, 3 · 16000000

256= 46786. (8.13)

Upi²ite po£etnu vrijednost registra TCNT3, uklonite komentar funkcijetimer3_set_prescaler te dodijelite argument funkciji timer3_set_prescaler kojim ¢ese kongurirati djelitelj frekvencije radnog takta iznosa 256.

U while petlji na LCD displej ispisuje se vrijeme rada mikroupravlja£a u minutama.Primijetite da smo u while petlji postavili ka²njenje od 60 s. Zbog tog ka²njenja mikroupravlja£

118 Tajmeri i broja£i

u while petlji 60 sekundi ni²ta ne radi. Prekidna rutina poziva se bez obzira na ka²njenje uwhile petlji.

Prevedite datoteku vjezba814.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Komentirajte za²to se izmjena stanja crvene diode vremenski razilazi s izmjenama stanja ºute izelene diode?

Zatvorite datoteku vjezba814.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 8.1.5

Napravite program koji ¢e omogu¢iti tzv. beskona£no tr£anje svih LED dioda svakih 250 ms ito redoslijedom crvena → ºuta → zelena → plava → crvena → ... . Izmjenu stanja LED diodasvakih 250 ms ostvarite pomo¢u sklopa Timer/Counter1. Crvena LED dioda spojena je nadigitalni pin PB7, ºuta LED dioda spojena je na digitalni pin PB5, zelena LED dioda spojenaje na digitalni pin PB6, a plava LED dioda spojena je na digitalni pin PB7. Istovremeno je naLCD displeju potrebno ispisivati vrijeme rada mikroupravlja£a u minutama. Minute generirajtetako da postavite ka²njenje while petlje od 60 s.

U projektnom stablu otvorite datoteku vjezba815.cpp. Omogu¢ite samo prevoenjedatoteke vjezba815.cpp. Po£etni sadrºaj datoteke vjezba815.cpp prikazan je programskimkodom 8.15.

Programski kod 8.15: Po£etni sadrºaj datoteke vjezba815.cpp

#include "AVR VUB/avrvub.h"

#include "LCD/lcd.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

#include "Interrupt/interrupt.h"

uint8_t brojac = 0;

ISR(TIMER1_OVF_vect) // prekidna rutina za timer1

TCNT1 = 0; // po£etna vrijednost registra

switch (++ brojac)

case 1:

set_port(PORTB ,PB4 ,1);

set_port(PORTB ,PB7 ,0);

break;

case 2:

set_port(PORTB ,PB5 ,1);

set_port(PORTB ,PB4 ,0);

break;

case 3:

set_port(PORTB ,PB6 ,1);

set_port(PORTB ,PB5 ,0);

break;

case 4:

set_port(PORTB ,PB7 ,1);

set_port(PORTB ,PB6 ,0);

brojac = 0;

break;

default:

break;

8.1 Vjeºbe - Normalan na£in rada tajmera 119

void inicijalizacija ()

// PB4 , PB5 , PB6 , PB7 izlazni pinovi

DDRB |= (1 << PB4) | (1 << PB5) | (1 << PB6) | (1 << PB7);

// inicijalizacija za timer1

timer1_set_normal_mode ();

timer1_set_prescaler(TIMER1_PRESCALER_64);

timer1_interrupt_OVF_enable ();

lcd_init (); // inicijalizacija LCD displeja

interrupt_enable (); // globalno omogu¢i prekide //sei();

TCNT1 = 0; // po£etna vrijednost registra

int main(void)

inicijalizacija ();

uint16_t minute = 0;

while (1)

lcd_clrscr ();

lcd_home ();

lcd_print("ON : %u min", minute ++);

_delay_ms (60000); // ka²njenje 60 s

return 0;

U ovoj vjeºbi koristit ¢emo sklop Timer/Counter1 kao tajmer u normalnom na£inu rada. Uprogramskom kodu 8.13 u funkciji inicijalizacija() nalaze se funkcije koje konguriraju radsklopa Timer/Counter1 u normalnom na£inu rada, deniraju djelitelj frekvencije radnog takta iomogu¢uju prekid preljevom registra TCNT1.

U vjeºbi je potrebno ostvariti tr£e¢e LED diode redoslijedom crvena → ºuta → zelena →plava → crvena → ... . Izmjenu stanja LED dioda svakih 250 ms potrebno je ostvariti pomo¢usklopa Timer/Counter1. Sli£an program napravili smo u vjeºbi 4.1.4, no u toj vjeºbi koristilismo vremenska ka²njenja.

U prekidnoj rutini ISR(TIMER1_OVF_vect) nalazi se switch case blok koji ima £etiri slu£aja.Svaki slu£aj zaduºen je za uklju£enje sljede¢e LED diode i isklju£enje prethodno uklju£ene LEDdiode (npr. case 2: crvena LED dioda se isklju£i, a ºuta LED dioda se uklju£i). Slu£aj uswitch case bloku odabire se pomo¢u varijable brojac. U svakom pozivu prekidne rutinevarijabla brojac uve¢a se za 1. U slu£aju broj 4 (case 4:) vrijednost varijable brojac postavljase u 0 kako bi se ostvarilo ponovno tr£anje LED dioda.

Vrijeme izmeu dvaju poziva prekidne rutine mora biti 250 ms (tT1 = 0,25 s). Po£etnuvrijednost registra TCNT1 izra£unat ¢emo pomo¢u korigirane relacije (8.2):

TCNT10 = 65536− tT1 ·F_CPU

PRESCALER= 65536− 0, 25 · 16000000

64= 3036. (8.14)

Upi²ite po£etnu vrijednost registra TCNT1 u programski kod 8.15 na za to predvieno mjesto.U while petlji na LCD displej ispisuje se vrijeme rada mikroupravlja£a u minutama. Primijetiteda smo u while petlji postavili ka²njenje od 60 s. Zbog tog ka²njenja mikroupravlja£ u whilepetlji 60 sekundi ni²ta ne radi. Prekidna rutina poziva se bez obzira na ka²njenje u while petlji.

Prevedite datoteku vjezba815.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Promijenite smjer tr£anja LED dioda te ponovno prevedite datoteku vjezba815.cpp u strojni

120 Tajmeri i broja£i

kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenjus mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba815.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 8.1.6

Napravite program u kojem ¢e se, ako je pritisnuto tipkalo spojeno na pin PD0, uzimati uzorcis analognog senzora spojenog na pin ADC5. Vrijeme uzorkovanja neka iznosi 800 ms. Uzimanjeuzoraka ostvarite u prekidnoj rutini ISR(TIMER3_OVF_vect). Vrijednost napona na pinu ADC5ispi²ite na LCD displej u while petlji samo kada se uzimaju uzorci.

U projektnom stablu otvorite datoteku vjezba816.cpp. Omogu¢ite samo prevoenjedatoteke vjezba816.cpp. Po£etni sadrºaj datoteke vjezba816.cpp prikazan je programskimkodom 8.16.

Programski kod 8.16: Po£etni sadrºaj datoteke vjezba816.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

// uklju£i sva potrebna zaglavlja

uint8_t uzorak_procitan = 0; // logi£ka varijabla

uint16_t ADC_5; // vrijednost AD pretvorbe na pinu ADC5

// prekidna rutina za timer3

ISR(TIMER3_OVF_vect)

TCNT3 = 0; // po£etna vrijednost registra

ADC_5 = adc_read(ADC5); // ADC na kanalu ADC5

uzorak_procitan = 1;

void inicijalizacija ()

// inicijalizacija za timer3

// inicijalizacija LCD displeja

// inicijalizacija AD pretvorbe

// globalno omogu¢i prekide //sei();

TCNT3 = 0; // po£etna vrijednost registra

int main(void)

inicijalizacija ();

float U_ADC5; // napon na pinu ADC5

const float V_REF = 5.0; // AVCC je referentni napon

DigitalInput tipka(D0); // digitalni ulaz - tipka PD0

tipka.pullup_on (); // uklju£enje pull up otpornika na PD0

while (1)

if(tipka.state() == false)

timer3_interrupt_OVF_enable ();

else

timer3_interrupt_OVF_disable ();

8.1 Vjeºbe - Normalan na£in rada tajmera 121

lcd_clrscr ();

if(uzorak_procitan == 1)

U_ADC5 = ADC_5 * V_REF / 1023; // pretvorba u napon

lcd_clrscr ();

lcd_home ();

lcd_print("UADC5 = %.2fV", U_ADC5);

uzorak_procitan = 0;

return 0;

U programskom kodu 8.16 prvo je potrebno uklju£iti sva zaglavlja koja nedostaju. Primijetiteda se u vjeºbi koriste LCD displej, analogno-digitalna pretvorba, tajmer i prekidi. U vjeºbije potrebno svakih 800 ms o£itati uzorak s analognog senzora spojenog na pin ADC5 ako jepritisnuto tipkalo spojeno na pin PD0. U praksi se to uvijek radi s tajmerima jer uvijek postojizahtjev za preciznost uzimanja uzoraka.

Mjerenje analognim senzorom provodi se pomo¢u prekidne rutine ISR(TIMER3_OVF_vect).Uzorke je potrebno uzimati svakih 800 ms (tT3 = 0,8 s) pa je po£etna vrijednost registra TCNT3izra£unata prema korigiranoj relaciji (8.2):

TCNT30 = 65536− tT3 ·F_CPU

PRESCALER_1= 65536− 0, 8 · 16000000

256= 15536. (8.15)

Upi²ite po£etnu vrijednost registra TCNT3 na odgovaraju¢a mjesta u programskom kodu 8.16.U funkciji inicijalizacija() potrebno je inicijalizirati brojne ureaje. U programski kod 8.16upi²ite sljede¢e funkcije:

• timer3_set_normal_mode() - postavljanje sklopa Timer/Counter3 u normalnan na£inrada,

• timer3_set_prescaler(TIMER1_PRESCALER_256) - postavljanje djelitelj frekvencijeradnog takta za sklop Timer/Counter3 na iznos 256 (prema relaciji (8.15)),

• lcd_init() - inicijalizacija LCD displeja,

• adc_init() - inicijalizacija AD pretvorbe,

• interrupt_enable() - omogu¢enje prekida na globalnoj razini.

U funkciji main() stvoren je objekt tipka tipa digitalni ulaz na pinu PD0 te je uklju£enpritezni otpornik na pinu PD0. Prekidna rutina ISR(TIMER3_OVF_vect) poziva se samo ako jeomogu¢en prekid koji izaziva preljev u registru TCNT3. Unutar while(1) petlje provjeravamo jeli pritisnuto tipkalo te:

• ako je tipkalo pritisnuto (tipka.state()== false), tada je potrebno omogu¢iti prekid kojise izaziva preljevom registra TCNT3 pomo¢u funkcije timer3_interrupt_OVF_enable(),

• ina£e, ako tipkalo nije pritisnuto, tada je potrebno onemogu¢iti prekid koji se izazivapreljevom registra TCNT3 pomo¢u funkcije timer3_interrupt_OVF_disable() i izbrisatitekst na LCD displeju.

Na gore navedeni na£in ostvarili smo funkcionalnost uzimanja uzoraka samo kada je tipkalospojeno na PD0 pritisnuto.

122 Tajmeri i broja£i

Vrijednost napona na analognom ulazu ADC5 ispisujemo na LCD displeju ako jezadovoljen uvjet if (uzorak_procitan == 1). Varijablu uzorak_procitan koristimo kaoindikaciju da nam je na raspolaganju novi uzorak koji moºemo ispisati na LCD displeju. Ovuvarijablu deklarirali smo kao globalnu i dodijelili joj vrijednost 0 (nije dostupan novi uzorakza ispis na LCD displej). Uvijek kada se pozove prekidna rutina ISR(TIMER3_OVF_vect),varijabli uzorak_procitan dodjeljujemo vrijednost 1 (dostupan je novi uzorak za ispis na LCDdisplej). Prilikom ispisa napona s analognog senzora na LCD displej, varijabli uzorak_procitandodjeljujemo vrijednost 0. Ovaj postupak neophodan je kako bismo na LCD displeju sprije£ilineprestano ispisivanje napona koje bi rezultiralo ne£itljivim prikazom na njemu. Primijetite kakoje i varijabla ADC_5 u koju se sprema rezultat analogno-digitalne pretvorbe na analognom ulazuADC5 deklarirana kao globalna varijabla. Razlog tome je taj ²to se ovoj varijabli pristupa i umain() funkciji i u prekidnoj rutini ISR(TIMER3_OVF_vect), stoga doseg ove varijable mora bitiglobalan.

Prevedite datoteku vjezba816.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£om ATmega32U4.

Zatvorite datoteku vjezba816.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

8.1 Vjeºbe - Normalan na£in rada tajmera 123

8.1.1 Zadaci - Normalan na£in rada tajmera

Zadatak 8.1.1

Napravite program u kojem ¢ete pomo¢u sklopa Timer/Counter0 mijenjati stanje plave LEDdiode svakih 16 ms. Plava LED dioda spojena je na pin PB7. Istovremeno je na LCD displejupotrebno ispisivati vrijeme rada mikroupravlja£a u minutama. Minute generirajte tako dapostavite ka²njenje while petlje od 60 s.

Zadatak 8.1.2

Napravite program u kojem ¢ete pomo¢u sklopa Timer/Counter1 mijenjati stanje zelene LEDdiode svakih 180 ms. Zelena LED dioda spojena je na pin PB6. Istovremeno je na LCDdispleju potrebno ispisivati vrijeme rada mikroupravlja£a u minutama. Minute generirajte takoda postavite ka²njenje while petlje od 60 s.

Zadatak 8.1.3

Napravite program u kojem ¢ete pomo¢u sklopa Timer/Counter3 mijenjati stanje zelene LEDdiode svakih 1400 ms. Zelena LED dioda spojena je na pin PB6. Istovremeno je na LCDdispleju potrebno ispisivati vrijeme rada mikroupravlja£a u minutama. Minute generirajte takoda postavite ka²njenje while petlje od 60 s.

Zadatak 8.1.4

Napravite program u kojem ¢ete pomo¢u sklopa Timer/Counter0 mijenjati stanje crvene LEDdiode svakih 450 ms, pomo¢u sklopa Timer/Counter1 mijenjati stanje ºute LED diode svakih450 ms, a pomo¢u sklopa Timer/Counter3 mijenjati stanje zelene LED diode svakih 450 ms.Crvena LED dioda spojena je na pin PB4, ºuta LED dioda spojena je na pin PB5, a zelenaLED dioda spojena je na pin PB6. Istovremeno je na LCD displeju potrebno ispisivati vrijemerada mikroupravlja£a u minutama. Minute generirajte tako da postavite ka²njenje while petljeod 60 s.

Zadatak 8.1.5

Napravite program koji ¢e omogu¢iti tzv. beskona£no tr£anje svih LED dioda svakih 320 msi to redoslijedom plava → zelena → ºuta → crvena → plava →... . Izmjenu stanja LED diodasvakih 320 ms ostvarite pomo¢u sklopa Timer/Counter3. Crvena LED dioda spojena je nadigitalni pin PB4, ºuta LED dioda spojena je na digitalni pin PB5, zelena LED dioda spojenaje na digitalni pin PB6, a plava LED dioda spojena je na digitalni pin PB7. Istovremeno je naLCD displeju potrebno ispisivati vrijeme rada mikroupravlja£a u minutama. Minute generirajtetako da postavite ka²njenje while petlje od 60 s.

124 Tajmeri i broja£i

Zadatak 8.1.6

Napravite program u kojem ¢e se, ako je pritisnuto tipkalo spojeno na pin PF7, uzimati uzorcis analognog senzora spojenog na pin ADC5. Vrijeme uzorkovanja neka iznosi 700 ms. Uzimanjeuzoraka ostvarite u prekidnoj rutini ISR(TIMER1_OVF_vect). Vrijednost napona na pinu ADC5ispi²ite na LCD displej u while petlji samo kada se uzimaju uzorci.

8.2 Vjeºbe - PWM na£in rada tajmera

8.2.1 Fast PWM na£in rada tajmera

Fast PWM na£in rada bit ¢e obja²njen na sklopu Timer/Counter0 za kanal A. U Fast PWMna£inu rada tajmera na temelju vrijednosti u registrima TCNT0 te registrima OCR0A (kanal A),odnosno OCR0B (kanal B) generira se pravokutni valni oblik visoke frekvencije na pinu PB7(OC0A), odnosno pinu PD0 (OC0B). PWM naj£e²¢e se koristi kod upravljanja brzinom vrtnjeistosmjernog motora, pretvara£a napona, promjene inteziteta LED rasvjete i sli£no. Vremenskidijagram Fast PWM na£ina rada prikazan je na slici 8.5. Vrijednost registra TCNT0 cijelo sevrijeme uve¢ava za 1 i kre¢e se od 0 (DNO) do 255 (VRH). Nakon ²to registar TCNT0 postignevrijednost 255, ponovno se postavlja u 0 te uve¢ava za 1 prema gore. U registar OCR0A moºemoupisati vrijednosti u rasponu od [0, 255]. Vrijednost u registru OCR0A osvjeºava se svaki put kadavrijednost registra TCNT0 prelazi iz 255 u 0.

TCNT0

0

255

PB7 (OC0A)

0

5 V

OCR0A = 85 OCR0A = 122 OCR0A = 122

Osvježavanje

vrijednosti

registra OCR0A

OCR0A = 200OCR0A = 200

0

5 V

PB7 (OC0A)

COM0A0 = 0COM0A1 = 1

COM0A0 = 1COM0A1 = 1

t

t

t

T

DT

Slika 8.5: Vremenski dijagram Fast PWM na£ina rada

8.2 Vjeºbe - PWM na£in rada tajmera 125

Vrijednosti registara TCNT0 i OCR0A cijelo se vrijeme usporeuju. U trenutku kada sevrijednosti ovih dvaju registara izjedna£e (TCNT0 == OCR0A) na pinu PB7 (OC0A) se de²avapromjena stanja signala iz visokog u nisko ili obratno, ²to ovisi o konguraciji bitova COM0A1 iCOM0A0. Ovisno o stanju bitova COM0A1 i COM0A0, prema tablici 8.3 na pinu PB7 (OC0A) generirase pravokutni valni oblik prikazan na slici 8.5.

Tablica 8.3: Postavke bitova COM0A1 i COM0A0 u Fast PWM na£ina rada (kanal A) [1]

COM0A1 COM0A0 Postavke Fast PWM na£ina rada

0 0 Pin PB7 (OC0A) isklju£en

0 1Ako je WGM02 = 0, tada je pin PB7 (OC0A) isklju£en.

Ako je WGM02 = 1, promjena stanja pina PB7 (OC0A) dogaa sekada je vrijednost registra TCNT0 jednaka vrijednosti registra OCR0A.

1 0

Pin PB7 (OC0A) postavlja se u nisko stanje kada jevrijednost registra TCNT0 jednaka vrijednosti registra OCR0A.Pin PB7 (OC0A) postavlja se u visoko stanje kada vrijednost

registra TCNT0 prijee iz 255 (VRH) u 0 (DNO).

1 1

PB7 (OC0A) postavlja se u visoko stanje kada jevrijednost registra TCNT0 jednaka vrijednosti registra OCR0A.PB7 (OC0A) postavlja se u nisko stanje kada vrijednost

registra TCNT0 prijee iz 255 (VRH) u 0 (DNO).

Ako je konguracija bitova COM0A1 = 1 i COM0A0 = 0, tada se pin PB7 (OC0A) postavljau nisko stanje kada je vrijednost registra TCNT0 jednaka vrijednosti registra OCR0A, a u visokostanje kada vrijednost registra TCNT0 prijee iz 255 u 0. Ovakva vrsta konguracije generiraneinvertiraju¢i PWM signal (slika 8.5).

Ako je konguracija bitova COM0A1 = 1 i COM0A0 = 1, tada se pin PB7 (OC0A) postavljau visoko stanje kada je vrijednost registra TCNT0 jednaka vrijednosti registra OCR0, a u niskostanje kada vrijednost registra TCNT0 prijee iz 255 u 0. Ovakva vrsta konguracije generirainvertiraju¢i PWM signal (slika 8.5).

Blokovska shema na slici 8.2 prikazuje sklopovski dio koji provjerava jednakost registara TCNT0i OCR0A te dio koji generira valni oblik na pinu PB7 (OC0A). PWM signal moºe se generirati ina pinu PD0 (OC0B) (kanal B) pomo¢u sklopa Timer/Counter0, no tada je potrebno pogledatikonguraciju bitova COM0B1 i COM0B0 u literaturi [1] u tablici 13-5. PWM signal mogu generiratii ostala dva sklopa: Timer/Counter1 i Timer/Counter3. Konguraciju PWM sklopova moºeteprona¢i u literaturi [1] u tablicama 14-1 do 14-4.

Frekvencija PWM signala u Fast PWM na£inu rada za sklop Timer/Counter0 jest:

F_fPWM =F_CPU

PRESCALER · (TOP + 1)=

F_CPUPRESCALER · 256

, (8.16)

a period PWM signala jest:

T =1

F_fPWM=PRESCALER · (TOP + 1)

F_CPU=PRESCALER · 256

F_CPU. (8.17)

Frekvencija i period PWM signala ovise samo o djelitelju frekvencije radnog takta, odnosnoo varijabli PRESCALER. Varijablu PRESCALER odabiremo sukladno potrebama sustavana koji dovodimo PWM signal te o brzini elektroni£kih komponenata koje u sustav dovodeenergiju. Varijabla TOP za sklop Timer/Counter0 iznosi 255, dok za sklopove Timer/Counter1

126 Tajmeri i broja£i

i Timer/Counter3 moºe iznositi 255, 511, 1023, kao i proizvoljan iznos u rasponu [0, 65535]2.irina impulsa neinvertiraju¢eg PWM signala na kanalu A odreena je vremenom visokog stanjaTD (engl. duty cycle) u odnosu na vrijeme perioda T (slika 8.5) prema relaciji:

TDT

=OCR0A

255. (8.18)

irinu PWM signala na pinu PB7 (OC0A) mijenjamo promjenom vrijednosti registra OCR0Aprema relaciji:

OCR0A =TDT· 255. (8.19)

Slu£ajevi u kojima registar OCR0A poprima vrijednost 0 (DNO) ili 255 (VRH) specijalni suslu£ajevi. Kod neinvertiraju¢eg PWM signala (COM0A1 = 1, COM0A0 = 0) za specijalne slu£ajevevrijedi:

• ako je OCR0A = 255, tada je pin PB7 (OC0A) konstantno u visokom stanju,

• ako je OCR0A = 0, tada ¢e se se na pinu PB7 (OC0A) generirati uski ²iljak.

Na primjer, ako upravljamo intezitetom LED diode u slu£aju kada je OCR0A = 0, LED dioda¢e sjajiti najmanjim mogu¢im intezitetom zbog uskog ²iljka PWM signala iako bismo o£ekivalida ¢e LED dioda biti isklju£ena. Ovo svakako spada u nedostatak Fast PWM na£ina rada. Tajnedostatak nema Phase Correct PWM na£in rada koji ¢e biti opisan u sljede¢em potpoglavlju.

Ako se koristi kanal B (uz WGM02 = 0), tada ²irinu PWM signala na pinu PD0 (OC0B)mijenjamo promjenom vrijednosti registra OCR0B prema relaciji:

OCR0B =TDT· 255. (8.20)

Omjer TDT predstavlja postotak aktivnog stanja neinvertiraju¢eg PWM signala.

Pretpostavimo da PWM signal koristimo u silaznom pretvara£u za koji vrijedi da se istosmjerninapon UDC (npr. UDC = 30 V) pretvara u raspon od [0, UDC ] V. Neinvertiraju¢i PWM signal napinu PB7 (OC0A) upravlja radom sklopke u izvedbi unipolarnog tranzistora. Ozna£imo izlazninapon na silaznom pretvara£u Ui. Izlazni napon moºe se izra£unati prema relaciji:

Ui =TDT· UDC =

OCR0A

255· UDC . (8.21)

Napon na izlazu iz silaznog pretvara£a mijenjamo promjenom vrijednosti registra OCR0 premarelaciji:

OCR0A =UiUDC

· 255. (8.22)

U programskom kodu 8.17 prikazana je konguracija tajmera u Fast PWM na£inu rada.

Programski kod 8.17: Konguracija tajmera u Fast PWM na£inu rada

TCCR0B |= (0 << CS02) | (1 << CS01) | (0 << CS00); // F_CPU /8

TCCR0A |= (1 << WGM01) | (1 << WGM00); // Fast PWM na£in rada

TCCR0B |= (0 << WGM02); // VRH je 0x0FF

TCCR0A |= (1 << COM0A1) | (0 << COM0A0); // Neinvertiraju¢i PWM

OCR0A = 100;

2Detalje o proizvoljnom iznosu moºete prona¢i u literaturi [1] u tablicama 14-1 do 14-4. Preporuka autora jestda se koristi raspon [100, 65535] kako bi imali dovoljnu rezoluciju promjene ²irine impulsa PWM signala.

8.2 Vjeºbe - PWM na£in rada tajmera 127

Naredbom TCCR0B |= (0 << CS02)| (1 << CS01)| (0 << CS00); frekvenciju radnogtakta podijelili smo s 8, prema tablici 8.1. Frekvencija PWM signala prema relaciji 8.16 jest:

F_fPWM =F_CPU

PRESCALER · 256=

16000000

8 · 256= 7812, 5Hz. (8.23)

Fast PWM na£in rada tajmera odabran je naredbom TCCR0A |= (1 << WGM01)| (1 << WGM00);prema tablici 8.2. Neinvertiraju¢i na£in rada odabran je naredbomTCCR0A |= (1 << COM0A1)| (0 << COM0A0);. U tom na£inu rada vrijednost registraOCR0A postavljena je na 100. Ukoliko je ovo konguracija PWM signala koji upravlja silaznimpretvara£em koji je prethodno spomenut, izlazni napon za konguraciju prikazanu programskimkodom 8.17 moºe se izra£unati prema relaciji (8.21):

Ui =OCR0A

255· UDC =

100

255· 30 = 11.765V. (8.24)

Ako na izlazu ºelimo posti¢i vrijednost izlaznog napona 25 V, tada je u registar OCR0Apotrebno upisati vrijednost dobivenu relacijom (8.22):

OCR0A =UiUDC

· 255 =25

30· 255 = 213. (8.25)

Za sklopove Timer/Counter1 i Timer/Counter2 konguracija Fast PWM na£ina rada sli£naje prethodno provedenoj konguraciji sklopa Timer/Counter0. Za sve detalje o konguracijisklopova Timer/Counter1 i Timer/Counter2 pogledajte literaturu [1].

8.2.2 Phase Correct PWM na£in rada tajmera

Druga vrsta PWM signala koja se moºe generirati mikroupravlja£em ATmega32U4 jest PhaseCorrect PWM. I ovaj na£in rada bit ¢e obja²njen na sklopu Timer/Counter0 za kanal A. Zarazliku od Fast PWM na£inu rada, Phase Correct PWM na£in rada ima dvostruko manjufrekvenciju. Razlog tome je taj ²to u Phase Correct PWM na£inu rada registar TCNT0 uve¢avasvoju vrijednost za 1 od 0 (DNO) do 255 (VRH), a kada doe do vrijednosti 255 po£inje smanjivatisvoju vrijednost za 1 do 0 i tako uzastopno. Na temelju vrijednosti u registrima TCNT0 teregistrima OCR0A (kanal A), odnosno OCR0B (kanal B) generira se pravokutni valni oblik na pinuPB7 (OC0A), odnosno pinu PD0 (OC0B). U registar OCR0Amoºemo upisati vrijednosti u rasponuod [0, 255]. Vrijednost u registru OCR0A osvjeºava se svaki put kada vrijednost registra TCNT0dosegne 255.

128 Tajmeri i broja£i

TCNT0

0

255

PB7 (OC0A)

0

5 V

OCR0A = 85 OCR0A = 122

Osvježavanje

vrijednosti

registra OCR0A

OCR0A = 200

0

5 V

PB7 (OC0A)

COM0A0 = 0COM0A1 = 1

COM0A0 = 1COM0A1 = 1

T

DT

t

t

t

Slika 8.6: Vremenski dijagram Fast PWM na£ina rada

Vrijednosti registara TCNT0 i OCR0A cijelo se vrijeme usporeuju. U trenutku kada sevrijednosti ovih dvaju registara izjedna£e (TCNT0 == OCR0A), na pinu PB7 (OC0A) de²ava sepromjena stanja signala iz visokog u nisko ili obratno, ²to ovisi o konguraciji bitova COM0A1 iCOM0A0. Ovisno o stanju bitova COM0A1 i COM0A0, prema tablici 8.4 na pinu PB7 (OC0A) generirase pravokutni valni oblik prikazan na slici 8.6.

Tablica 8.4: Postavke bitova COM0A1 i COM0A0 u Phase Correct PWM na£ina rada (kanal A) [1]

COM0A1 COM0A0 Postavke Phase Correct PWM na£ina rada

0 0 Pin PB7 (OC0A) isklju£en

0 1Ako je WGM02 = 0, tada je pin PB7 (OC0A) isklju£en.

Ako je WGM02 = 1, promjena stanja pina PB7 (OC0A) dogaa sekada je vrijednost registra TCNT0 jednaka vrijednosti registra OCR0A.

1 0

Pin PB7 (OC0A) postavlja se u nisko stanje kada je vrijednostregistra TCNT0 jednaka vrijednosti registra OCR0A pri brojanju prema gore.

Pin PB7 (OC0A) postavlja se u visoko stanje kada je vrijednostregistra TCNT0 jednaka vrijednosti registra OCR0A pri brojanju prema dolje.

1 1

Pin PB7 (OC0A) postavlja se u visoko stanje kada je vrijednostregistra TCNT0 jednaka vrijednosti registra OCR0A pri brojanju prema gore.

Pin PB7 (OC0A) postavlja se u nisko stanje kada je vrijednostregistra TCNT0 jednaka vrijednosti registra OCR0A pri brojanju prema dolje.

Ako je konguracija bitova COM0A1 = 1 i COM0A0 = 0, tada se pin PB7 (OC0A) postavljau nisko stanje kada je vrijednost registra TCNT0 jednaka vrijednosti registra OCR0A pri brojanjuprema gore, a u visoko stanje kada je vrijednost registra TCNT0 jednaka vrijednosti registra OCR0Apri brojanju prema dolje. Ovakva vrsta konguracije generira neinvertiraju¢i PWM signal (slika8.6).

Ako je konguracija bitova COM0A1 = 1 i COM0A0 = 1, tada se pin PB7 (OC0A) postavlja uvisoko stanje kada je vrijednost registra TCNT0 jednaka vrijednosti registra OCR0A pri brojanjuprema gore, a u nisko stanje kada je vrijednost registra TCNT0 jednaka vrijednosti registra OCR0A

8.2 Vjeºbe - PWM na£in rada tajmera 129

pri brojanju prema dolje. Ovakva vrsta konguracije generira invertiraju¢i PWM signal (slika8.6).

PWM signal moºe se generirati i na pinu PD0 (OC0B) (kanal B) pomo¢u sklopaTimer/Counter0, no tada je potrebno pogledati konguraciju bitova COM0B1 i COM0B0 u literaturi[1] u tablici 13-6.

Frekvencija PWM signala u Phase Correct PWM na£inu rada za sklop Timer/Counter0 jest:

F_pcPWM =F_CPU

PRESCALER · 2 · TOP=

F_CPUPRESCALER · 510

, (8.26)

a period PWM signala jest:

T =1

F_pcPWM=PRESCALER · 2 · TOP

F_CPU=PRESCALER · 510

F_CPU. (8.27)

Frekvencija i period PWM signala ovise samo o djelitelju frekvencije radnog takta, odnosno ovarijabli PRESCALER. Varijablu PRESCALER odabiremo sukladno potrebama sustava nakoji dovodimo PWM signal te o brzini elektroni£kih komponenata koje u sustav dovode energiju.Vrijednosti koje moºe poprimiti varijabla TOP opisane su u potpoglavlju o Fast PWM na£inurada. irina impulsa neinvertiraju¢eg PWM signala na kanalu A odreena je vremenom visokogstanja TD (engl. duty cycle) u odnosu na vrijeme perioda T (slika 8.5) prema relaciji:

TDT

=OCR0A

255. (8.28)

irinu PWM signala na pinu PB7 (OC0A) mijenjamo promjenom vrijednosti registra OCR0Aprema relaciji:

OCR0A =TDT· 255. (8.29)

Slu£ajevi u kojima registar OCR0A poprima vrijednost 0 (DNO) ili 255 (VRH) specijalni suslu£ajevi. Kod neinvertiraju¢eg PWM signala (COM0A1 = 1, COM0A0 = 0) za specijalne slu£ajevevrijedi:

• ako je OCR0A = 255, tada je pin PB7 (OC0A) konstantno u visokom stanju,

• ako je OCR0A = 0, tada je pin PB7 (OC0A) konstantno u niskom stanju.

Za razliku od Fast PWM na£ina rada, kod Phase Correct PWM na£ina rada ne pojavljujese uski ²iljak u PWM signalu.

Ako se koristi kanal B (uz WGM02 = 0), tada ²irinu PWM signala na pinu PD0 (OC0B)mijenjamo promjenom vrijednosti registra OCR0B prema relaciji:

OCR0B =TDT· 255. (8.30)

Omjer TDT predstavlja postotak aktivnog stanja neinvertiraju¢eg PWM signala. U

programskom kodu 8.18 prikazana je konguracija tajmera u Phase Correct PWM na£inu rada.

Programski kod 8.18: Konguracija tajmera u Phase Correct PWM na£inu rada

TCCR0B |= (0 << CS02) | (1 << CS01) | (0 << CS00); // F_CPU /8

TCCR0A |= (0 << WGM01) | (1 << WGM00); // Phase Correct PWM na£in rada

TCCR0B |= (0 << WGM02); // VRH je 0x0FF

TCCR0A |= (1 << COM0A1) | (0 << COM0A0); // Neinvertiraju¢i PWM

OCR0A = 180;

130 Tajmeri i broja£i

Naredbom TCCR0B |= (0 << CS02)| (1 << CS01)| (0 << CS00); frekvenciju radnogtakta podijelili smo s 8, prema tablici 8.1. Phase Correct PWM na£in rada tajmera odabran jenaredbom TCCR0A |= (0 << WGM01)| (1 << WGM00);, prema tablici 8.2. Neinvertiraju¢i na£inrada odabran je naredbom TCCR0A |= (1 << COM0A1)| (0 << COM0A0);. U tom na£inu radavrijednost registra OCR0A postavljena je na 180. Srednja vrijednost napona na pinu PB7 (OC0A)za konguraciju prikazanu programskim kodom 8.18 moºe se izra£unati prema relaciji (8.21):

Ui =OCR0A

255· 5 =

180

255· 5 = 3.529V. (8.31)

Ako na pinu PB7 (OC0A) ºelimo posti¢i srednju vrijednost napona iznosa UPB7 =1,5 V, tadaje u registar OCR0A potrebno upisati vrijednost dobivenu sljede¢om relacijom (napon napajanjamikroupravlja£a ATmega32U4 iznosi UV CC =5 V):

OCR0A =UPB7

UV CC· 255 =

1, 5

5· 255 = 77. (8.32)

Za sklopove Timer/Counter1 i Timer/Counter2 konguracija Phase Correct PWM na£inarada sli£na je prethodno provedenoj konguraciji sklopa Timer/Counter0. Za sve detalje okonguraciji sklopova Timer/Counter1 i Timer/Counter2 pogledajte literaturu [1].

8.2.3 Konguracija PWM na£ina rada tajmera pomo¢u zaglavlja "timer.h"

Autor je pripremio brojne funkcije koje omogu¢uju jednostavnu konguraciju PWM na£inarada tajmera pomo¢u zaglavlja "timer.h" koje se nalazi u mapi "Timer". U nastavku je popisfunkcija koje se koriste za generiranje PWM signala s opisom:

• timer0_set_fast_PWM() - pode²avanje Fast PWM na£ina rada za sklop Timer/Counter0

• timer0_set_phase_correct_PWM() - pode²avanje Phase Correct PWM na£ina rada zasklop Timer/Counter0,

• timer0_OC0A_enable_non_inverted_PWM() - omogu¢avanje generiranja neinvertiraju¢egPWM signala na kanalu A (OC0A) za sklop Timer/Counter0,

• timer0_OC0A_enable_inverted_PWM() - omogu¢avanje generiranja invertiraju¢eg PWMsignala na kanalu A (OC0A) za sklop Timer/Counter0,

• timer0_OC0A_disable() - onemogu¢avanje generiranja PWM signala na kanalu A (OC0A)za sklop Timer/Counter0,

• OC0A_set_duty_cycle(float duty) - postavljanje ²irine impulsa na kanalu A (OC0A) zasklop Timer/Counter0. Funkcija prima argument duty u rasponu [0, 100.0] koja predstavlja²irinu impulsa PWM signala.

• timer0_OC0B_enable_non_inverted_PWM() - omogu¢avanje generiranja neinvertiraju¢egPWM signala na kanalu B (OC0B) za sklop Timer/Counter0,

• timer0_OC0B_enable_inverted_PWM() - omogu¢avanje generiranja invertiraju¢eg PWMsignala na kanalu B (OC0B) za sklop Timer/Counter0,

• timer0_OC0B_disable() - onemogu¢avanje generiranja PWM signala na kanalu B (OC0B)za sklop Timer/Counter0,

8.2 Vjeºbe - PWM na£in rada tajmera 131

• OC0B_set_duty_cycle(float duty) - postavljanje ²irine impulsa na kanalu B (OC0B) zasklop Timer/Counter0. Funkcija prima argument duty u rasponu [0, 100.0] koja predstavlja²irinu impulsa PWM signala.

• timer1_set_fast_PWM_8bit() - pode²avanje Fast PWM na£ina rada za sklopTimer/Counter1 s vr²nom vrijedno²¢u 255 (brojanje u rasponu [0, 255], konstanta zaodreivanje raspona brojanja je PWM_8BIT),

• timer1_set_fast_PWM_9bit() - pode²avanje Fast PWM na£ina rada za sklopTimer/Counter1 s vr²nom vrijedno²¢u 511 (brojanje u rasponu [0, 511], konstanta zaodreivanje raspona brojanja je PWM_9BIT),

• timer1_set_fast_PWM_10bit() - pode²avanje Fast PWM na£ina rada za sklopTimer/Counter1 s vr²nom vrijedno²¢u 1023 (brojanje u rasponu [0, 1023], konstanta zaodreivanje raspona brojanja je PWM_10BIT),

• timer1_set_fast_PWM_ICR1(uint16_t top) - pode²avanje Fast PWM na£ina rada zasklop Timer/Counter1 s vr²nom vrijedno²¢u top (brojanje u rasponu [0, top], konstantaza odreivanje raspona brojanja je PWM_ICR1). Vr²na vrijednost top zapisuje se u registarICR1 i moºe poprimiti vrijednosti u rasponu [0, 65535].

• timer1_set_phase_correct_PWM_8bit() - pode²avanje Phase Correct PWM na£ina radaza sklop Timer/Counter1 s vr²nom vrijedno²¢u 255 (brojanje u rasponu [0, 255], konstantaza odreivanje raspona brojanja je PWM_8BIT),

• timer1_set_phase_correct_PWM_9bit() - pode²avanje Phase Correct PWM na£ina radaza sklop Timer/Counter1 s vr²nom vrijedno²¢u 511 (brojanje u rasponu [0, 511], konstantaza odreivanje raspona brojanja je PWM_9BIT),

• timer1_set_phase_correct_PWM_10bit() - pode²avanje Phase Correct PWM na£ina radaza sklop Timer/Counter1 s vr²nom vrijedno²¢u 1023 (brojanje u rasponu [0, 1023],konstanta za odreivanje raspona brojanja je PWM_10BIT),

• timer1_set_phase_correct_PWM_ICR1(uint16_t top) - pode²avanje Phase CorrectPWM na£ina rada za sklop Timer/Counter1 s vr²nom vrijedno²¢u top (brojanje u rasponu[0, top], konstanta za odreivanje raspona brojanja je PWM_ICR1). Vr²na vrijednost topzapisuje se u registar ICR1 i moºe poprimiti vrijednosti u rasponu [0, 65535].

• timer1_OC1A_enable_non_inverted_PWM() - omogu¢avanje generiranja neinvertiraju¢egPWM signala na kanalu A (OC1A) za sklop Timer/Counter1,

• timer1_OC1A_enable_inverted_PWM() - omogu¢avanje generiranja invertiraju¢eg PWMsignala na kanalu A (OC1A) za sklop Timer/Counter1,

• timer1_OC1A_disable() - onemogu¢avanje generiranja PWM signala na kanalu A (OC1A)za sklop Timer/Counter1,

• OC1A_set_duty_cycle(float duty, uint16_t top) - postavljanje ²irine impulsa nakanalu A (OC1A) za sklop Timer/Counter1. Funkcija prima argument duty u rasponu [0,100.0] koji predstavlja ²irinu impulsa PWM signala te argument top koji moºe poprimitidenirane konstante (vidi programski kod 8.19): PWM_8BIT, PWM_9BIT, PWM_10BIT,PWM_ICR1.

• timer1_OC1B_enable_non_inverted_PWM() - omogu¢avanje generiranja neinvertiraju¢egPWM signala na kanalu B (OC1B) za sklop Timer/Counter1,

132 Tajmeri i broja£i

• timer1_OC1B_enable_inverted_PWM() - omogu¢avanje generiranja invertiraju¢eg PWMsignala na kanalu B (OC1B) za sklop Timer/Counter1,

• timer1_OC1B_disable() - onemogu¢avanje generiranja PWM signala na kanalu B (OC1B)za sklop Timer/Counter1,

• OC1B_set_duty_cycle(float duty, uint16_t top) - postavljanje ²irine impulsa nakanalu B (OC1B) za sklop Timer/Counter1. Funkcija prima argument duty u rasponu [0,100.0] koji predstavlja ²irinu impulsa PWM signala te argument top koji moºe poprimitidenirane konstante (vidi programski kod 8.19): PWM_8BIT, PWM_9BIT, PWM_10BIT,PWM_ICR1.

• timer1_OC1C_enable_non_inverted_PWM() - omogu¢avanje generiranja neinvertiraju¢egPWM signala na kanalu C (OC1C) za sklop Timer/Counter1,

• timer1_OC1C_enable_inverted_PWM() - omogu¢avanje generiranja invertiraju¢eg PWMsignala na kanalu B (OC1C) za sklop Timer/Counter1,

• timer1_OC1C_disable() - onemogu¢avanje generiranja PWM signala na kanalu C (OC1C)za sklop Timer/Counter1,

• OC1C_set_duty_cycle(float duty, uint16_t top) - postavljanje ²irine impulsa nakanalu C (OC1C) za sklop Timer/Counter1. Funkcija prima argument duty u rasponu [0,100.0] koji predstavlja ²irinu impulsa PWM signala te argument top koji moºe poprimitidenirane konstante (vidi programski kod 8.19): PWM_8BIT, PWM_9BIT, PWM_10BIT,PWM_ICR1.

Programski kod 8.19: Deniranje konstanti koje predstavljaju vr²ne vrijednosti rasponabrojanja

//TOP vrijednost za PWM signale

#define PWM_8BIT 255

#define PWM_9BIT 511

#define PWM_10BIT 1023

#define PWM_ICR1 ICR1

U sljede¢im vjeºbama bit ¢e prikazan niz funkcija koje su napisane za konguriranje PWMna£ina rada, a koje se nalaze u biblioteci timer.h.

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku PWM.zip. Na radnoj povr²inistvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢i pritom dijakriti£keznakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢ete stvoriti zvat ¢e seIvica Ivic. Datoteku PWM.zip raspakirajte u novostvorenu datoteku na radnoj povr²ini.Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini te dvostrukim klikom pokreniteVUB mikroracunala.atsln u datoteci \\PWM\vjezbe. U otvorenom projektu nalaze se sve vjeºbekoje ¢emo obraditi u poglavlju Tajmeri i broja£i. Vjeºbe ¢emo pisati u datoteke s ekstenzijom*.cpp.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koja moºete koristiti za provjeru ispravnostiprogramskih zadataka.

8.2 Vjeºbe - PWM na£in rada tajmera 133

Vjeºba 8.2.1

Napravite program koji ¢e na pinu PB7 (OC0A) generirati neinvertiraju¢i PWM signal pomo¢usklopa Timer/Counter0. Frekvenciju PWM signala namjestite tako da bude ve¢a od 3 kHz, amanja od 10 kHz. Svakih 1000 ms u while petlji mijenjajte ²irinu impulsa PWM signala, tako daona iznosi redom 10 %→ 40 %→ 90 %→ 10 % perioda T . Po mogu¢nosti, osciloskopom pratitiPWM signal na pinu PB7 (OC0A). Koristite Fast PWM na£ina rada sklopa Timer/Counter0.

U projektnom stablu otvorite datoteku vjezba821.cpp. Omogu¢ite samo prevoenjedatoteke vjezba821.cpp. Po£etni sadrºaj datoteke vjezba821.cpp prikazan je programskimkodom 8.20.

Programski kod 8.20: Po£etni sadrºaj datoteke vjezba821.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

void inicijalizacija ()

// inicijalizacija za timer 0 - neinvertiraju¢i Fast PWM

timer0_set_prescaler(TIMER0_PRESCALER_8);

timer0_set_fast_PWM ();

timer0_OC0A_enable_non_inverted_PWM ();

output_port(DDRB ,PB7);

int main(void)

inicijalizacija ();

while (1)

OCR0A = 0;

_delay_ms (1000);

OCR0A = 0;

_delay_ms (1000);

OCR0A = 0;

_delay_ms (1000);

return 0;

U ovoj vjeºbi sklop Timer/Counter0 koristit ¢emo u Fast PWM na£inu rada. PWM signalgenerirat ¢emo na kanalu A, odnosno na pinu PB7 (OC0A). Frekvencija PWM signala morabiti ve¢a od 3 kHz, a manja od 10 kHz. Prema relaciji (8.16), frekvencija PWM signala ovisi ofrekvenciji radnog takta F_CPU i o djelitelju frekvencije radnog takta. Frekvencija radnog taktajest 16 MHz pa je potrebno odabrati djelitelj frekvencije radnog takta za koji ¢e vrijediti dafrekvencija bude izmeu 3 i 10 kHz. Za djelitelj frekvencije radnog takta odabrat ¢emo 8. Premarelaciji (8.16), frekvencija PWM signala bit ¢e:

F_fPWM =F_CPU

PRESCALER · 256=

16000000

8 · 256= 7812, 5 Hz = 7.81 kHz. (8.33)

Dobivena frekvencija PWM signala u relaciji (8.39) ve¢a je od 3 kHz i manja od 10kHz. Poku²ajte u relaciju (8.16) uvrstiti ostale vrijednosti djelitelj frekvencije radnog taktakako bismo ustanovili sve mogu¢e frekvencije PWM signala pomo¢u sklopa Timer/Counter0.U programskom kodu 8.20 u funkciji inicijalizacija() djelitelj frekvencije radnog takta

134 Tajmeri i broja£i

iznosa 8 konguriran je funkcijom timer0_set_prescaler(TIMER0_PRESCALER_8). Fast PWMna£in rada ²to postavlja se pozivom funkcije timer0_set_fast_PWM(). PWM signal mora bitineinvertiraju¢i, a to se postiºe pozivom funkcije timer0_OC0A_enable_non_inverted_PWM().Obje prethodne funkcije pozvane su u funkciji inicijalizacija(). Sve kori²tene funkcije zakonguriranje Fast PWM na£ina rada nalaze se u zaglavlju timer.h, stoga je ovo zaglavljepotrebno uklju£iti u programski kod. PWM signal generira se na pinu PB7 (OC0A) pa ga jepotrebno kongurirati kao izlazni pin. Ukoliko zaboravite pin PB7 kongurirati kao izlazni, nanjemu se ne¢e generirati PWM signal.

Nakon konguracije neinvertiraju¢eg PWM signala potrebno je odrediti vrijednosti registraOCR0A za koju ¢e ²irina impulsa PWM signala biti 10 %, 40 % i 90 % perioda T . Prema relaciji(8.20) vrijednost OCR0A registra za ²irinu PWM signala 10 % perioda T bit ¢e:

OCR0A =TDT· 255 = 0, 1 · 255 = 26. (8.34)

Prema relaciji (8.20) vrijednost OCR0A registra za ²irinu PWM signala 40 % perioda T bit ¢e:

OCR0A =TDT· 255 = 0, 4 · 255 = 102. (8.35)

Prema relaciji (8.20) vrijednost OCR0A registra za ²irinu PWM signala 90 % perioda T bit ¢e:

OCR0A =TDT· 255 = 0, 9 · 255 = 230. (8.36)

U programski kod 8.20 upi²ite izra£unate vrijednosti registra OCR0A u while petlju ispredsvakog ka²njenja iznosa 1000 ms. Ako mikroupravlja£ koristite samo za generiranje PWM signala,tada u funkciji main obavezno morate napraviti beskona£nu while petlju. Kada ne biste napravilibeskona£nu petlju, mikroupravlja£ ne bi generirao PWM signal jer bi zavr²io s izvoenjem mainfunkcije.

Prevedite datoteku vjezba821.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.PWM signal pratit ¢emo pomo¢u osciloskopa. Spajanje sonde osciloskopa na razvojno okruºenje smikroupravlja£em ATmega32U4 prikazano je na slici 8.7.

Slika 8.7: Spajanje sonde osciloskopa na razvojno okruºenje s mikroupravlja£em ATmega32U4

Na razvojnom okruºenju s mikroupravlja£em ATmega32U4 pinovi su izvu£eni na ravnepriklju£nice na kojima su ozna£ena imena pinova. Na slici 8.7 prikazane su dvije ravne

8.2 Vjeºbe - PWM na£in rada tajmera 135

priklju£nice. Sondu osciloskopa potrebno je spojiti izmeu dvaju spojnih mjesta na ravnimpriklju£nicama: GND i PB7 (slika 8.7). Na osciloskopu prikaºite tri perioda PWM signalate frekvenciju PWM signala. Prikaz ²irine impulsa na pinu PB7 (OC0A) pomo¢u osciloskopaprikazan je na slici 8.8.

irina impulsa moºe se denirati kori²tenjem funkcije OC0A_set_duty_cycle(float duty)koja kao argument prima ²irinu impulsa PWM signala u rasponu od 0 % fo 100 %. Na primjer,ukoliko ºelite na pinu PB7 (OC0A) postaviti ²irinu impulsa iznosa 40 %, dovoljno je pozvatifunkciju OC0A_set_duty_cycle(40.0). Zamijenite sva pridruºivanja vrijednosti u registar OCR0Au while petlju s navedenom funkcijom.

(a) TD = 10% (b) TD = 40% (c) TD = 90%

Slika 8.8: Prikaz ²irine impulsa na pinu PB7 (OC0A) pomo¢u osciloskopa

U programski kod 8.20 funkciju timer0_OC0A_enable_non_inverted_PWM() zamijenite sfunkcijom timer0_OC0A_enable_inverted_PWM(). Prevedite datoteku vjezba821.cpp u strojnikod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenjus mikroupravlja£em ATmega32U4. Komentirajte pona²anje LED diode spojene na pin PB7(OC0A) u odnosu na prethodni programski kod. Pogledajte sada PWM signal generiran na pinuPB7 (OC0A) pomo¢u osciloskopa.

U programski kod 8.20 tijelo funkcije inicijalizacija() zamijenite programskim kodom8.21. Ovaj pristup sloºeniji je od kori²tenja gotovih funkcija iz zaglavlja timer.h jer zahtijevapode²enje registara prema tablicama 8.2 i 8.3. Prevedite datoteku vjezba821.cpp u strojni kodi snimite ga na mikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenju smikroupravlja£em ATmega32U4.

Programski kod 8.21: Konguracija tajmera u Fast PWM na£inu rada (djelitelj frekvencijeradnog takta iznosi 8, PWM signal je neinvertiraju¢i)

TCCR0B |= (0 << CS02) | (1 << CS01) | (0 << CS00); // F_CPU /8

TCCR0A |= (1 << WGM01) | (1 << WGM00); // Fast PWM na£in rada

TCCR0B |= (0 << WGM02); // VRH je 0x0FF

TCCR0A |= (1 << COM0A1) | (0 << COM0A0); // Neinvertiraju¢i PWM

DDRB |= (1 << PB7); // PB7 izlazni pin

Zatvorite datoteku vjezba821.cpp i onemogu¢ite prevoenje ove datoteke.

136 Tajmeri i broja£i

Vjeºba 8.2.2

Napravite program koji ¢e na pinu PB7 (OC0A) generirati neinvertiraju¢i PWM signal pomo¢usklopa Timer/Counter0. Frekvenciju PWM signala namjestite tako da bude ve¢a od 3 kHz, amanja od 10 kHz. Omogu¢ite promjenu ²irine impulsa PWM signala pomo¢u potenciometraspojenog na pin ADC5. Na LCD displeju ispi²ite frekvenciju PWM signala i ²irinu impulsaPWM signala u postocima. Po mogu¢nosti, osciloskopom pratiti PWM signal na pinu PB7(OC0A). Koristite Fast PWM na£ina rada sklopa Timer/Counter0.

U projektnom stablu otvorite datoteku vjezba822.cpp. Omogu¢ite samo prevoenjedatoteke vjezba822.cpp. Po£etni sadrºaj datoteke vjezba822.cpp prikazan je programskimkodom 8.22.

Programski kod 8.22: Po£etni sadrºaj datoteke vjezba822.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

#include "LCD/lcd.h"

#include "ADC/adc.h"

void inicijalizacija ()

// inicijalizacija za timer 0 - neinvertiraju¢i Fast PWM

lcd_init ();

adc_init ();

int main(void)

inicijalizacija ();

float duty; // ²irina impulsa

uint16_t ADC_5; // vrijednost AD pretvorbe na pinu ADC5

while (1)

ADC_5 = adc_read(ADC5); // ADC na kanalu ADC5

duty = 0;

OC0A_set_duty_cycle(duty);

lcd_clrscr ();

lcd_home ();

lcd_print("PWM freq:%luHz\n", F_CPU / 8 / 256);

lcd_print("TD/T:%.2f%%", duty);

_delay_ms (500);

return 0;

U programskom kodu 8.22 u funkciji inicijalizacija() napravite konguraciju sklopaTimer/Counter0 u Fast PWM na£inu rada. Generirani PWM signal mora biti neinvertiraju¢ite frekvencije ve¢e od 3 kHz, a manje od 10 kHz (pogledajte konguraciju u prethodnoj vjeºbi).irinu PWM signala potrebno je mijenjati pomo¢u potenciometra koji je spojen na pin ADC5.Zbog toga je u funkciji inicijalizacija() pozvana funkcija adc_init() kojom se kongurira

8.2 Vjeºbe - PWM na£in rada tajmera 137

analogno-digitalna pretvorba. irinu PWM signala mijenjat ¢emo pomo¢u registra OCR0A, nokoriste¢i funkciju OC0A_set_duty_cycle. Vrijednost analogno-digitalne pretvorbe na pinu ADC5kre¢e se od [0, 1023]. Prema tome, 0 ¢e predstavljati 0 % popunjenosti PWM signala, a 1023 ¢epredstavljati 100 % popunjenosti PWM signala. Omjer TDT [%] izra£unat ¢emo pomo¢u vrijednostianalogno-digitalne pretvorbe na pinu ADC5 na sljede¢i na£in:

duty =TDT

[%] =ADC_5

1023· 100%. (8.37)

Izraz (8.37) potrebno je pridruºiti varijabli duty u programskom kodu 8.22. irina impulsamijenja se u while petlji svakih 500 ms. Na LCD displeju prikazuje se frekvencija PWM signalaizra£unata prema relaciji (8.16) te postotak popunjenosti PWM signala prema relaciji (8.37).

Prevedite datoteku vjezba822.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Na slici 8.7 prikazane su dvije ravne priklju£nice. Sondu osciloskopa potrebno je spojiti izmeudvaju spojnih mjesta na ravnim priklju£nicama: GND i PB7 (slika 8.7). Na osciloskopuprikaºite tri perioda PWM signala te frekvenciju PWM signala. Mijenjajte izlazni otporpotenciometra pomo¢u odvija£a i pratite na osciloskopu popunjenost PWM signala. tozaklju£ujete? Primijetite da pri ²irini impulsa PWM signala iznosa 0 % (duty = 0) LED diodasjaji jako malim intezitetom. Za²to?

Zatvorite datoteku vjezba822.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 8.2.3

Napravite program koji ¢e:

• na pinu PB5 (OC1A) generirati neinvertiraju¢i PWM signal pomo¢u sklopaTimer/Counter1,

• na pinu PB6 (OC1B) generirati invertiraju¢i PWM signal pomo¢u sklopa Timer/Counter1,

• na pinu PB7 (OC1C) generirati neinvertiraju¢i PWM signal pomo¢u sklopaTimer/Counter1.

Frekvenciju PWM signala namjestite tako da bude manja od 3 kHz. Omogu¢ite promjenu ²irineimpulsa PWM signala pomo¢u potenciometra spojenog na pin ADC5. Na LCD displeju ispi²itefrekvenciju PWM signala i ²irinu impulsa PWM signala u postocima. Koristite Fast PWMna£ina rada sklopa Timer/Counter1.

U projektnom stablu otvorite datoteku vjezba823.cpp. Omogu¢ite samo prevoenjedatoteke vjezba823.cpp. Po£etni sadrºaj datoteke vjezba823.cpp prikazan je programskimkodom 8.23.

Programski kod 8.23: Po£etni sadrºaj datoteke vjezba823.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

#include "LCD/lcd.h"

#include "ADC/adc.h"

void inicijalizacija ()

// inicijalizacija za timer 1 - Fast PWM

138 Tajmeri i broja£i

timer1_set_prescaler(TIMER1_PRESCALER_64);

timer1_set_fast_PWM_8bit ();

timer1_OC1A_enable_non_inverted_PWM ();

timer1_OC1B_enable_inverted_PWM ();

timer1_OC1C_enable_non_inverted_PWM ();

DDRB |= (1 << PB5) | (1 << PB6) | (1 << PB7);

adc_init (); // inicijalizacija AD pretvorbe

lcd_init (); // inicijalizacija LCD displeja

int main(void)

inicijalizacija ();

float duty;

while (1)

duty = adc_read(ADC5)*100.0/1023.0;

OC1A_set_duty_cycle(duty , PWM_8BIT);

OC1B_set_duty_cycle(duty , PWM_8BIT);

OC1C_set_duty_cycle(duty , PWM_8BIT);

lcd_clrscr ();

lcd_home ();

lcd_print("PWM freq:%luHz\n", F_CPU / 64 / 256);

lcd_print("TD/T:%.2f%%", duty);

_delay_ms (500);

return 0;

U ovoj vjeºbi sklop Timer/Counter1 koristit ¢emo u Fast PWM na£inu rada. SklopTimer/Counter1 moºe generirati PWM signal na trima kanalima: kanalu (PB5 (OC1A)), kanalB (PB6 (OC1B)) i kanal C (PB7 (OC1C)). U ovoj vjeºbi generirat ¢emo PWM signal na svimtrima kanalima. Frekvencija PWM signala mora biti manja od 3 kHz. Prema relaciji (8.16),frekvencija PWM signala ovisi o frekvenciji radnog takta F_CPU i o djelitelju frekvencije radnogtakta. Frekvencija radnog takta je 16 MHz pa je potrebno odabrati djelitelj frekvencije radnogtakta za koji ¢e vrijediti da frekvencija bude manja od 3 kHz. Za djelitelj frekvencije radnogtakta odabrat ¢emo 64. Prema relaciji (8.16), frekvencija PWM signala bit ¢e:

F_fPWM =F_CPU

PRESCALER · 256=

16000000

64 · 256= 976, 56 Hz. (8.38)

Konguracija sklopa Timer/Counter1 provodi se sukladno tablicama 14-1 do 14-5 u literaturi[1] ili kori²tenjem brojnih funkcija napisanih u zaglavlju timer.h. U programskom kodu 8.23 ufunkciji inicijalizacija() napravljena je konguraciju sklopa Timer/Counter1 u Fast PWMna£inu rada funkcijom timer1_set_fast_PWM_8bit(). Ovom funkcijom deniran je rasponbrojanja registra TCNT1 ([0, 255]).

Neinvertiraju¢i ili invertiraju¢i PWM signal kongurira se sljede¢im funkcijama u funkcijiinicijalizacija():

• timer1_OC1A_enable_non_inverted_PWM() - na pinu PB5 (OC1A) generirat ¢e seneinvertiraju¢i PWM signal,

• timer1_OC1B_enable_inverted_PWM() - na pinu PB6 (OC1B) generirat ¢e se invertiraju¢iPWM signal,

8.2 Vjeºbe - PWM na£in rada tajmera 139

• timer1_OC1B_enable_non_inverted_PWM() - na pinu PB7 (OC1C) generirat ¢e seneinvertiraju¢i PWM signal.

PWM signal generira se na pinovima PB5 (OC1A), PB6 (OC1B) i PB7 (OC1C) pa ih jepotrebno kongurirati kao izlazne pinove. irinu PWM signala potrebno je mijenjati pomo¢upotenciometra koji je spojen na pin ADC5, a ra£unat ¢emo je pomo¢u relacije (8.37) iz prethodnevjeºbe. Izraz (8.37) potrebno je pridruºiti varijabli duty u programskom kodu 8.23. Promjena²irine PWM signala za sva tri kanala provodi se funkcijama:

• OC1A_set_duty_cycle(duty, PWM_8BIT),

• OC1B_set_duty_cycle(duty, PWM_8BIT) i

• OC1C_set_duty_cycle(duty, PWM_8BIT).

Prvi argument navedenih funkcija jest ²irina impulsa duty koji je prora£unat prema relaciji(8.37). Prema programskom kodu 8.19, konstanta kojom se denira raspon brojanja registraTCNT1 za 8-bitni Fast PWM jest PWM_8BIT. Ova konstanta dodjeljuje se kao drugi argumentprethodno navedenih funkcija. irina impulsa mijenja se u while petlji svakih 500 ms. NaLCD displeju prikazuje se frekvencija PWM signala izra£unata prema relaciji (8.16) te postotakpopunjenosti PWM signala.

Prevedite datoteku vjezba823.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.uta i plava LED dioda mijenjaju intezitet na druga£iji na£in od zelene LED diode. Za²to?

Zatvorite datoteku vjezba823.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 8.2.4

Napravite program koji ¢e na pinu PB7 (OC0A) generirati neinvertiraju¢i PWM signal pomo¢usklopa Timer/Counter0. Frekvenciju PWM signala namjestite tako da bude ve¢a od 3 kHz, amanja od 10 kHz. Svakih 500 ms u while petlji mijenjajte ²irinu impulsa PWM signala, takoda ona iznosi redom 0 % → 25 % → 50 % → 75 % → 100 %→ 0 % perioda T . Po mogu¢nosti,osciloskopom pratiti PWM signal na pinu PB7 (OC0A). Koristite Phase Correct PWM na£inarada sklopa Timer/Counter0.

U projektnom stablu otvorite datoteku vjezba824.cpp. Omogu¢ite samo prevoenjedatoteke vjezba824.cpp. Po£etni sadrºaj datoteke vjezba824.cpp prikazan je programskimkodom 8.24.

Programski kod 8.24: Po£etni sadrºaj datoteke vjezba824.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

void inicijalizacija ()

// inicijalizacija za timer 0 - neinvertiraju¢i Phase Correct PWM

timer0_set_prescaler(TIMER0_PRESCALER_8);

timer0_set_phase_correct_PWM ();

timer0_OC0A_enable_non_inverted_PWM ();

output_port(DDRB ,PB7);

140 Tajmeri i broja£i

int main(void)

inicijalizacija ();

while (1)

OCR0A = 0;

_delay_ms (1000);

OCR0A = 0;

_delay_ms (1000);

OCR0A = 0;

_delay_ms (1000);

OCR0A = 0;

_delay_ms (1000);

OCR0A = 0;

_delay_ms (1000);

return 0;

U ovoj vjeºbi sklop Timer/Counter0 koristit ¢emo u Phase Correct PWM na£inu rada. PWMsignal generirat ¢emo na kanalu A, odnosno na pinu PB7 (OC0A). Frekvencija radnog takta je 16MHz pa je potrebno odabrati djelitelj frekvencije radnog takta za koji ¢e vrijediti da frekvencijabude izmeu 3 i 10 kHz. Za djelitelj frekvencije radnog takta odabrat ¢emo 8. Prema relaciji(8.26), frekvencija PWM signala bit ¢e:

F_pcPWM =F_CPU

PRESCALER · 510=

16000000

8 · 510= 3921, 57 Hz = 3.92 kHz. (8.39)

Dobivena frekvencija PWM signala u relaciji (8.39) ve¢a je od 3 kHz i manja od 10 kHz. Uprogramskom kodu 8.24 u funkciji inicijalizacija() djelitelj frekvencije radnog takta iznosa 8konguriran je funkcijom timer0_set_prescaler(TIMER0_PRESCALER_8). Phase Correct PWMna£in rada postavlja se pozivom funkcije timer0_set_phase_correct_PWM().

PWM signal mora biti neinvertiraju¢i, a to se postiºe pozivom funkcijetimer0_OC0A_enable_non_inverted_PWM(). Obje prethodne funkcije pozvane su u funkcijiinicijalizacija(). Sve kori²tene funkcije za konguriranje Phase Correct PWM na£ina radanalaze se u zaglavlju timer.h, stoga je ovo zaglavlje potrebno uklju£iti u programski kod. PWMsignal generira se na pinu PB7 (OC0A) pa ga je potrebno kongurirati kao izlazni pin.

Nakon konguracije neinvertiraju¢eg PWM signala potrebno je odrediti vrijednosti registraOCR0A za koju ¢e ²irina impulsa PWM signala biti 0 %, 25 %, 50 %, 75 % i 100 % perioda T .

Prema relaciji (8.20), vrijednost OCR0A registra za ²irinu PWM signala 0 % perioda T bit ¢e:

OCR0A =TDT· 255 = 0 · 255 = 0. (8.40)

Prema relaciji (8.20), vrijednost OCR0A registra za ²irinu PWM signala 25 % perioda T bit¢e:

OCR0A =TDT· 255 = 0, 25 · 255 = 64. (8.41)

Prema relaciji (8.20), vrijednost OCR0A registra za ²irinu PWM signala 50 % perioda T bit¢e:

OCR0A =TDT· 255 = 0, 5 · 255 = 128. (8.42)

Prema relaciji (8.20), vrijednost OCR0A registra za ²irinu PWM signala 75 % perioda T bit¢e:

OCR0A =TDT· 255 = 0, 75 · 255 = 191. (8.43)

8.2 Vjeºbe - PWM na£in rada tajmera 141

Prema relaciji (8.20), vrijednost OCR0A registra za ²irinu PWM signala 100 % perioda T bit¢e:

OCR0A =TDT· 255 = 1 · 255 = 255. (8.44)

U programski kod 8.24 upi²ite izra£unate vrijednosti registra OCR0A u while petlju ispredsvakog ka²njenja iznosa 1000 ms. Ako mikroupravlja£ koristite samo za generiranje PWM signala,tada u funkciji main obavezno morate napraviti beskona£nu while petlju. Kada ne biste napravilibeskona£nu petlju, mikroupravlja£ ne bi generirao PWM signal jer bi zavr²io s izvoenjem mainfunkcije.

Prevedite datoteku vjezba824.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.PWM signal pratit ¢emo pomo¢u osciloskopa. Spajanje sonde osciloskopa na razvojno okruºenjes mikroupravlja£em ATmega32U4 prikazano je na slici 8.7. Na osciloskopu prikaºite tri periodaPWM signala te frekvenciju PWM signala prema uputama u prvoj vjeºbi.

irina impulsa moºe se denirati kori²tenjem funkcije OC0A_set_duty_cycle(float duty)koja kao argumant prima ²irinu impulsa PWM signala u rasponu od 0 % fo 100 %. Na primjer,ukoliko ºelite na pinu PB7 (OC0A) postaviti ²irinu impulsa iznosa 25 %, dovoljno je pozvatifunkciju OC0A_set_duty_cycle(25.0). Zamijenite sva pridruºivanja vrijednosti u registar OCR0Au while petlju s navedenom funkcijom.

U programskom kodu 8.24 tijelo funkcije inicijalizacija() zamijenite programskim kodom8.25. Ovaj pristup sloºeniji je od kori²tenja gotovih funkcija iz zaglavlja timer.h jer zahtijevapode²enje registara prema tablicama 8.2 i 8.3. Prevedite datoteku vjezba824.cpp u strojni kodi snimite ga na mikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenju smikroupravlja£em ATmega32U4.

Programski kod 8.25: Konguracija tajmera u Phase Correct PWM na£inu rada (djeliteljfrekvencije radnog takta iznosi 8, PWM signal je neinvertiraju¢i)

// inicijalizacija za timer 0-neinvertiraju¢i Phase Correct PWM (drugi na£in)

TCCR0B |= (0 << CS02) | (1 << CS01) | (0 << CS00); // F_CPU /8

TCCR0A |= (0 << WGM01) | (1 << WGM00); // Phase Corect PWM na£in rada

TCCR0B |= (0 << WGM02); // VRH je 0x0FF

TCCR0A |= (1 << COM0A1) | (0 << COM0A0); // Neinvertiraju¢i PWM

DDRB |= (1 << PB7); // PB7 izlazni pin

Zatvorite datoteku vjezba824.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 8.2.5

Napravite program koji ¢e na pinu PB7 (OC0A) generirati neinvertiraju¢i PWM signal pomo¢usklopa Timer/Counter0 samo ako nije pritisnuto tipkalo spojeno na pin PD0. FrekvencijuPWM signala namjestite tako da bude ve¢a od 3 kHz, a manja od 10 kHz. Omogu¢ite promjenu²irine impulsa PWM signala pomo¢u potenciometra spojenog na pin ADC5. Na LCD displejuispi²ite frekvenciju PWM signala i ²irinu impulsa PWM signala u postocima. Koristite PhaseCorrect PWM na£ina rada sklopa Timer/Counter0.

U projektnom stablu otvorite datoteku vjezba825.cpp. Omogu¢ite samo prevoenjedatoteke vjezba825.cpp. Po£etni sadrºaj datoteke vjezba825.cpp prikazan je programskimkodom 8.26.

Programski kod 8.26: Po£etni sadrºaj datoteke vjezba825.cpp

142 Tajmeri i broja£i

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

#include "LCD/lcd.h"

#include "ADC/adc.h"

void inicijalizacija ()

// inicijalizacija za timer 0 - neinvertiraju¢i Phase Correct PWM

input_port(DDRD ,PD0); //PD0 ulazni pin

set_port(PORTD , PD0 ,1); // pull up otpornik na PD0

lcd_init ();

adc_init ();

int main(void)

inicijalizacija ();

float duty; // ²irina impulsa

uint16_t ADC_5; // vrijednost AD pretvorbe na pinu ADC5

while (1)

if (get_pin(PIND , PD0) == 0)

timer0_OC0A_disable ();

else

timer0_OC0A_enable_non_inverted_PWM ();

ADC_5 = adc_read(ADC5); // ADC na kanalu ADC5

duty = ADC_5 *100.0/1023.0;

OC0A_set_duty_cycle(duty);

lcd_clrscr ();

lcd_home ();

lcd_print("PWM freq:%luHz\n", F_CPU / 8 / 510);

lcd_print("TD/T:%.2f%%", duty);

_delay_ms (500);

return 0;

U programskom kodu 8.26 u funkciji inicijalizacija() napravite konguraciju sklopaTimer/Counter0 u Phase Correct PWM na£inu rada. Generirani PWM signal mora bitineinvertiraju¢i te frekvencije ve¢e od 3 kHz, a manje od 10 kHz (pogledajte konguraciju uprethodnim vjeºbama). irinu PWM signala potrebno je mijenjati pomo¢u potenciometra kojije spojen na pin ADC5. Zbog toga je u funkciji inicijalizacija() pozvana funkcija adc_init()kojom se kongurira analogno-digitalna pretvorba.

PWM signal potrebno je generirati ako tipkalo spojeno na pin PD0 nije pritisnuto.Ova funkcionalnost realizirana je na po£etku while petlje u programskom kodu 8.26.Ako je tipkalo PD0 pritisnuto (vrijedi get_pin(PIND, PD0)== 0), tada se poziva funkcijatimer0_OC0A_disable() kojom se isklju£uje generiranje PWM signala na pin PB7 (OC0A).Kada tipkalo nije pritisnuto, tada se poziva funkcija timer0_OC0A_enable_non_inverted_PWM()kojom se omogu¢uje generiranje PWM signala na pin PB7 (OC0A).

8.2 Vjeºbe - PWM na£in rada tajmera 143

irinu PWM signala potrebno je mijenjati pomo¢u potenciometra koji je spojen na pin ADC5,a ra£unat ¢emo ju pomo¢u relacije (8.37). Izraz (8.37) potrebno je pridruºiti varijabli duty uprogramskom kodu 8.26. irina impulsa mijenja se u while petlji svakih 500 ms. Na LCD displejuprikazuje se frekvencija PWM signala izra£unata prema relaciji (8.16) te postotak popunjenostiPWM signala prema relaciji (8.37).

Prevedite datoteku vjezba825.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Mijenjajte izlazni otpor potenciometra pomo¢u odvija£a. Primijetite da je pri ²irini impulsaPWM signala iznosa 0 % (duty = 0) LED dioda isklju£ena. Za razliku od Fast PWM na£inarada gdje se pri ²irini impulsa iznosa 0 % pojavljuje ²iljak, kod Phase Correct PWM na£ina radatoga ²iljka nema, ²to omogu¢uje isklju£enje ureaja u potpunosti.

Zatvorite datoteku vjezba825.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 8.2.6

Napravite program koji ¢e na pinu PB5 (OC1A) generirati neinvertiraju¢i PWM signal pomo¢usklopa Timer/Counter1. Frekvenciju PWM signala namjestite tako da djelitelj frekvencijeradnog takta iznosi 64. Omogu¢ite promjenu ²irine impulsa PWM signala pomo¢u potenciometraspojenog na pin ADC5. Na LCD displeju ispi²ite frekvenciju PWM signala i ²irinu impulsaPWM signala u postocima. Koristite Phase Correct PWM na£ina rada sklopa Timer/Counter1u 8-bitnom, 9-bitnom, 10-bitnom te punom rasponu brojanja registra TCNT1.

U projektnom stablu otvorite datoteku vjezba826.cpp. Omogu¢ite samo prevoenjedatoteke vjezba826.cpp. Po£etni sadrºaj datoteke vjezba826.cpp prikazan je programskimkodom 8.27.

Programski kod 8.27: Po£etni sadrºaj datoteke vjezba826.cpp

#include "AVR VUB/avrvub.h"

#include <avr/io.h>

#include <util/delay.h>

#include "Timer/timer.h"

#include "LCD/lcd.h"

#include "ADC/adc.h"

void inicijalizacija ()

// inicijalizacija za timer 1 - Phase Correct PWM - [0, 255]

timer1_set_prescaler(TIMER1_PRESCALER_64);

timer1_set_phase_correct_PWM_8bit ();

timer1_OC1A_enable_non_inverted_PWM ();

DDRB |= (1 << PB5); //PB5 izlazni pin

adc_init (); // inicijalizacija AD pretvorbe

lcd_init (); // inicijalizacija LCD displeja

int main(void)

inicijalizacija ();

uint16_t pwm_bit;

float duty;

while (1)

pwm_bit = PWM_8BIT;

duty = adc_read(ADC5)*100.0/1023.0;

144 Tajmeri i broja£i

OC1A_set_duty_cycle(duty , pwm_bit);

lcd_clrscr ();

lcd_home ();

lcd_print("PWM freq:%luHz\n", F_CPU / 64 / (2 * pwm_bit));

lcd_print("TD/T:%.2f%%", duty);

_delay_ms (500);

return 0;

U ovoj vjeºbi sklop Timer/Counter1 koristit ¢emo u Phase Correct PWM na£inu rada.Program mora na pinu PB5 (OC1A) generirati neinvertiraju¢i PWM, i to za razli£iteraspone brojanja registra TCNT1. Djelitelj frekvencije radnog takta zadan je i iznosi 64.U funkciji inicijalizacija() djelitelj frekvencije radnog takta namje²ten je funkcijomtimer1_set_prescaler(TIMER1_PRESCALER_64) i ne¢e se mijenjati za razli£ite raspone brojanjaregistra TCNT1.

U nastavku ¢emo koristiti konstante za vr²ne vrijednosti registra TCNT1 pri 8-bitnom,9-bitnom, 10-bitnom te punom rasponu brojanja registra TCNT1 koje su denirane programskimkodom 8.28.

Programski kod 8.28: Deniranje konstanti koje predstavljaju vr²ne vrijednosti rasponabrojanja (TOP varijabla u izrazu (8.26))

//TOP vrijednost za PWM signale

#define PWM_8BIT 255

#define PWM_9BIT 511

#define PWM_10BIT 1023

#define PWM_ICR1 ICR1

Za 8-bitni Phase Correct PWM na£in rada frekvencija PWM signala bit ¢e:

F_pcPWM =F_CPU

PRESCALER · (2 · PWM_8BIT)=

16000000

64 · 510= 490, 2 Hz. (8.45)

Vrijednost OCR1A registra za 8-bitni Phase Correct PWM na£in rada, u ovisnosti oanalogno-digitalnoj pretvorbi na pinu ADC5, ra£una se prema sljede¢oj relaciji:

OCR1A =ADC_5

1023· PWM_8BIT (8.46)

U programskom kodu 8.27 provedena je konguracija za 8-bitni Phase Correct PWM na£inrada funkcijom timer1_set_phase_correct_PWM_8bit(). Za promjenu ²irine impulsa PWMsignala koristi se funkcija OC1A_set_duty_cycle(duty, pwm_bit) gdje je argument duty ²irinaimpulsa u rasponu od 0 do 100 %, a argument pwm_bit predstavlja vr²nu vrijednost registraTCNT1. Za 8-bitni raspon brojanja u registru TCNT1 vrijedi pwm_bit = PWM_8BIT. Preveditedatoteku vjezba826.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajteprogram na razvojnom okruºenju s mikroupravlja£em ATmega32U4. Ponovite postupak tako daumjesto funkcije OC1A_set_duty_cycle(duty, pwm_bit) koristite relaciju (8.46). Na ovaj na£indirektno upisujete ²irinu impulsa PWM signala u registar OCR1A.

Za 9-bitni Phase Correct PWM na£in rada frekvencija PWM signala bit ¢e:

F_pcPWM =F_CPU

PRESCALER · (2 · PWM_9BIT)=

16000000

64 · 1022= 244, 62 Hz. (8.47)

Vrijednost OCR1A registra za 9-bitni Phase Correct PWM na£in rada, u ovisnosti oanalogno-digitalnoj pretvorbi na pinu ADC5, ra£una se prema sljede¢oj relaciji:

OCR1A =ADC_5

1023· PWM_9BIT (8.48)

8.2 Vjeºbe - PWM na£in rada tajmera 145

Da biste podesili 9-bitni Phase Correct PWM na£in rada u programskom kodu 8.27, napravitesljede¢e korake:

• funkciju timer1_set_phase_correct_PWM_8bit() zamijenite funkcijom za 9-bitni na£inrada timer1_set_phase_correct_PWM_9bit(),

• varijabli pwm_bit dodijelite vrijednost PWM_9BIT.

Prevedite datoteku vjezba826.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Ponovite postupak tako da umjesto funkcije OC1A_set_duty_cycle(duty, pwm_bit) koristiterelaciju (8.48).

Za 10-bitni Phase Correct PWM na£in rada frekvencija PWM signala bit ¢e:

F_pcPWM =F_CPU

PRESCALER · (2 · PWM_10BIT)=

16000000

64 · 2046= 122, 19 Hz. (8.49)

Vrijednost OCR1A registra za 10-bitni Phase Correct PWM na£in rada, u ovisnosti oanalogno-digitalnoj pretvorbi na pinu ADC5, ra£una se prema sljede¢oj relaciji:

OCR1A =ADC_5

1023· PWM_10BIT = ADC_5 (8.50)

Da biste podesili 10-bitni Phase Correct PWM na£in rada u programskom kodu 8.27,napravite sljede¢e korake:

• funkciju timer1_set_phase_correct_PWM_8bit() zamijenite funkcijom za 10-bitni na£inrada timer1_set_phase_correct_PWM_10bit(),

• varijabli pwm_bit dodijelite vrijednost PWM_10BIT.

Prevedite datoteku vjezba826.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Ponovite postupak tako da umjesto funkcije OC1A_set_duty_cycle(duty, pwm_bit) koristiterelaciju (8.50). S obzirom na to da je analogno-digitalna pretvorba ²irine 10 bitova, vrijednostanalogno-digitalne pretvorbe na pinu ADC5 moºe se direktno dodijeliti registru OCR1A.

Sklop Timer/Counter1 moºe generirati PWM signal na temelju cijelog raspona brojanjaregistra TCNT1 koji je ²irine 16 bitova ([0, 65535]). Tada se vr²na vrijednost do koje ¢e registarTCNT1 brojati pode²ava registrom ICR1. Frekvencija ¢e u tom slu£aju biti:

F_pcPWM =F_CPU

PRESCALER · (2 · PWM_ICR1)=

F_CPUPRESCALER · (2 · ICR1)

. (8.51)

Relacija (8.51) daje ve¢u slobodu u odabiru frekvencija PWM signala, za razliku odprethodnih slu£ajeva u kojima su frekvencije mogle biti diskretno odabrane. Ukoliko ºelimogenerirati PWM signal ºeljene frekvencije, tada je vrijednost registra ICR1 potrebno izra£unatina sljede¢i na£in:

ICR1 =F_CPU

PRESCALER · 2 · F_pcPWM. (8.52)

Na primjer, ako ºelite generirati PWM signal frekvencije 50 Hz, tada ¢e vrijednost registraICR1 biti:

ICR1 =F_CPU

PRESCALER · 2 · F_pcPWM=

16000000

64 · 2 · 50= 2500. (8.53)

146 Tajmeri i broja£i

Vrijednost OCR1A registra za slu£aj kada raspon brojanja registra TCNT1 deniramo pomo¢uregistra ICR1 za Phase Correct PWM na£in rada, u ovisnosti o analogno-digitalnoj pretvorbi napinu ADC5, ra£una se prema sljede¢oj relaciji:

OCR1A =ADC_5

1023· PWM_ICR1 (8.54)

Da biste podesili Phase Correct PWM na£in rada u punom rasponu brojanja registra TCNT1u programskom kodu 8.27 napravite sljede¢e korake:

• funkciju timer1_set_phase_correct_PWM_8bit() zamijenite funkcijom za na£in rada ucijelom rasponu [0, 65535] timer1_set_phase_correct_PWM_ICR1(2500) (PWM signal bit¢e frekvencije 50 Hz),

• varijabli pwm_bit dodijelite vrijednost PWM_ICR1.

Prevedite datoteku vjezba826.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Ponovite postupak tako da umjesto funkcije OC1A_set_duty_cycle(duty, pwm_bit) koristiterelaciju (8.54).

Promijenite djelitelj frekvencije radnog takta na iznos 1024. Prevedite datotekuvjezba826.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte programna razvojnom okruºenju s mikroupravlja£em ATmega32U4. to se dogaa s crvenom LEDdiodom i za²to?

Zatvorite datoteku vjezba826.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

8.2 Vjeºbe - PWM na£in rada tajmera 147

8.2.4 Zadaci - PWM na£in rada tajmera

Zadatak 8.2.1

Napravite program koji ¢e na pinu PB7 (OC0A) generirati neinvertiraju¢i PWM signal pomo¢usklopa Timer/Counter0. Frekvenciju PWM signala namjestite tako da bude ve¢a od 3 kHz, amanja od 10 kHz. Svakih 500 ms u while petlji mijenjajte ²irinu impulsa PWM signala, takoda ona iznosi redom 0 % → 25 % → 50 % → 75 % → 100 %→ 0 % perioda T . Po mogu¢nosti,osciloskopom pratiti PWM signal na pinu PB7 (OC0A). Koristite Fast PWM na£ina rada sklopaTimer/Counter0.

Zadatak 8.2.2

Napravite program koji ¢e na pinu PB7 (OC0A) generirati invertiraju¢i PWM signal pomo¢usklopa Timer/Counter0. Frekvenciju PWM signala namjestite tako da bude manja od 3 kHz.Omogu¢ite promjenu ²irine impulsa PWM signala pomo¢u potenciometra spojenog na pinADC5. Na LCD displeju ispi²ite frekvenciju PWM signala i ²irinu impulsa PWM signala upostocima. Po mogu¢nosti, osciloskopom pratiti PWM signal na pinu PB7 (OC0A). KoristiteFast PWM na£ina rada sklopa Timer/Counter0.

Zadatak 8.2.3

Napravite program koji ¢e:

• na pinu PB5 (OC1A) generirati invertiraju¢i PWM signal pomo¢u sklopa Timer/Counter1,

• na pinu PB6 (OC1B) generirati neinvertiraju¢i PWM signal pomo¢u sklopaTimer/Counter1,

• na pinu PB7 (OC1C) generirati invertiraju¢i PWM signal pomo¢u sklopa Timer/Counter1.

Frekvenciju PWM signala namjestite tako da bude ve¢a od 3 kHz. Omogu¢ite promjenu ²irineimpulsa PWM signala pomo¢u potenciometra spojenog na pin ADC5. Na LCD displeju ispi²itefrekvenciju PWM signala i ²irinu impulsa PWM signala u postocima. Koristite Fast PWMna£ina rada sklopa Timer/Counter1.

Zadatak 8.2.4

Napravite program koji ¢e na pinu PB7 (OC0A) generirati neinvertiraju¢i PWM signal pomo¢usklopa Timer/Counter0. Frekvenciju PWM signala namjestite tako da bude ve¢a od 3 kHz,a manja od 10 kHz. Svakih 500 ms u while petlji mijenjajte ²irinu impulsa PWM signala,tako da ona iznosi redom 10 % → 40 % → 70 % → 95 % → 10 % perioda T . Po mogu¢nosti,osciloskopom pratiti PWM signal na pinu PB7 (OC0A). Koristite Phase Correct PWM na£inarada sklopa Timer/Counter0.

148 Tajmeri i broja£i

Zadatak 8.2.5

Napravite program koji ¢e na pinu PB7 (OC0A) generirati invertiraju¢i PWM signal pomo¢usklopa Timer/Counter0 samo ako je pritisnuto tipkalo spojeno na pin PF7. Frekvenciju PWMsignala namjestite tako da bude ve¢a od 3 kHz, a manja od 10 kHz. Omogu¢ite promjenu ²irineimpulsa PWM signala pomo¢u potenciometra spojenog na pin ADC5. Na LCD displeju ispi²itefrekvenciju PWM signala i ²irinu impulsa PWM signala u postocima. Koristite Phase CorrectPWM na£ina rada sklopa Timer/Counter0.

Zadatak 8.2.6

Napravite program koji ¢e na pinu PB6 (OC1B) generirati neinvertiraju¢i PWM signal pomo¢usklopa Timer/Counter1. Frekvenciju PWM signala namjestite tako da bude jednaka 50 Hz.Omogu¢ite promjenu ²irine impulsa PWM signala pomo¢u potenciometra spojenog na pinADC5. Na LCD displeju ispi²ite frekvenciju PWM signala i ²irinu impulsa PWM signala upostocima. Koristite Phase Correct PWM na£ina rada sklopa Timer/Counter1 punom rasponubrojanja registra TCNT1.

Poglavlje 9

Numeri£ki displej i posma£ni registar

Numeri£ki displej naj£e²¢e se koristi za prikaz brojeva pomo¢u segmenata. Svaki je segmentLED dioda koja moºe biti uklju£ena ili isklju£ena. Mnogi numeri£ki displeji imaju decimalnuto£ku kako bi omogu¢ili ispis realnih brojeva. Numeri£ki displej sa sedam segmenata za prikazbrojeva i jednim segmentom za prikaz decimalne to£ke prikazan je na slici 9.1.

(a) Spoj zajedni£ke katode (b) Spoj zajedni£ke anode

Slika 9.1: Numeri£ki displej sa sedam segmenata za prikaz brojeva i jednim segmentom zaprikaz decimalne to£ke

Imena segmenata za prikaz brojeva jesu a, b, c, d, e, f i g, dok je ime segmenta zaprikaz decimalne to£ke p. Kombinacijom uklju£enih i isklju£enih segmenata a, b, c, d, e,f i g moºe se prikazati bilo koja znamenka dekadskog sustava, uklju£uju¢i i slova potrebna zaprikaz znamenaka heksadekadskog sustava. Postoje dvije izvedbe numeri£kih displeja:

• spoj zajedni£ke katode (slika 9.1a) i

• spoj zajedni£ke anode (slika 9.1b).

150 Numeri£ki displej i posma£ni registar

U spoju zajedni£ke katode sve katode LED dioda koje £ine segmente spojene su na zajedni£kipotencijal Gnd (0 V). U tom slu£aju jedan segment uklju£ujemo tako da na pin tog segmentapreko predotpora od 330 Ω dovedemo potencijal od 5 V (slika 9.2a).

U spoju zajedni£ke anode sve anode LED dioda koje £ine segmente spojene su na zajedni£kipotencijal Vcc (5 V). U tom slu£aju jedan segment uklju£ujemo tako da na pin tog segmentapreko predotpora od 330 Ω dovedemo potencijal od 0 V (slika 9.2b).

(a) Predotpor u spoju zajedni£ke katode (b) Predotpor u spoju zajedni£ke anode

Slika 9.2: Predotpori u spoju zajedni£ke katode i anode za segment a

Predotpor na slici 9.2 sluºi kao strujna za²tita LED diode segmenta, a ujedno i kao za²titadigitalnog pina mikroupravlja£a od prevelike struje. Na slici 9.3 i u tablici 9.1 prikazani suuklju£eni i isklju£eni segmenti za prikaz znamenaka iz dekadskog sustava. U tablici 9.1 za segmentp koji se odnosi na decimalnu to£ku stanje je nedenirano i ozna£eno je slovom x. Segment puklju£uje se prema potrebi, odnosno kada prikazujemo realne brojeve. Za prikaz svih znamenakadekadskog sustava potrebno je osam digitalnih pinova kojima ¢emo uklju£ivati ili isklju£ivatipojedini segment. U spoju zajedni£ke katode visoko stanje na digitalnom pinu mikroupravlja£auklju£uje segment, a nisko stanje isklju£uje segment. U spoju zajedni£ke anode nisko stanje nadigitalnom pinu mikroupravlja£a uklju£uje segment, a visoko stanje isklju£uje segment.

Slika 9.3: Prikaz uklju£enih i isklju£enih segmenata za znamenke dekadskog sustava

151

Tablica 9.1: Stanja pojedinih segmenata za prikaz jedne znamenke dekadskog sustava

ZnamenkaSegmenti

a b c d e f g p0 uklju£en uklju£en uklju£en uklju£en uklju£en uklju£en isklju£en x1 isklju£en uklju£en uklju£en isklju£en isklju£en isklju£en isklju£en x2 uklju£en uklju£en isklju£en uklju£en uklju£en isklju£en uklju£en x3 uklju£en uklju£en uklju£en uklju£en isklju£en isklju£en uklju£en x4 isklju£en uklju£en uklju£en isklju£en isklju£en uklju£en uklju£en x5 uklju£en isklju£en uklju£en uklju£en isklju£en uklju£en uklju£en x6 uklju£en isklju£en uklju£en uklju£en uklju£en uklju£en uklju£en x7 uklju£en uklju£en uklju£en isklju£en isklju£en isklju£en isklju£en x8 uklju£en uklju£en uklju£en uklju£en uklju£en uklju£en uklju£en x9 uklju£en uklju£en uklju£en uklju£en isklju£en uklju£en uklju£en x

U narednim vjeºbama prezentirat ¢emo £etveroznamenkaste brojeve na £etiri numeri£kadispleja. Za prikaz znamenke na jednom numeri£kom displeju potrebno je 8 digitalnih izlaza.Ako ºelimo prikazati £etiri znamenke na £etiri numeri£ka displeja, potrebna su 32 digitalna izlazamikroupravlja£a. Na po£etku ovog udºbenika naveli smo kako mikroupravlja£ ATmega32U4 ima26 digitalnih pinova. Prema tome, pomo¢u mikroupravlja£a ATmega32U4 nije mogu¢e prikazati£etveroznamenkasti broj na na£in da upravljamo svakim segmentom, ve¢ je mogu¢e najvi²eprikazati troznamenkasti broj gdje bi utro²ak digitalnih pinova bio 24.

esto je u praksi potrebno pro²iriti digitalne izlaze nekog mikroupravlja£a, a naro£ito kada sekoriste numeri£ki displeji, matri£ni displeji i drugi ureaji koji zahtijevaju velik utro²ak digitalnihizlaza. Jedan od na£ina pro²irenja digitalnih izlaza jest kori²tenje posma£nog registra sa serijskimulazom (engl. Shift Bit Register). Naj£e²¢e su posma£ni registri ²irine 8 bitova, odnosno 8digitalnih izlaza. Primjer jednog takvog posma£nog registra jest 74HC595D koji ¢emo koristiti uvjeºbi. Blok shema posma£nog registra prikazana je na slici 9.4. Na shemi sa slike 9.4 prikazanisu sljede¢i osnovni signali i elementi posma£nog registra:

• Registar za pohranu (engl. Storage Register) - registar ²irine 8 bitova koji se puni nizombinarnih podataka s ulaza SI,

• SI - (engl. Serial Input) ulaz na koji se dovodi serijski niz binarnih podataka (0 ili 1),

• SCK - (engl. Serial Clock) ulaz na koji se dovodi signal takta. Na svaki rastu¢i brid signalatakta binarni podatak s ulaza SI upisuje se u Registar za pohranu (0 ili 1 → QA), dokse istovremeno svi bitovi Registra za pohranu posmi£u desno (QA → QB, QB → QC , ...,QG → QH , QH → Q∗

H).

• Q∗H - izlaz iz posma£nog registra na koji se prosljeuje bit QH nakon rastu¢eg brida signala

SCK,

• Izlazni registar (engl. Output Register) - registar koji se puni bitovima iz Registraza pohranu na svaki rastu¢i brid signala RCK,

• RCK - (engl. Register Clock) - ulaz koji na rastu¢i brid signala puni Izlazni registar(kopira bitove Registra za pohranu u Izlazni registar),

• QA, QB, ..., QH - pro²ireni izlazi posma£nog registra £ije je stanje istovjetno stanju bitovau Izlaznom registru.

152 Numeri£ki displej i posma£ni registar

0 0 0 0 0 0 0 0

Shift bit register

QA QB QC QD QE QF QG QH

SI 0 0 0 0 0 0 0 0

RCK

SCKQH

*

Izlazni registar

Shift bit register

QA QB QC QD QE QF QG QH

SI Registar za pohranu

RCK

SCKQH

*

Slika 9.4: Blok shema posma£nog registra

Postupka punjenja posma£nog registra prikazat ¢emo na primjeru binarne kombinacije01100110. Stanja ulaznih signala SI, SCK, i RCK posma£nog registra za punjenje binarnomkombinacijom 01100110 prikazana su na slici 9.5.

1. 2. 3. 4. 5. 6. 7. 8.

SI

SCK

RCK

Slika 9.5: Stanja ulaznih signala posma£nog registra za punjenje binarnom kombinacijom01100110

Postupak punjenja posma£nog registra binarnom kombinacijom 01100110 prikazan je na slici9.6, a provodi se na sljede¢i na£in (pretpostavimo da ne znamo prethodna stanja Registra zapunjenje i Izlaznog registra te ta stanja ozna£imo s x):

• na 1. rastu¢i brid signala SCK (slika 9.5), stanje ulaza SI je 0. Vrijednost bita 0 ulazi uRegistar za pohranu na poziciju QA uz posmicanje Registra za pohranu udesno (QA

→ QB, QB → QC , ..., QG → QH , QH → Q∗H ; stanje Registra za pohranu je 0xxxxxxx)

(slika 9.6 - 1. impuls SCK),

• na 2. rastu¢i brid signala SCK (slika 9.5), stanje ulaza SI je 1. Vrijednost bita 1 ulaziu Registar za pohranu na poziciju QA uz posmicanje Registra za pohranu udesno(QA

→ QB, QB → QC , ..., QG → QH , QH → Q∗H ; stanje Registra za pohranu je 10xxxxxx)

(slika 9.6 - 2. impuls SCK),

• na 3. rastu¢i brid signala SCK (slika 9.5), stanje ulaza SI je 1. Vrijednost bita 1 ulazi uRegistar za pohranu na poziciju QA uz posmicanje Registra za pohranu udesno (QA

→ QB, QB → QC , ..., QG → QH , QH → Q∗H ; stanje Registra za pohranu je 110xxxxx)

(slika 9.6 - 3. impuls SCK),

• na 4. rastu¢i brid signala SCK (slika 9.5), stanje ulaza SI je 0. Vrijednost bita 0 ulazi uRegistar za pohranu na poziciju QA uz posmicanje Registra za pohranu udesno (QA

→ QB, QB → QC , ..., QG → QH , QH → Q∗H ; stanje Registra za pohranu je 0110xxxx)

(slika 9.6 - 4. impuls SCK),

• na 5. rastu¢i brid signala SCK (slika 9.5), stanje ulaza SI je 0. Vrijednost bita 0 ulazi uRegistar za pohranu na poziciju QA uz posmicanje Registra za pohranu udesno (QA

→ QB, QB → QC , ..., QG → QH , QH → Q∗H ; stanje Registra za pohranu je 00110xxx)

(slika 9.6 - 5. impuls SCK),

153

• na 6. rastu¢i brid signala SCK (slika 9.5), stanje ulaza SI je 1. Vrijednost bita 1 ulazi uRegistar za pohranu na poziciju QA uz posmicanje Registra za pohranu udesno (QA

→ QB, QB → QC , ..., QG → QH , QH → Q∗H ; stanje Registra za pohranu je 100110xx)

(slika 9.6 - 6. impuls SCK),

• na 7. rastu¢i brid signala SCK (slika 9.5), stanje ulaza SI je 1. Vrijednost bita 1 ulazi uRegistar za pohranu na poziciju QA uz posmicanje Registra za pohranu udesno (QA

→ QB, QB → QC , ..., QG → QH , QH → Q∗H ; stanje Registra za pohranu je 1100110x)

(slika 9.6 - 7. impuls SCK),

• na 8. rastu¢i brid signala SCK (slika 9.5), stanje ulaza SI je 0. Vrijednost bita 0 ulazi uRegistar za pohranu na poziciju QA uz posmicanje Registra za pohranu udesno (QA

→ QB, QB → QC , ..., QG → QH , QH → Q∗H ; stanje Registra za pohranu je 01100110)

(slika 9.6 - 8. impuls SCK),

• na rastu¢i brid signala RCK (slika 9.5), Izlazni registar puni se kombinacijom 01100110iz Registra za punjenje,

• stanja izlaza posma£nog registra jesu: QA = 0, QB = 1, QC = 1, QD = 0, QE = 0, QF =1, QG = 1, QH = 0.

Izlaz QA predstavlja stanje najzna£ajnijeg bita (engl. Most Signicant Bit - MSB), a izlazQH predstavlja stanje najmanje zna£ajnog bita (engl. Least Signicant Bit - LSB).

x x x x x x x x

Posmačni registar

QA QB QC QD QE QF QG QH

SI 0 x x x x x x x

RCK

SCKQH

*

x x x x x x x x

Posmačni registar

QA QB QC QD QE QF QG QH

SI 1 0 x x x x x x

RCK

SCKQH

*

x x x x x x x x

Posmačni registar

QA QB QC QD QE QF QG QH

SI 1 1 0 x x x x x

RCK

SCKQH

*

x x x x x x x x

Posmačni registar

QA QB QC QD QE QF QG QH

SI 0 1 1 0 x x x x

RCK

SCKQH

*

x x x x x x x x

Posmačni registar

QA QB QC QD QE QF QG QH

SI 0 0 1 1 0 x x x

RCK

SCKQH

*

x x x x x x x x

Posmačni registar

QA QB QC QD QE QF QG QH

SI 1 0 0 1 1 0 x x

RCK

SCKQH

*

0

x x x x x x x x

Posmačni registar

QA QB QC QD QE QF QG QH

SI 1 1 0 0 1 1 0 x

RCK

SCKQH

*

0 1 1 0 0 1 1 0

Posmačni registar

QA QB QC QD QE QF QG QH

SI 0 1 1 0 0 1 1 0

RCK

SCKQH

*

1. impuls SCK 2. impuls SCK 3. impuls SCK 4. impuls SCK

5. impuls SCK 6. impuls SCK 7. impuls SCK 8. impuls SCK

Slika 9.6: Postupak punjenja posma£nog registra binarnom kombinacijom 01100110

Da bismo poslali 8 bitova podataka na posma£ni registar, potrebno je koristiti tri digitalnaizlaza mikroupravlja£a. Jedan posma£ni registar moºe upravljati jednim numeri£kim displejomtako da se izlaz QA spoji na segment a, QB spoji na segment b, QC spoji na segment c, ..., QH

spoji na segment p. Za £etiri numeri£ka displeja potrebno je koristiti £etiri posma£na registrakoji se mogu povezati serijski na sljede¢i na£in (slika 9.7):

• ulaz SI prvog posma£nog registra spajamo na digitalni izlaz mikroupravlja£a,

• ulaz SI drugog posma£nog registra spajamo na izlaz Q∗H prvog posma£nog registra,

• ulaz SI tre¢eg posma£nog registra spajamo na izlaz Q∗H drugog posma£nog registra,

• ulaz SI £etvrtog posma£nog registra spajamo na izlaz Q∗H tre¢eg posma£nog registra,

• SCK ulazi svih posma£nih registara spajaju se zajedno na digitalni izlaz mikroupravlja£a,

• RCK ulazi svih posma£nih registara spajaju se zajedno na digitalni izlaz mikroupravlja£a.

154 Numeri£ki displej i posma£ni registar

a

b

c

d

e

f

g

p

1 1 0 0 0 0 0 0

Posmačni registar - DISP4

QA QB QC QD QE QF QG QH

SI 1 1 0 0 0 0 0 0

RCK

SCK

QH*

1 1 0 1 1 0 1 0

Posmačni registar - DISP3

QA QB QC QD QE

SI 1 1 0 1 1 0 1 0

DISP4

SCK

RCK

QF QG QH

1 1 1 1 0 0 1 0

Posmačni registar – DISP2

QA QB QC QD QE

1 1 1 1 0 0 1 0

QF QG QH

QH* SI

SCK

RCK 0 1 1 0 0 1 1 0

Posmačni registar – DISP1

QA QB QC QD QE

0 1 1 0 0 1 1 0

QF QG QH

QH* SI

SCK

RCK

a

b

c

d

e

f

g

p

DISP3

a

b

c

d

e

f

g

p

DISP2

a

b

c

d

e

f

g

p

DISP1

Slika 9.7: Shema spajanja £etiriju posma£nih registara u seriju s numeri£kim displejima

Ako spajamo posma£ne registre na ovaj na£in, utro²ak digitalnih izlaza mikroupravlja£a zaupravljanje s £etiri numeri£ka displeja i dalje je tri. Vrijeme punjenja £etiriju posma£nih registarabit ¢e £etiri puta ve¢e. Pretpostavimo da na £etiri numeri£ka displeja ºelimo prikazati sljede¢eznamenke: DISP4 = 1, DISP3 = 2, DISP2 = 3 i DISP1 = 4. Stanja pojedinih segmenata za prikazjedne znamenke dekadskog sustava na numeri£kom displeju prikazana su u tablici 9.2. Prematablici 9.2, znamenka 1 odgovara binarnoj kombinaciji segmenata 01100000, znamenka 2 odgovarabinarnoj kombinaciji segmenata 11011010, znamenka 3 odgovara binarnoj kombinaciji segmenata111110010, a znamenka 4 odgovara binarnoj kombinaciji segmenata 01100110. Pretpostavimoda je numeri£ki displej DISP4 spojen na prvi posma£ni registar £iji je ulaz SI spojen na digitalniizlaz mikroupravlja£a. Numeri£ki displej DISP3 spojen je na drugi u seriji posma£ni registar(slika 9.7) itd.

Tablica 9.2: Stanja pojedinih segmenata za prikaz jedne znamenke dekadskog sustava nanumeri£kom displeju

ZnamenkaSegmenti

(hex)a b c d e f g p0 1 1 1 1 1 1 0 0 0xFC1 0 1 1 0 0 0 0 0 0x602 1 1 0 1 1 0 1 0 0xDA3 1 1 1 1 0 0 1 0 0xF24 0 1 1 0 0 1 1 0 0x665 1 0 1 1 0 1 1 0 0xB66 1 0 1 1 1 1 1 0 0xBE7 1 1 1 0 0 0 0 0 0xE08 1 1 1 1 1 1 1 0 0xFE9 1 1 1 1 0 1 1 0 0xF6

Postupak punjenja £etiriju bajtova podataka u £etiri posma£na registra prikazan je na slici9.8. S obzirom na na£in kako su posma£ni registri meusobno spojeni, binarna kombinacija zanumeri£ki displej DISP1 koji je zadnji u nizu mora i¢i prva u serijski niz posma£nih registara.

155

0 0 0 0 0 0 0 0

DISP4

0 0 0 0 0 0 0 0

DISP30 0 0 0 0 0 0 0

DISP2

0 0 0 0 0 0 0 0

DISP1

0 1 1 0 0 1 1 0

DISP4

0 0 0 0 0 0 0 0

DISP30 0 0 0 0 0 0 0

DISP2

0 0 0 0 0 0 0 0

DISP1 0b01100000

0b11011010

0b11110010

1 1 1 1 0 0 1 0

DISP4 DISP30 0 0 0 0 0 0 0

DISP2

0 0 0 0 0 0 0 0

DISP1 0b01100000

0b11011010 0 1 1 0 0 1 1 0

1 1 1 1 0 0 1 0

DISP4 DISP3 DISP2

0 0 0 0 0 0 0 0

DISP1 0b01100000 0 1 1 0 0 1 1 01 1 0 1 1 0 1 0

1 1 1 1 0 0 1 0

DISP4 DISP3 DISP2

0 1 1 0 0 0 0 0

DISP1

0 1 1 0 0 1 1 01 1 0 1 1 0 1 0

0 0 0 0

4 0 0 0

3 4 0 0

2 3 4 0

1 2 3 4

0b01100000

0b11011010

0b11110010

0b01100110

Slika 9.8: Postupak punjenja £etiriju bajtova podataka u £etiri posma£na registra

Pretpostavimo da su segmenti svih £etiriju numeri£kih displeja bili isklju£eni (slika 9.8 prviredak). Postupak punjenja £etiriju bajtova podataka provodi se na sljede¢i na£in:

1. na ulaz SI ²alje se binarna kombinacija za numeri£ki displej DISP1, odnosno znamenka 4£ija je binarna kombinacija jednaka 01100110. Svi posma£ni registri posmi£u se udesno za8 mjesta. Binarna kombinacija za numeri£ki displej DISP1 nalazi se na prvom posma£nomregistru (slika 9.8 drugi redak).

2. na ulaz SI ²alje se binarna kombinacija za numeri£ki displej DISP2, odnosno znamenka 3£ija je binarna kombinacija jednaka 111110010. Svi posma£ni registri posmi£u se udesno za8 mjesta. Binarna kombinacija za numeri£ki displej DISP1 nalazi se na drugom posma£nomregistru, a za numeri£ki displej DISP2 nalazi se na prvom posma£nom registru (slika 9.8tre¢i redak).

3. na ulaz SI ²alje se binarna kombinacija za numeri£ki displej DISP3, odnosno znamenka 2£ija je binarna kombinacija jednaka 11011010. Svi posma£ni registri posmi£u se udesno za8 mjesta. Binarna kombinacija za numeri£ki displej DISP1 nalazi se na tre¢em posma£nomregistru, za numeri£ki displej DISP2 nalazi se na drugom posma£nom registru, a zanumeri£ki displej DISP3 nalazi se na prvom posma£nom registru (slika 9.8 £etvrti redak).

4. na ulaz SI ²alje se binarna kombinacija za numeri£ki displej DISP4, odnosno znamenka 1£ija je binarna kombinacija jednaka 01100000. Svi posma£ni registri posmi£u se udesno za 8mjesta. Binarna kombinacija za numeri£ki displej DISP1 nalazi se na £etvrtom posma£nomregistru, za numeri£ki displej DISP2 nalazi se na tre¢em posma£nom registru, za numeri£kidisplej DISP3 nalazi se na drugom posma£nom registru, a za numeri£ki displej DISP4 nalazise na prvom posma£nom registru (slika 9.8 peti redak).

Kada sva £etiri posma£na registra napunimo s 4 bajta podataka, potrebno je poslati rastu¢ibrid na ulaz RCK kako bi se poslana kombinacija u £etiri posma£na registra iz Registara zapohranu proslijedila na Izlazne registre, odnosno na numeri£ke displeje. Prikaz brojeva 1, 2,3 i 4 na numeri£kim displejima DISP1, DISP2, DISP3 i DISP4 sa sadrºajem posma£nih registaraprikazan je na slici 9.7. Treba imati na umu da £etveroznamenkasti broj koji ¢e se prikazati nanizu od £etiri numeri£ka displeja ovisi o njihovu razmje²taju na tiskanoj plo£ici. Ako je razmje²taj

156 Numeri£ki displej i posma£ni registar

takav da s lijeva na desno imamo niz numeri£kih displeja DISP4, DISP3, DISP2 i DISP1, tada ¢enumeri£ki displeji prikazivati broj 1234 (razmje²taj na slici 9.7).

Ako je razmje²taj takav da s lijeva na desno imamo niz numeri£kih displeja DISP1, DISP2,DISP3 i DISP4, tada ¢e numeri£ki displeji prikazivati broj 4321. Na ovaj na£in spojeni sunumeri£ki displeji na razvojnom okruºenju sa slike 3.1.

9.1 Vjeºbe - numeri£ki displej i posma£ni registar

Shema spajanja £etiriju posma£nih registara i numeri£kih displeja na mikroupravlja£ATmega32U4 prikazana je na slici 9.9.

+5V

GND

100n

10k

+5V

1uF

74HC595D

GND

330330330330330330330330

74HC595D

GND

330330330330330330330330

74HC595D

GND

330330330330330330330330

74HC595D

GND

330330330330330330330330

22p

22p

GND

GND

GND

+5V

+5V+5V

+5V

GND GND

GND

+5V

+5V

100n

100n

100n

100n

GND

+5V

UGND

+5V

+5V

+5V +5V

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2

QB 1

QC 2

QD 3

QE 4

QF 5

QG 6

QH 7

SCL10SCK11

RCK12

G13

14 SI QA 15

QH* 9

CC

CC

p

a

b

c

d

e

f

g109

2

67 3

4

1

5

8R18R19R20R21R22R23R24R25

QB 1

QC 2

QD 3

QE 4

QF 5

QG 6

QH 7

SCL10SCK11

RCK12

G13

14 SI QA 15

QH* 9

CC

CC

p

a

b

c

d

e

f

g109

2

67 3

4

1

5

8R26R27R28R29R30R31R32R33

QB 1

QC 2

QD 3

QE 4

QF 5

QG 6

QH 7

SCL10SCK11

RCK12

G13

14 SI QA 15

QH* 9

CC

CC

p

a

b

c

d

e

f

g109

2

67 3

4

1

5

8

DISP2R34R35R36R37R38R39R40R41

QB 1

QC 2

QD 3

QE 4

QF 5

QG 6

QH 7

SCL10SCK11

RCK12

G13

14 SI QA 15

QH* 9

CC

CC

p

a

b

c

d

e

f

g109

2

67 3

4

1

5

8R42R43R44R45R46R47R48R49

C12

C13

134 2

S5

GND

VCC

816

IC2P

GND

VCC

816

IC5P

GND

VCC

816

IC6P

GND

VCC

816

IC7PC16

C17

C18

C15

21

Q1

1 2 3

JP6

RESET

MISOMOSI

RXTX

AREF

D-D+

VUSB

SCK

PD6

PC7

PC7

PE6

PD7

PC6

PF1

PF1 PF1

PF1

PF1

PF0

PF0

PF0

PF0

PF0

OE OE

OE

OE

OE

SS

DISP1

DISP4

DISP3

Slika 9.9: Shema spajanja £etiriju posma£nih registara i numeri£kih displeja na mikroupravlja£ATmega32U4

Na shemi se nalaze £etiri numeri£ka displeja u spoju zajedni£ke katode sa sedam segmenata(a, b, c, d, e, f, g) za prikaz znamenaka i jednim segmentom (p) za prikaz decimalne to£ke.Numeri£ki displeji imaju oznake DISP1, DISP2, DISP3 i DISP4, a povezani su na izlaze posma£nihregistara QA , QB, QC , QD, QE , QF , QG, QH . Na£in spajanja segmenata numeri£kog displejaprikazan je na slici 9.9 (QA → a, QB → b, QC → a, QD → d, QE → e, QF → f, QG → g,QH → p). Ulaz SI prvog posma£nog registra spojen je na pin PC7. Ulazi SCK svih posma£nihregistara spojeni su na pin PF1, dok su ulazi RCK svih posma£nih registara spojeni na pin PF0.

9.1 Vjeºbe - numeri£ki displej i posma£ni registar 157

Ulaz SI prvog posma£nog registra spojen je na mikroupravlja£. Izlaz Q∗H prvog posmi£nog

registra spojen je na ulaz SI drugog posmi£nog registra. Nadalje, izlaz Q∗H drugog posmi£nog

registra spojen je na ulaz SI tre¢eg posmi£nog registra te je izlaz Q∗H tre¢eg posmi£nog registra

spojen na ulaz SI £etvrtog posmi£nog registra. U prikazu £etveroznamenkastog broja vrijedisljede¢e:

• numeri£ki displej s oznakom DISP1 prikazuje znamenke tisu¢ica i spojen je na £etvrtiposma£ni registar,

• numeri£ki displej s oznakom DISP2 prikazuje znamenke stotica i spojen je na tre¢i posma£niregistar,

• numeri£ki displej s oznakom DISP3 prikazuje znamenke desetica i spojen je na drugiposma£ni registar,

• numeri£ki displej s oznakom DISP4 prikazuje znamenke jedinica i spojen je na prvi posma£niregistar,

Prema tome, kada se posma£ni registri pune £etveroznamenkastim brojevima, pune seredoslijedom: znamenka tisu¢ice, znamenka stotice, znamenka desetice i na kraju znamenkajedinice.

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku SSD-SBR.zip. Na radnojpovr²ini stvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢i pritomdijakriti£ke znakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢ete stvoriti zvat ¢e seIvica Ivic. Datoteku SSD-SBR.zip raspakirajte u novostvorenu datoteku na radnoj povr²ini.Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini te dvostrukim klikom pokreniteVUB mikroracunala.atsln u datoteci \\SSD-SBR\vjezbe. U otvorenom projektu nalaze se svevjeºbe koja ¢emo obraditi u poglavlju Numeri£ki displej i posma£ni registar. Vjeºbe ¢emopisati u datoteke s ekstenzijom *.cpp.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koja moºete koristiti za provjeru ispravnostiprogramskih zadataka. Na razvojnom okruºenju sa slike 3.1 odspojite LCD displej.

Vjeºba 9.1.1

Napravite program pomo¢u kojeg ¢ete na sva £etiri posma£na registra postaviti 8-bitni podatak0x66. Shema spajanja £etiriju posma£nih registara i numeri£kih displeja na mikroupravlja£ATmega32U4 prikazana je na slici 9.9.

U projektnom stablu otvorite datoteku vjezba911.cpp. Omogu¢ite samo prevoenjedatoteke vjezba911.cpp. Po£etni sadrºaj datoteke vjezba911.cpp prikazan je programskimkodom 9.1.

Programski kod 9.1: Po£etni sadrºaj datoteke vjezba911.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

void inicijalizacija ()

output_port(DDRC , PC7); // digitalni izlaz spojen na SI

output_port(DDRF , PF1); // digitalni izlaz spojen na SCK

output_port(DDRF , PF0); // digitalni izlaz spojen na RCK

158 Numeri£ki displej i posma£ni registar

int main(void)

inicijalizacija ();

uint8_t number = 0x66;

for (int i = 0; i < 8; i++)

if(number & 0x01) // ako je number LSB == 1

set_port(PORTC , PC7 , 1); // na SI po²alji 1

else // ako je number LSB == 0

set_port(PORTC , PC7 , 0); // na SI po²alji 0

// rastu¢i brid signala SCK

set_port(PORTF , PF1 , 1); //SCK = 1

_delay_us (1);

set_port(PORTF , PF1 , 0); //SCK = 0

_delay_us (1);

number = number >> 1; // posmakni broj za jedan u desno

// rastu¢i brid signala RCK

set_port(PORTF , PF0 , 1); //RCK = 1

_delay_us (1);

set_port(PORTF , PF0 , 0); //RCK = 0

_delay_us (1);

while (1)

_delay_ms (100);

return 0;

Rezultat slanja 8-bitnog podatka 0x66 na sva £etiri posma£na registra bit ¢e uklju£enjejednakih segmenata na sva £etiri numeri£ka displeja koji su spojeni na posma£ne registre. Koji¢e znak biti prikazan na numeri£kim displejima zasad ne znamo.

U programskom kodu 9.1 nalazi se programsko rje²enje koje postavlja jedan 8-bitni podatakna prvi posma£ni registar1. U funkciji inicijalizacija() kongurirani su sljede¢i digitalniizlazi za potrebe slanja podataka na posma£ni registar:

• pin PC7 spojen je na ulaz SI prvog posma£nog registra,

• pin PF1 spojen je na ulaz SCK svih £etiri posma£na registra,

• pin PF0 spojen je na ulaz RCK svih £etiri posma£na registra.

Binarna kombinacija za broj 0x66 koji se ²alje na prvi posma£ni registar jest 01100110. Umain() funkciji za slanje 8 bitova koristi se for petlja koja se izvr²ava osam puta. U jednomkoraku for petlje provode se sljede¢e radnje:

• naredbom if(number & 0x01) ispitujemo stanje LSB bita, odnosno bita 0. Ako je bit 0u stanju 1, tada se na izlazni pin PC7 koji je spojen na ulaz SI postavlja visoko stanje(binarna 1). Ina£e, se na izlazni pin PC7 koji je spojen na ulaz SI postavlja nisko stanje(binarna 0). U prvom koraku for petlje SI = 0.

1Ako se mikroupravlja£ resetira vi²e puta, a razvojno okruºenje ne izgubi napajanje, svi posma£ni registripopunit ¢e se istim 8-bitnim podatkom.

9.1 Vjeºbe - numeri£ki displej i posma£ni registar 159

• nakon ²to je pripremljen bit na ulazu SI, na izlaznom pinu PF1 koji je spojen na ulaz SCKgenerira se impuls trajanja 1 µs2 kako bi se na rastu¢i brid signala SCK napravio posmakbitova u posma£nim registrima.

• naredbom number = number >> 1; binarna kombinacija posmi£e se udesno za jednomjesto kako bi u sljede¢em koraku na poziciju bita 0 do²ao sljede¢i bit koji se ²alje naSI ulaz. U prvom koraku for petlje varijabla number nakon posmicanja udesno za jedankorak poprima vrijednost 00110011.

Nakon osam koraka for petlje 8-bitni podatak postavljen je u prvi posma£ni registar. Akotaj podatak ºelimo postaviti na izlaze posma£nog registra, tada se na izlaznom pinu PF0 koji jespojen na ulaz RCK generira impuls trajanja 1 µs kako bi se na rastu¢i brid sadrºaj Registraza punjenje proslijedio na Izlazni registar. Nakon slanja jednog 8-bitnog podatka na prviposma£ni registar while petlja se izvr²ava s ka²njenjem iznosa od 100 ms.

Prevedite datoteku vjezba911.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Odspojite napajanje na razvojnom okruºenju i spojite ga nazad. Na numeri£kom displeju DISP4prikazana je znamenka 4. Pritisnite tipku RESET kako biste resetirali mikroupravlja£ barem triputa. Primijetite kako se sada na svima numeri£kim displejima pojavila znamenka 4. Za²to?

Da biste odmah na sva £etiri numeri£ka displeja ispisali kombinaciju 4444, for petlju uprogramskom kodu 9.1 potrebno je izvr²iti £etiri puta. To ¢ete napraviti tako da for petljukojom punite posma£ni registar ugnjezdite u for petlju koja ¢e se izvr²iti £etiri puta. Vanjskafor petlja prikazana je u programskom kodu 9.2. S obzirom na to da varijabla number nakonosam posmicanja udesno poprima vrijednost 0, varijabli number u svakoj je iteraciji vanjske petljeponovno potrebno dodijeliti vrijednost 0x66. Nakon ²to se napune sva £etiri posmi£na registra,impulsom na ulaz RCK osvjeºavaju se izlazi posmi£nih registara.

Programski kod 9.2: Vanjska for petlja koju je potrebno dodati u programski kod 9.1

for(int n = 0; n < 4; n++)

number = 0x66;

// for petlja za punjenje posma£nog registra

// rastu¢i brid signala RCK

set_port(PORTF , PF0 , 1); //RCK = 1

_delay_us (1);

set_port(PORTF , PF0 , 0); //RCK = 0

_delay_us (1);

Ponovno prevedite datoteku vjezba911.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

U programskom kodu 9.3 prikazan je novi sadrºaj kojim je potrebno zamijeniti programskikod 9.1 u datoteci vjezba911.cpp. U ovom slu£aju stvoreni su sljede¢i objekti tipaDigitalOutput:

• DigitalOutput ShiftReg_SI(C7) - objekt koji upravlja pinom PC7 koji je spojen na ulazSI prvog posma£nog registra,

• DigitalOutput ShiftReg_SCK(F1) - objekt koji upravlja pinom PF1 koji je spojen naulaz SCK prvog posma£nog registra,

2Prema tehni£kim specikacijama sklopa 74HC595D, ovo vrijeme mora biti ve¢e od 15 ns pa se ka²njenje iznosa1 µs moºe izbrisati iz programskog koda, ²to ¢e dati impuls ²irine 62.5 ns (1/16 MHz = jedna instrukcija).

160 Numeri£ki displej i posma£ni registar

• DigitalOutput ShiftReg_RCK(F0) - objekt koji upravlja pinom PF0 koji je spojen naulaz RCK prvog posma£nog registra.

Programski kod 9.3: Novi sadrºaj datoteke vjezba911.cpp - kori²tenje klase DigitalOutput

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "DigitalIO/DigitalIO.h"

int main(void)

DigitalOutput ShiftReg_SI(C7);

DigitalOutput ShiftReg_SCK(F1);

DigitalOutput ShiftReg_RCK(F0);

uint8_t number;

for(int n = 0; n < 4; n++)

number = 0x66;

for(int i = 0; i < 8; i++)

if(number & 0x01) // ako je bit0 == 1

ShiftReg_SI.set(); // na SI po²alji 1

else // ako je bit0 == 0

ShiftReg_SI.reset(); // na SI po²alji 0

// rastu¢i brid signala SCK

ShiftReg_SCK.set(); //SCK = 1

_delay_us (1);

ShiftReg_SCK.reset(); //SCK = 0

_delay_us (1);

number = number >> 1; // posmakni broj za jedan u desno

// rastu¢i brid signala RCK

ShiftReg_RCK.set(); //RCK = 1

_delay_us (1);

ShiftReg_RCK.reset(); //RCK = 0

_delay_us (1);

while (1)

_delay_ms (100);

return 0;

Primijetite da su makronaredbe set_port zamijenjene pozivima metoda nad objektima(ShiftReg_SCK.set() umjesto set_port(PORTF, PF0, 1) itd.). Ostali dio koda isti je kao uprogramskom kodu 9.1. Ponovno prevedite datoteku vjezba911.cpp u strojni kod i snimite ga namikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£emATmega32U4.

U programskom kodu 9.4 prikazan je novi sadrºaj koji je potrebno napisati u datotekuvjezba911.cpp koji je temeljen na sljede¢im funkcijama koje su napisane u zaglavlju ssd_sbr.h:

• shift_bit_init() - funkcija koja inicijalizira posma£ni registar, odnosno konguriradigitalne izlaze mikroupravlja£a spojene na ulaze posma£nog registra SI, SCK i RCK.

• shift_bit_clock_sck() - funkcija za generiranje impulsa ²irine 1 µs na ulazu SCK,

9.1 Vjeºbe - numeri£ki displej i posma£ni registar 161

• shift_bit_clock_rck() - funkcija za generiranje impulsa ²irine 1 µs na ulazu RCK,

• shift_bit_send_1byte(uint8_t number) - funkcija za slanje jednog bajta podataka(number) na posma£ni registar,

• shift_bit_send_4byte(uint8_t num1, uint8_t num2, uint8_t num3, uint8_t num4)- funkcija za slanje £etiriju bajtova (num1, num2, num3, num4) na posma£ni registarredoslijedom argumenata funkcije.

Funkcije za slanje podataka na posma£ne registre zasnovane su na programskom kodu 9.1.

Programski kod 9.4: Novi sadrºaj datoteke vjezba911.cpp - kori²tenje funkcija zaglavljassd_sbr.h

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "SSD i SBR/ssd_sbr.h"

void inicijalizacija ()

// konfiguracija pinova mikroupravlja£a koji su spojeni

// na Shift Bit Register (definirati konstante u ssd_sbr.h)

shift_bit_init ();

int main(void)

inicijalizacija ();

uint8_t number = 0x66;

// petlja koja pojedina£no ²alje £etiri bajta

for(int n = 0; n < 4; n++)

shift_bit_send_1byte(number);

// generiranje impulsa na RCK

shift_bit_clock_rck ();

while (1)

_delay_ms (100);

return 0;

Neposredno prije kori²tenja posma£nog registra spojenog na mikroupravlja£ u zaglavljussd_sbr.h konstantama je potrebno dodijeliti informacije o pinovima mikroupravlja£a koji suspojeni na ulaze posma£nog registra SI, SCK i RCK. Denirane konstante u zaglavlju ssd_sbr.hprikazane su u programskom kodu 9.5. S obzirom na to da je pin PC7 spojen na ulaz SI, konstantiSI_DDR dodijeljen je registar DDRC, konstanti SI_PORT dodijeljen je registar PORTC, a konstantiSI_PIN dodijeljena je pozicija pina PC7. Isto vrijedi i za ostale ulaze posma£nog registra.

162 Numeri£ki displej i posma£ni registar

Programski kod 9.5: Deniranje konstanti za konguriranje pinova mikroupravlja£a spojenih naulaze posma£nog registra

//DDR registri za ulaze SI , SCK i RCK

#define SI_DDR DDRC

#define SCK_DDR DDRF

#define RCK_DDR DDRF

//PORT registri za ulaze SI , SCK i RCK

#define SI_PORT PORTC

#define SCK_PORT PORTF

#define RCK_PORT PORTF

// pinovi za ulaze SI, SCK i RCK

#define SI_PIN PC7

#define SCK_PIN PF1

#define RCK_PIN PF0

Prevedite datoteku vjezba911.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Zamijenite sada for petlju u programskom kodu 9.4 koja pojedina£no ²alje 4 bajta podatkana posma£ne registre pomo¢u funkcije shift_bit_send_1byte(uint8_t number) funkcijomkoja odjednom ²alje 4 bajta podataka na posma£ne registra. Ponovno prevedite datotekuvjezba911.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte programna razvojnom okruºenju s mikroupravlja£em ATmega32U4.

U zaglavlje DigitalIO.h dodana je nova klasa koja se zove Shift_Bit_Register. U klasiShift_Bit_Register denirana su dva preoptere¢ena konstruktora, od kojih je jedan tipadefault. Stvaranje objekata koji su tipa Shift_Bit_Register mogu¢e je na sljede¢i na£in:

• Shift_Bit_Register SBR(C7, F1, F0); - objekt se inicijalizira trima konstantama oblikaXi (X = B, C, D, E, F; i = 0,1,2,3,4,5,6,7) gdje X ozna£ava port, a i pin na portu. Npr. zapin 7 na portu C koristit ¢emo konstantu C7 , a za pin 1 na portu F koristit ¢emo konstantuF1. Prvi argument konstruktora jest pin na koji je spojen ulaz SI (PC7), drugi argumentkonstruktora jest pin na koji je spojen ulaz SCK (PF1), a tre¢i argument konstruktora jestpin na koji je spojen ulaz RCK (PF0).

Kori²tenje klase Shift_Bit_Register prikazano je u programskom kodu 9.6. BibliotekaDigitalIO.h u kojoj se nalazi klasa Shift_Bit_Register u programski kod 9.6 uklju£ena jepomo¢u naredbe #include "DigitalIO/DigitalIO.h". Primijetite kako u ovom pristupu nemainicijalizacijske funkcije inicijalizacija(). Razlog tome je taj ²to se objekti trebaju tretiratikao i varijable jer egzistiraju samo u bloku u kojem su denirani. Dakle, objekt SBR dohvatljivje samo u main() funkciji.

Klasa Shift_Bit_Register ima brojne metode (funkcije klase) koje se mogu pozvati nadobjektima:

• clock_sck() - metoda generira impuls ²irine 1 µs na ulazu SCK,

• clock_rck() - metoda generira impuls ²irine 1 µs na ulazu RCK,

• send_1byte(uint8_t number) - metoda sluºi za slanje jednog bajta podataka (number)na posma£ni registar,

• send_4byte(uint8_t num1, uint8_t num2, uint8_t num3, uint8_t num4) - metodasluºi za slanje £etiriju bajtova (num1, num2, num3, num4) na posma£ni registarredoslijedom argumenata metode.

9.1 Vjeºbe - numeri£ki displej i posma£ni registar 163

Programski kod 9.6: Novi sadrºaj datoteke vjezba911.cpp - kori²tenje klaseShift_Bit_Register zaglavlja DigitalIO.h

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "DigitalIO/DigitalIO.h"

int main(void)

// stvaranje objekta za posma£ni registar

Shift_Bit_Register SBR(C7 , F1 , F0);

uint8_t number = 0x66;

// petlja koja pojedina£no ²alje £etiri bajta

for(int n = 0; n < 4; n++)

SBR.send_1byte(number);

// generiranje impulsa na RCK

SBR.clock_rck ();

while (1)

_delay_ms (100);

return 0;

Prevedite datoteku vjezba911.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Zamijenite sada for petlju u programskom kodu 9.6 koja pojedina£no ²alje 4 bajta podatkana posma£ne registre pomo¢u poziva metode nad objektom SBR.send_1byte(number) pozivommetode koja odjednom ²alje 4 bajta podataka na posma£ne registra. Ponovno prevedite datotekuvjezba911.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte programna razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba911.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 9.1.2

Napravite program u kojem ¢ete na numeri£kim displejima izmjenjivati znakove sa slika 9.10 i9.11 svakih 1000 ms.

a

b

c

d

e

f

g

p

a

b

c

d

e

f

g

p

a

b

c

d

e

f

g

p

a

b

c

d

e

f

g

p

Slika 9.10: Znakovi za prikaz na numeri£kim displejima (1)

164 Numeri£ki displej i posma£ni registar

a

b

c

d

e

f

g

p

a

b

c

d

e

f

g

p

a

b

c

d

e

f

g

p

a

b

c

d

e

f

g

p

Slika 9.11: Znakovi za prikaz na numeri£kim displejima (2)

Shema spajanja £etiriju posma£nih registara i numeri£kih displeja na mikroupravlja£ATmega32U4 prikazana je na slici 9.9.

U projektnom stablu otvorite datoteku vjezba912.cpp. Omogu¢ite samo prevoenjedatoteke vjezba912.cpp. Po£etni sadrºaj datoteke vjezba912.cpp prikazan je programskimkodom 9.7.

Programski kod 9.7: Po£etni sadrºaj datoteke vjezba912.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "DigitalIO/DigitalIO.h"

int main(void)

// stvaranje objekta za posma£ni registar

Shift_Bit_Register SBR(C7 , F1 , F0);

// heksadecimalni kodovi znakova sa slika 9.10 i 9.11

// inicijalizirajte polja: npr. signs1 [4] = 0x66 , 0x77 , 0x88 , 0x99;

uint8_t signs1 [4] = ;

uint8_t signs2 [4] = ;

while (1)

// po²alji znakove sa slike 9.10

for(int n = 0; n < 4; n++)

SBR.send_1byte(signs1[n]);

SBR.clock_rck (); // generiranje impulsa na RCK

_delay_ms (1000);

// po²alji znakove sa slike 9.11

SBR.send_4byte(signs2 [0], signs2 [1], signs2 [2], signs2 [3]);

_delay_ms (1000);

return 0;

U programskom kodu 9.7 prikazana je main() funkcija u kojoj je stvoren objekt SBR tipaShift_Bit_Register, sukladno uputama u prethodnoj vjeºbi. Najvaºniji zadatak u ovoj vjeºbijest kreirati traºene znakove prikazane na slikama 9.10 i 9.11. Znakovi se kreiraju tako dase segmentima koji moraju biti uklju£eni dodijeli logi£ka vrijednost 1, a segmentima kojimoraju biti isklju£eni dodijeli logi£ka vrijednost 0. Na primjer, znak C bit ¢e prezentiran nanumeri£kom displeju ako su uklju£eni segmenti a, d, e, f, a isklju£eni segmenti b, c, g,h. Temeljem informacije o uklju£enosti i isklju£enosti segmenata kreira se binarna kombinacijaoblika abcdefgh, odnosno za znak C 10011100. Deniranje preostalih znakova sa slika 9.10 i 9.11

9.1 Vjeºbe - numeri£ki displej i posma£ni registar 165

prikazano je u tablici 9.3. Denirane znakove potrebno je u programskom kodu 9.7 dodijelitideklariranim cjelobrojnim poljima3 signs1 i signs2.

Tablica 9.3: Deniranje znakova sa slika 9.10 i 9.11

ZnakSegmenti

(hex)QA QB QC QD QE QF QG QH

a b c d e f g pa

b

c

d

e

f

g

p 1 0 0 1 1 1 0 0 0x9Ca

b

c

d

e

f

g

p 0 1 1 0 1 1 1 0 0x6Ea

b

c

d

e

f

g

p 0 0 0 0 1 1 0 0 0x0Ca

b

c

d

e

f

g

p 1 1 0 0 1 1 1 0 0xCEa

b

c

d

e

f

g

p 1 1 1 1 0 0 1 0 0xF2a

b

c

d

e

f

g

p 1 1 0 1 1 0 1 0 0xDAa

b

c

d

e

f

g

p 0 1 1 1 1 1 0 0 0x7Ca

b

c

d

e

f

g

p 0 1 1 0 0 1 1 0 0x66

Izmjena znakova sa slika 9.10 i 9.11 implementirana je u while petlji u programskom kodu9.7 kori²tenjem metode za slanje jednog bajta (send_1byte(uint8_t)) i kori²tenjem metode zaslanje £etiriju bajtova odjednom (send_4byte(uint8_t, uint8_t, uint8_t, uint8_t)).

Prevedite datoteku vjezba912.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Promijenite programski kod 9.7 tako da za prikaz znakova ne koristite klasuShift_Bit_Register, ve¢ funkcije denirane u zaglavlju ssd_sbr.h. Prevedite datotekuvjezba912.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte programna razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba912.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 9.1.3

Napravite program u kojim ¢ete realizirati ²topericu na preciznost desetinke sekunde. topericase pokre¢e i zaustavlja tipkalom spojenim na pin PD0. Resetiranje ²toperice na po£etno stanje000.0 potrebno je omogu¢iti pomo¢u tipkala spojenog na pin PD1. Maksimalno vrijeme koje²toperica moºe prikazati jest 999.9. Shema spajanja £etiriju posma£nih registara i numeri£kihdispleja na mikroupravlja£ ATmega32U4 prikazana je na slici 9.9.

U projektnom stablu otvorite datoteku vjezba913.cpp. Omogu¢ite samo prevoenje datotekevjezba913.cpp. Po£etni sadrºaj datoteke vjezba913.cpp prikazan je programskim kodom 9.8.

Programski kod 9.8: Po£etni sadrºaj datoteke vjezba913.cpp

#include <avr/io.h>

3Polja je potrebno inicijalizirati: npr uint8_t signs1[4] = 0x9C, 0x6E, 0x0C, 0xCE;.

166 Numeri£ki displej i posma£ni registar

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "DigitalIO/DigitalIO.h"

#include "SSD i SBR/ssd_sbr.h"

int main(void)

// stvaranje objekta za posma£ni registar

Shift_Bit_Register SBR(C7 , F1 , F0);

DigitalInput StartStop(D0); // PD0 ulazni pin

DigitalInput Clear(D1); // PD1 ulazni pin

StartStop.pullup_on (); //pull up na PD0

Clear.pullup_on (); //pull up na PD1

uint16_t desetinke = 0;

uint8_t d1 = 0, d2 = 0, d3 = 0, d4 = 0;

// slanje £etiri bajta na posma£ne registre

SBR.send_4byte(digits[d1], digits[d2], digits[d3] | DOT , digits[d4]);

bool counting = false;

while (1)

// na padaju¢i brid tipkala StartStop

if(StartStop.isFalling_edge ())

if (counting)

counting = false;

else

counting = true;

// na padaju¢i brid tipkala Clear

if(Clear.isFalling_edge ())

desetinke = 0;

d1 = d2 = d3 = d4 = 0;

SBR.send_4byte(digits[d1], digits[d2], digits[d3]

| DOT , digits[d4]);

if (counting)

// ra£unanje znamenaka

d1 = desetinke / 1000;

d2 = (desetinke / 100) % 10;

d3 = (desetinke / 10) % 10;

d4 = desetinke % 10;

SBR.send_4byte(digits[d1], digits[d2], digits[d3]

| DOT , digits[d4]);

// brojanje desetinki sekunde

_delay_ms (100);

if (++ desetinke > 9999)

desetinke = 0;

return 0;

Na po£etku main() funkcije u programskom kodu 9.8 stvoreni su objekt tipaShift_Bit_Register koji se koristi za punjenje posma£nog registra i dva objekta tipaDigitalInput koji se koriste za o£itanje stanja tipkala koji su spojeni na digitalne pinove PD0i PD1. Na digitalnim ulazima PD0 i PD1 uklju£eni su pritezni otpornici.

9.1 Vjeºbe - numeri£ki displej i posma£ni registar 167

Varijabla desetinke sluºi za brojanje desetinki sekundi, dok se varijable d1, d2, d3 i d4koriste za znamenke tisu¢ica, stotica, desetica i jedinica. U zaglavlju ssd_sbr.h denirali smopolje s deset elemenata koje prema tablici 9.2 sadrºi binarne kombinacije uklju£enih i isklju£enihsegmenata za prezentaciju brojeva. Naziv tog polja jest digits, a znamenke koje ºelimo prikazatina numeri£kim displejima adresiraju se indeksom polja. Na primjer, ako ºelimo prikazati broj 4na numeri£kom displeju, indeksirat ¢emo element digits[4] itd. U programskom kodu 9.8naredbom #include "SSD i SBR/ssd_sbr.h" uklju£ili smo zaglavlje ssd_sbr.h u kojem jedenirano polje digits. Po£etno su sve znamenke postavljene na 0 i poslane na posma£neregistre, odnosno prezentirane na numeri£kim displejima.

U naredbi SBR.send_4byte(digits[d1], digits[d2], digits[d3] | DOT, digits[d4]);na poziciji znamenke d3 nalazi se konstanta DOT u bitovnoj ILI operaciji s digits[d3]. KonstantaDOT ima vrijednost 0x01, a sluºi za uklju£enje to£ke, odnosno segmenta h na numeri£kom displeju.S obzirom na to da nam je cilj prezentirati sekunde na numeri£kim displejima, a vrijeme mjerimona preciznost jedne desetinke sekunde, to£ka ide iza tre¢e znamenke.

Varijabla counting je tipa bool i koristi se kao indikator na sljede¢i na£in:

• ako je varijabla counting == false, tada ²toperica ne mjeri vrijeme,

• ako je varijabla counting == true, tada ²toperica mjeri vrijeme.

Ova varijabla mijenja svoje stanje na svaki padaju¢i brid tipkala StartStop pomo¢u ifnaredbe koja provjerava stanje varijable counting i mijenja ga u negirano stanje. Uvjetovaniif blok naredaba moºe se zamijeniti jednom naredbom counting ^= true; koja mijenja stanjevarijable counting. Tipkalom Clear e varijabla desetinke i sve znamenke postavljaju se na 0.

Vrijeme koje se nalazi u varijabli desetinke potrebno je rastaviti na znamenke tisu¢ica,stotica, desetica i jedinica. Znamenke smo u programskom kodu 9.8 redom izra£unali na sljede¢ina£in:

• d1 - znamenka tisu¢ica dobije se cjelobrojnim dijeljenjem varijable desetinke s 1000 (npr.1204/1000 = 1 ⇒ d1 = 1),

• d2 - znamenka stotica dobije se tako da se varijabla desetinke podijeli sa 100, a zatim seizra£una ostatak pri cjelobrojnom dijeljenju s 10 (npr. 1204/100 = 12 ⇒12%10 = 2 ⇒ d2= 2)

• d3 - znamenka desetica dobije se tako da se varijabla desetinke podijeli s 10, a zatim seizra£una ostatak pri cjelobrojnom dijeljenju s 10 (npr. 1204/10 = 120 ⇒ 120%10 = 0 ⇒d3 = 0),

• d4 - znamenka jedinica dobije se tako da se izra£una ostatak cjelobrojnog djeljenja varijabledesetinke s 10 (npr. 1204%10 = 4 ⇒ d4 = 4).

Varijabla desetinke uve¢ava se u while petlji s ka²njenjem od 100 ms i ograni£ena je namaksimalnu vrijednost 9999, nakon £ega se postavlja u 0. Ovo rje²enje zapravo nije najzgodnijejer je, osim ka²njenja iznosa od 100 ms, u while petlji veliki broj naredaba koje za svoje izvoenjetro²e mikroprocesorsko vrijeme.

Prevedite datoteku vjezba913.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Preciznije mjerenje vremena moºe se ostvariti pomo¢u tajmera. Dodatno, zanimljivo bibilo implementirati i mogu¢nost mjerenja vremena prema gore i prema dolje (odbrojavanje).Navedene zna£ajke implementirane su u programskom kodu 9.9. Za mjerenje vremena kori²tenje sklop Timer/Counter1 koji je konguriran tako da prekidnu rutinu poziva to£no svakih 100ms. Prou£ite razlike u programskim kodovima 9.8 i 9.9. Klju£ne su sljede¢e razlike:

168 Numeri£ki displej i posma£ni registar

• varijable desetinke i count_up postale su globalne jer im doseg mora biti globalan,

• koristi se varijabla new_time_ready koja poprima vrijednost true kad tajmer generira novudesetinku sekunde te omogu¢uje ispis na numeri£ke displeje. Kada se novo vrijeme ispi²ena numeri£ke displeje, varijabla new_time_ready poprima vrijednost false,

• ovisno o tome mjeri li ²toperica vrijeme ili ne, sklop Timer/Counter1 omogu¢uje se ili neomogu¢uje,

• stvoren je novi objekt tipa DigitalInput naziva Direction koji na padaju¢i brid tipkalaspojenog na pin PF6 mijenja smjer mjerenja vremena,

• uklju£ena su sva potrebna zaglavlja.

Prepravite datoteku vjezba913.cpp u skladu s programskim kodom 9.9 te prevedite datotekuvjezba913.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajte programna razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Programski kod 9.9: Novi sadrºaj datoteke vjezba913.cpp - napredniji pristup rje²enju

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "DigitalIO/DigitalIO.h"

#include "SSD i SBR/ssd_sbr.h"

#include "Timer/timer.h"

#include "Interrupt/interrupt.h"

uint16_t desetinke = 0;

bool count_up = true;

bool new_time_ready = false;

ISR(TIMER1_OVF_vect)

TCNT1 = 40536;

new_time_ready = true;

if(count_up)

if (++ desetinke > 9999)

desetinke = 0;

else

if (--desetinke == 65535)

desetinke = 9999;

void inicijalizacija ()

// normalna na£in rada - timer 1

timer1_set_normal_mode ();

timer1_set_prescaler(TIMER1_PRESCALER_64);

TCNT1 = 40536;

interrupt_enable ();

int main(void)

inicijalizacija ();

// stvaranje objekta za posma£ni registar

Shift_Bit_Register SBR(C7 , F1 , F0);

DigitalInput StartStop(D0); // PD0 ulazni pin

9.1 Vjeºbe - numeri£ki displej i posma£ni registar 169

DigitalInput Clear(D1); // PD1 ulazni pin

DigitalInput Direction(F6); // PF6 ulazni pin

StartStop.pullup_on (); //pull up na PD0

Clear.pullup_on (); //pull up na PD1

Direction.pullup_on (); //pull up na PF6

bool counting = false;

uint8_t d1 = 0, d2 = 0, d3 = 0, d4 = 0;

// slanje £etiri bajta na posma£ne registre

SBR.send_4byte(digits[d1], digits[d2], digits[d3] | DOT , digits[d4]);

while (1)

// na padaju¢i brid tipkala StartStop

if(StartStop.isFalling_edge ())

if (counting)

counting = false;

timer1_interrupt_OVF_disable ();

else

counting = true;

timer1_interrupt_OVF_enable ();

// na padaju¢i brid tipkala Direction

if(Direction.isFalling_edge ())

if (count_up)

count_up = false;

else

count_up = true;

// na padaju¢i brid tipkala Clear

if(Clear.isFalling_edge ())

desetinke = 0;

d1 = d2 = d3 = d4 = 0;

SBR.send_4byte(digits[d1], digits[d2], digits[d3]

| DOT , digits[d4]);

// ako je tajmer generirao novih 100 ms, prikaºi ih

if (new_time_ready)

// ra£unanje znamenaka

d1 = desetinke / 1000;

d2 = (desetinke / 100) % 10;

d3 = (desetinke / 10) % 10;

d4 = desetinke % 10;

SBR.send_4byte(digits[d1], digits[d2], digits[d3]

| DOT , digits[d4]);

new_time_ready = false;

return 0;

Zatvorite datoteku vjezba913.cpp i onemogu¢ite prevoenje ove datoteke.

170 Numeri£ki displej i posma£ni registar

Vjeºba 9.1.4

Napravite program koji ¢e na numeri£kim displejima ispisati napon na potenciometru spojenomna pin ADC5. Napon ispi²ite na tri decimalna mjesta. Shema spajanja £etiriju posma£nihregistara i numeri£kih displeja na mikroupravlja£ ATmega32U4 prikazana je na slici 9.9.

U projektnom stablu otvorite datoteku vjezba914.cpp. Omogu¢ite samo prevoenjedatoteke vjezba914.cpp. Po£etni sadrºaj datoteke vjezba914.cpp prikazan je programskimkodom 9.10.

Programski kod 9.10: Po£etni sadrºaj datoteke vjezba914.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "DigitalIO/DigitalIO.h"

#include "SSD i SBR/ssd_sbr.h"

#include "ADC/adc.h"

void inicijalizacija ()

adc_init (); // inicijalizacija AD pretvorbe

int main(void)

inicijalizacija ();

// stvaranje objekta za posma£ni registar

Shift_Bit_Register SBR(C7 , F1 , F0);

uint8_t d1, d2 , d3 , d4;

uint16_t napon_mV;

while (1)

napon_mV = adc_read(ADC5) * 5000.0 / 1023.0;

// ra£unanje znamenaka za prikaz

d1 = napon_mV / 1000;

d2 = (napon_mV / 100) % 10;

d3 = (napon_mV / 10) % 10;

d4 = napon_mV % 10;

// slanje £etiri bajta na posma£ne registre

SBR.send_4byte(digits[d1] | DOT , digits[d2], digits[d3], digits[d4]);

_delay_ms (200);

return 0;

U ovoj vjeºbi potrebno je prezentirati napon potenciometra na pinu ADC5 pomo¢unumeri£kih displeja. U programski kod 9.10 u funkciji inicijalizacija() pozovite funkcijuadc_init() kojom ¢ete inicijalizirati analogno-digitalnu pretvorbu.

Napon koji ¢emo prikazivati na numeri£kim displejima mora biti prezentiran na tri decimalnamjesta. Iz realnog broja mogu¢e je izvu¢i znamenke prije i poslije decimalne to£ke. U tom smislu,napon u V moºemo pomnoºiti s 1000 i dobiti £etveroznamenkasti cijeli broj, ²to ¢e predstavljatinapon u mV. Taj cijeli broj lako je rastaviti na znamenke tisu¢ica, stotica, desetica i jedinica.Budu¢i da znamo da smo izra£unali napon u mV, decimalnu ¢emo to£ku postaviti nakon prveznamenke kako bi prezentirani napon bio u V.

Analogno-digitalnom pretvorbom na pinu ADC5 dobit ¢emo broj iz cjelobrojnog intervala[0, 1023]. Taj broj treba skalirati na realni interval [0, 5,0] V. Ako prethodni realni interval

9.1 Vjeºbe - numeri£ki displej i posma£ni registar 171

pomnoºimo s 1000, dobit ¢emo cjelobrojni interval [0, 5000] mV. Relacija za izra£un intervala [0,5000] mV jest:

UADC5 =ADC5

1023· 5000. (9.1)

U relaciji (9.1) dobili smo napon u mV. elimo li prezentirati napon u V na numeri£kimdisplejima, na rezultatu pretvorbe prema relaciji (9.1) decimalnu to£ku pomi£emo za tri mjestaulijevo. Prema tome, kako smo ve¢ spomenuli, decimalna to£ka dolazi iza prve znamenke(digits[d1] | DOT). Relacija (9.1) implementirana je u while petlji, nakon £ega su izra£unateznamenke napona i poslane na numeri£ke displeje posredno preko posma£nih registara.

Prevedite datoteku vjezba914.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba914.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 9.1.5

Napravite program u kojem ¢ete na numeri£ke displeje ispisivati 25C, AH i -12.3naizmjence svakih 1000 ms. Shema spajanja £etiriju posma£nih registara i numeri£kih displejana mikroupravlja£ ATmega32U4 prikazana je na slici 9.9.

U projektnom stablu otvorite datoteku vjezba915.cpp. Omogu¢ite samo prevoenje datotekevjezba915.cpp. Po£etni sadrºaj datoteke vjezba915.cpp prikazan je programskim kodom 9.11.

Programski kod 9.11: Po£etni sadrºaj datoteke vjezba915.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "DigitalIO/DigitalIO.h"

#include "SSD i SBR/ssd_sbr.h"

int main(void)

// stvaranje objekta za posma£ni registar

Shift_Bit_Register SBR(C7 , F1 , F0);

while (1)

// slanje definiranih znakova na numeri£ke displeje

SBR.send_4byte(DIGIT_2 , DIGIT_5 , BIG_DEEGRE , CHAR_C);

_delay_ms (1000);

SBR.send_4byte(EMPTY_SPACE , CHAR_A , CHAR_H , EMPTY_SPACE);

_delay_ms (1000);

SBR.send_4byte(MINUS , DIGIT_1 , DIGIT_2 | DOT , DIGIT_3);

_delay_ms (1000);

return 0;

Numeri£ki displeji osim brojeva mogu prezentirati i druge znakove, sukladno segmentima kojisu uklju£eni ili isklju£eni. U zaglavlju ssd_sbr.h denirane su konstante s korisnim znakovimakoji se mogu prezentirati na numeri£kom displeju. U ovoj vjeºbi kori²teni su znakovi:

• DIGIT_2 - prikaz broja 2, ²to je ekvivalent digits[2],

• DIGIT_5 - prikaz broja 5, ²to je ekvivalent digits[5],

• BIG_DEEGRE - prikaz stupnjeva Celzijusevih,

• CHAR_C - prikaz slova C,

172 Numeri£ki displej i posma£ni registar

• EMPTY_SPACE - prikaz praznog mjesta,

• CHAR_A - prikaz slova A,

• CHAR_H - prikaz slova H,

• MINUS - prikaz predznaka -.

Navedeni se znakovi ²alju na posma£ne registre kako je to prikazano u programskomkodu 9.10. Prevedite datoteku vjezba915.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Proizvoljno u programski kod 9.10 dodajte prikaz novih znakova koji su denirani u zaglavljussd_sbr.h. Prevedite datoteku vjezba915.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba915.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

9.2 Zadaci - numeri£ki displej

Zadatak 9.2.1

Napravite program pomo¢u kojeg ¢ete na sva £etiri posma£na registra postaviti 8-bitni podatak0x9C. Shema spajanja £etiriju posma£nih registara i numeri£kih displeja na mikroupravlja£ATmega32U4 prikazana je na slici 9.9.

Zadatak 9.2.2

Napravite program u kojem ¢ete na numeri£kim displejima izmjenjivati znakove AudI i A3 svakih1000 ms. Shema spajanja £etiriju posma£nih registara i numeri£kih displeja na mikroupravlja£ATmega32U4 prikazana je na slici 9.9.

Zadatak 9.2.3

Napravite program u kojim ¢ete realizirati ²topericu na preciznost stotinke sekunde. topericase pokre¢e i zaustavlja tipkalom spojenim na pin PD0. Resetiranje ²toperice na po£etno stanje00.00 potrebno je omogu¢iti pomo¢u tipkala spojenog na pin PD1. Maksimalno vrijeme koje²toperica moºe prikazati jest 49.99. Shema spajanja £etiriju posma£nih registara i numeri£kihdispleja na mikroupravlja£ ATmega32U4 prikazana je na slici 9.9.

Zadatak 9.2.4

Napravite program koji ¢e prezentirati otpor potenciometra spojenog na pin ADC5 u kΩ na dvadecimalna mjesta (nazivni otpor potenciometra jest 10 kΩ). Shema spajanja £etiriju posma£nihregistara i numeri£kih displeja na mikroupravlja£ ATmega32U4 prikazana je na slici 9.9.

9.2 Zadaci - numeri£ki displej 173

Zadatak 9.2.5

Napravite program u kojem ¢ete na numeri£ke displeje ispisivati 18C, B B i -25.9naizmjence svakih 1000 ms. Shema spajanja £etiriju posma£nih registara i numeri£kih displejana mikroupravlja£ ATmega32U4 prikazana je na slici 9.9.

174 Numeri£ki displej i posma£ni registar

Poglavlje 10

Univerzalna asinkrona serijska

komunikacija

Univerzalnu asinkronu serijsku komunikaciju omogu¢uje sklopovlje UART (engl. UniversalAsynchronous Receiver-Transmitter). Ovo sklopovlje koristi dva pina:

• RxD - pin za primanje podataka koji je povezan s primateljom (engl. receiver),

• TxD - pin za slanje podataka koji je povezan s po²iljateljom (engl. transmitter).

Pomo¢u RxD i TxD pinova omogu¢ena je dvosmjerna (engl. full-duplex ) komunikacija, ²tozna£i da dva ureaja mogu istovremeno i slati i primati podatke pomo¢u dviju ºice. Razlogtome jest ²to sklopovlje UART ima odvojene registre za primanje i slanje podataka. Shemapovezivanja dvaju ureaja sa sklopovljem UART prikazana je na slici 10.1. Princip spajanjauvijek je isti. RxD pin prvog ureaja spaja se na TxD pin drugog ureaja i obratno (slika 10.1).Mase (Gnd) dvaju ureaja koji komuniciraju moraju biti spojene zajedno kako bi ureaji imaliisti referentni potencijal.

Slika 10.1: Shema povezivanja dvaju ureaja sa sklopovljem UART

Komunikacija izmeu dvaju sklopovlja UART asinkrona je, ²to zna£i da ne postoji izvortakta koji sinkronizira prijenos podataka. Zbog asinkrone serijske komunikacije dva ureaja sasklopovljem UART koja razmjenjuju podatke moraju imati jednaku konguraciju parametara.Parametri sklopovlja UART jesu [4]:

• Brzina prijenosa podataka (engl. baude rate) - sklopovlje UART ima registar kojim sekongurira brzina prijenosa podataka u bitovima po sekundi (b/s). esto su kori²tenebrzine prijenosa od 9600 do 115200 b/s. Brzina prijenosa ovisi o radnom taktu ureaja

176 Univerzalna asinkrona serijska komunikacija

(mikroupravlja£a, ra£unala, modema) pa su izmeu brzina prijenosa od 9600 do 115200b/s dostupne samo neke brzine (naj£e²¢e one koje su vi²ekratnik frekvencije radnog takta).

• Broj podatkovnih bitova - broj podatkovnih bitova moºe biti 5, 6, 7, 8 i 9. Naj£e²¢e se kaobroj podatkovnih bitova koristi 8 jer je to 1 bajt (B) podataka.

• Paritetni bit (engl. parity bit) - omogu¢uje detekciju jednostrukih gre²aka u prijenosupodataka. Paritetni bit moºe biti omogu¢en ili onemogu¢en. Ako je omogu¢en, tada sepomo¢u njega moºe osigurati parni ili neparni paritet.

• Stop bit - bit koji ozna£ava kraj jednog podatka. Broj stop bitova moºe biti 1 ili 2.

Podatkovni okvir kod univerzalne asinkrone serijske komunikacije prikazan je na slici 10.2.

Slika 10.2: Podatkovni okvir kod univerzalne asinkrone serijske komunikacije

Kada se podaci ne ²alju izmeu dvaju ureaja, oba pina (RxD i TxD) u stanju su logi£kejedinice. To stanje je stanje mirovanja (engl. idle). Svako slanje podataka izmeu dvajuureaja po£inje tako da ureaj koji ²alje podatak svoj TxD pin postavlja u logi£ku nulu. Ovajprijelaz iz logi£ke jedinice u logi£ku nulu naziva se Start bit. Nakon Start bita, ²alju se bitovipodatka D0, D1, ..., D9. Broj podatkovnih bitova moºe se kongurirati, a naj£e²¢e se ²aljepodatak ²irine 8 bitova (1 B). Iza podatkovnih bitova, ako je omogu¢en, ²alje se paritetni bit.Komunikacija zavr²ava Stop bitom/bitovima. Stop bitovi uvijek su logi£ke jedinice. Trajanjebitova podatkovnog okvira sa slike 10.2 ovisi o brzini prijenosa podataka. Naj£e²¢e postavkeuniverzalne asinkrone serijske komunikacije jesu:

• brzina prijenosa podataka: prema potrebi i mogu¢nostima ureaja (npr. 19200),

• broj podatkovnih bitova: 8,

• paritetni bit: onemogu¢en,

• Stop bit: 1.

Kako bismo poslali 1 B (8 bitova) podataka, potrebno je poslati ukupno 10 bitova (1 Start bit+ 8 bitova podataka + 1 Stop bit = 10 bitova). Ako je brzina prijenosa 19200 b/s, tada se u jednojsekundi moºe poslati 1920 B podataka ( (19200 b/s) / (10 b/B) = 1920 B). Zbog asinkronogna£ina prijenosa, dva ureaja koja razmjenjuju podatke moraju biti jednako kongurirana. Usuprotnom tuma£enje podatka ne¢e biti ispravno.

Sklopovlje UART denira samo asinkroni serijski komunikacijski protokol, ali ne i zi£kekarakteristike ureaja koji komuniciraju. Na primjer, kod mikroupravlja£a se koristi TTL logikau kojoj je naponska razina logi£ke jedinice 5 V, a naponska razina logi£ke nule je 0 V. Kodra£unala se koristi standard RS232 u kojem je naponska razina logi£ke jedinice -12 V, a naponskarazina logi£ke nule je 12 V. Kako bismo ostvarili komunikaciju izmeu mikroupravlja£a i ra£unala,potrebno je koristiti prilagodni meusklop koji ¢e uskladiti naponske nivoe. Sklop koji se koristiu tu svrhu zove se MAX232. Danas ra£unala nemaju integrirani RS232 standard i COM portpa se sklop MAX232 gotovo i ne koristi u prakti£noj primjeni. e²¢e se danas koriste integriranikrugovi (prilagodni meusklopovi) koji rade pretvorbu izmeu USB ↔ TTL. Neki od poznatijihintegriranih krugova koji omogu¢uju ovu pretvorbu jesu CP2102 i FT232. Naime, ove ureajera£unalo promatra kao virtualni COM port koji radi na RS232 standardu.

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 177

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija

Mikroupravlja£ ATmega32U4 posjeduje sklopovlje USART (engl. Universal Synchronous andAsynchronous Serial Receiver and Transmitter). Ovo sklopovlje sluºi i za sinkronu i za asinkronukomunikaciju. U vjeºbama ¢emo koristiti samo asinkronu komunikaciju. U mikroupravlja£uATmega32U4 sklopovlje USART kompatibilno je sa sklopovljem UART koje smo prethodnoopisali. Podaci se na mikroupravlja£ ATmega32U4 asinkronom serijskom komunikacijom primajupomo¢u pina RXD1 (PD2), a ²alju pomo¢u pina TXD1 (PD3). Ukoliko na mikroupravlja£uATmega32U4 koristite asinkronu serijsku komunikaciju, tada digitalne pinove PD2 i PD3 nemoºete koristiti u druge svrhe. U svrhu vjeºbi, mikroupravlja£ ATmega32U4 spojit ¢emo sra£unalom koriste¢i ili prilagodni meusklop CP2102 na razvojnom okruºenju ili direktnimpristupom pinovima RXD1 i TXD1. Shema spajanja prilagodnog meusklopa CP2102 namikroupravlja£ ATmega32U4 prikazana je na slici 10.3.

+5V

GND

100n

10k

+5V

1uF

1k 1k

+5V +5V

CP2102GND

100n1uF

GND

100n

22p

22p

GND

GND

+5V

+5V

+5V

GND

UGND

22R

22R

USB konektor

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2

LED5 LED6

R11 R12

REGIN7

VDD6

GND3

VBUS8

D+4

D-5

RST 9

SUSPEND 12

SUSPEND 11

RI 2

DCD 1

DTR 28

DSR 27

TXD 26

RXD 25

RTS 24

CTS 23GNDEXPGNDM

IC8

1234

RX/TX

C9C10

C11

C12

C13

134 2

S5

21

Q1

R8

R9

123

JP7-2

123

JP7-1

2 1F2

11

22

33

44

55

SHIELDS1*6

J5

RESET

RESET

MISOMOSI

RX RX

RX

TX

TX

TX

AREF

D-D+

VUSB

VUSB

SCK

PD6

PC7

PE6

PD7

PC6

PF1PF0

UGND

USB-VCC

D1-

D1-

D1+

D1+

RX-CP2102

RX-CP2102

RX-CON

RX-CON

TX-CON

TX-CON

TX-CP2102

TX-CP2102

SS

Slika 10.3: Shema spajanja prilagodnog meusklopa CP2102 na mikroupravlja£ ATmega32U4

Na shemi sa slike 10.3 UART komunikacija moºe se koristiti na dva na£ina:

1. na£in: posredno preko prilagodnog meusklopa CP2102. U tom slu£aju kratkospojniciJP7-1 i JP7-2 moraju biti spojeni izmeu trnova 2 i 3.

2. na£in: direktnim pristupom UART pinovima mikroupravlja£a RXD1 i TXD1. U tomslu£aju kratkospojnici JP7-1 i JP7-2 moraju biti spojeni izmeu trnova 1 i 2.

Kada se koristi prilagodni meusklop CP2102, tada se razvojno okruºenje sa slike 3.1 nara£unalo povezuje mikro USB konektorom tipa B.

Podatak primljen preko RXD1 pina sprema se u meuspremnik primljenih podataka. Kada sepodatak ²alje preko TXD1 pina, on se neposredno prije slanja sprema u meuspremnik podatakaza slanje. Sklopovlje USART u mikroupravlja£u ATmega32U4 koristi istu memorijsku lokacijuregistra za slanje i za primanje podataka. Ime registra je UDR1. Kada £itamo podatak iz registraUDR1, tada kao povratnu vrijednost dobijemo podatak iz meuspremnika primljenih podataka.Kada podatak zapisujemo u registar UDR1, tada se on prosljeuje u meuspremnik podataka zaslanje. Sklopovlje USART automatski ²alje i prima podatke. Primljene podatke potrebno je navrijeme pro£itati iz registra UDR1 jer postoji opasnost da se novi podatak prepi²e preko staroga.Kada se na pinu RXD1 pojavi Start bit, mikroupravlja£ generira prekid. Na taj na£in novipodatak odmah moºemo pro£itati iz registra UDR1, bez obzira na to ²to se u glavnom programuizvodi dio programskog koda.

178 Univerzalna asinkrona serijska komunikacija

Rad sklopovlja USART kongurira se pomo¢u registara UCSR1A, UCSR1B i UCSR1C.Konguracija se odnosi na broj podatkovnih bitova, paritetni bit, broj Stop bitova, omogu¢avanjeprekida kada pristigne podatak i drugo. Podatkovni okvir koji podrºava mikroupravlja£ATmega32U4 isti je kao podatkovni okvir prikazan na slici 10.2. Vi²e detalja o konguracijiregistara UCSR1A, UCSR1B i UCSR1C pogledajte u literaturi [1] na stranicama 209 - 213.

Brzina prijenosa podataka kongurira se pomo¢u registra UBRR1, a ra£una se prema relaciji[1]:

BAUD =F_CPU

16(UBRR1 + 1). (10.1)

Vrijednost registra UBRR1 za frekvenciju radnog takta F_CPU i brzinu prijenosa BAUDmoºe se izra£unati iz relacije (10.1) na sljede¢i na£in:

UBRR1 =F_CPU

16 ·BAUD− 1. (10.2)

Rezultat dobiven pomo¢u relacije (10.2) mora biti cijeli broj jer ¢e se u suprotnom javljatipogre²ka pri prijenosu podataka. U tablicama 18-4 do 18-6 u literaturi [1] nalaze se vrijednostiregistra UBRR1 za standardne brzine prijenosa podataka1 i standardne frekvencije radnog takta tepostotna pogre²ka u prijenosu podataka. Frekvencija radnog takta koju mi koristimo u vjeºbamajest 16 MHz. Ako odaberemo brzinu prijenosa podataka od 19200 b/s, javit ¢e se pogre²ka uprijenosu podataka od 0,2 %2. Za pogre²ku u prijenosu podataka od 0,0 % za standardne brzineprijenosa preporu£uje se kori²tenje vanjskog izvora radnog takta od 7,3728 MHz, 11,0592 MHz,14,7456 MHz i 18,4320 MHz.

Rad asinkrone serijske komunikacije testirat ¢emo pomo¢u aplikacija za upravljanje inadzor razvojnog okruºenja s mikroupravlja£em ATmega32U4. S mreºne stranice www.vub.hr/mikroracunala skinite datoteku Serijska komunikacija - aplikacija.zip u kojoj se nalaziinstalacija aplikacije. Datoteku Serijska komunikacija - aplikacija.zip raspakirajte naradnu povr²inu u datoteku datoteke UART VUB. Aplikaciju pokrenite tako da pokrenete *.exedatoteku UART. Po£etni prozor aplikacije prikazan je na slici 10.4.

1Standardne brzine prijenosa: 2400 b/s, 4800 b/s, 9600 b/s, 19200 b/s, 14,4 kb/s, 19,2 kb/s, 28,8 kb/s,38,4kb/s, 57,6 kb/s, 76,8 kb/s, 115,2 kb/s, ...

2Ova je gre²ka zanemariva kada se ²alju mali paketi poruka (male tekstualne poruke), ²to je uobi£ajeno kodmikroupravlja£a.

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 179

Slika 10.4: Aplikacija za upravljanje i nadzor razvojnog okruºenja s mikroupravlja£emATmega32U4 pomo¢u serijske komunikacije

Aplikacija omogu¢uje interakciju s razvojnim okruºenjem sa slike 3.1. Moºe slati i primatitekstualne poruke. Aplikacija ¢e na razvojno okruºenje slati poruke zadanog sadrºaja i za sljede¢eakcije:

• Prvim pritiskom na tipku PD0 aplikacija pomo¢u serijskog porta ²alje poruku "B41\r",sljede¢im pritiskom ²alje poruku "B40\r" itd. Poruka "B41\r" uklju£uje crveno svjetlo uaplikaciji, a poruka "B40\r" isklju£uje crveno svjetlo u aplikaciji.

• Prvim pritiskom na tipku PD1 aplikacija pomo¢u serijskog porta ²alje poruku "B51\r",sljede¢im pritiskom ²alje poruku "B50\r" itd. Poruka "B51\r" uklju£uje ºuto svjetlo uaplikaciji, a poruka "B50\r" isklju£uje ºuto svjetlo u aplikaciji.

• Prvim pritiskom na tipku PF6 aplikacija pomo¢u serijskog porta ²alje poruku "B61\r",sljede¢im pritiskom ²alje poruku "B60\r" itd. Poruka "B61\r" uklju£uje zeleno svjetlo uaplikaciji, a poruka "B60\r" isklju£uje zeleno svjetlo u aplikaciji.

• Prvim pritiskom na tipku PF7 aplikacija pomo¢u serijskog porta ²alje poruku "B71\r",sljede¢im pritiskom ²alje poruku "B70\r" itd. Poruka "B71\r" uklju£uje plavo svjetlo uaplikaciji, a poruka "B70\r" isklju£uje plavo svjetlo u aplikaciji.

• Pritiskom na tipku Send aplikacija ¢e pomo¢u serijskog porta poslati poruku koja se nalaziu tekst okviru Message. Na primjer, ako u tekst okviru Message pi²e VUB MEH i RAC,aplikacija ¢e pomo¢u serijskog porta poslati poruku "VUB MEH i RAC\r".

• Promjenom stanja kliza£a Slider £iji je raspon vrijednosti cijelih brojeva [0, 255], aplikacija¢e pomo¢u serijskog porta poslati poruku formata "S%u*\r". U navedenoj poruci:

znak 'S' ozna£ava da se ²alje cjelobrojni podatak s kliza£a.

kvalikator "%u" je cjelobrojna vrijednost kliza£a Slider.

znakovi "*\r" su zaklju£ni znakovi kako bismo mogli detektirati kraj broja i krajporuke.

Na primjer, ako stanje kliza£a Slider iznosi 155, aplikacija ¢e pomo¢u serijskog portaposlati poruku "S155*\r".

180 Univerzalna asinkrona serijska komunikacija

• Pritiskom na tipku Send RGB aplikacija ¢e pomo¢u serijskog porta poslati poruku formata"R%u;%u;%u*\r". U navedenoj poruci:

znak 'R' ozna£ava da se ²alju tri cjelobrojne vrijednosti namijenjene za RGB diodu.

prvi kvalikator "%u" cjelobrojna je vrijednost kliza£a R £iji je raspon vrijednosti cijelihbrojeva [0, 100], a koristi se za upravljanjem intenziteta crvene diode na RGB diodi.

prvi znak ';' separator je prvog i drugog broja.

drugi kvalikator "%u" cjelobrojna je vrijednost kliza£a G £iji je raspon vrijednosticijelih brojeva [0, 100], a koristi se za upravljanjem intenziteta zelene diode na RGBdiodi.

drugi znak ';' separator je drugog i tre¢eg broja.

tre¢i kvalikator "%u" cjelobrojna je vrijednost kliza£a B £iji je raspon vrijednosticijelih brojeva [0, 100], a koristi se za upravljanjem intenziteta plave diode na RGBdiodi.

znakovi "*\r" zaklju£ni su znakovi kako bismo mogli detektirati kraj tre¢eg broja ikraj poruke.

Na primjer, ako stanje kliza£a R iznosi 23, stanje kliza£a G iznosi 172, a stanje kliza£a Biznosi 250, aplikacija ¢e pomo¢u serijskog porta poslati poruku "R23;172;250*\r".

Sigurno ste primijetili da svaka poruka zavr²ava specijalnim znakom "\r". Radi se o znakuCarriage Return (ASCII kod 0x0D), a koristi se kao zaklju£ni znak svake tekstualne poruke kakobi mikroupravlja£ mogao detektirati kraj poruke. U programu mikroupravlja£a znak CarriageReturn bit ¢e potrebno navesti kao zaklju£ni znak.

Ukupan promet podataka serijskim portom prikazuje se u tekstualnim okvirima ReceiveDialog (Rx) za dolazne poruke i Transmit Dialog (Tx) za odlazne poruke. Aplikacija ¢eobraditi primljene poruke zadanog sadrºaja na sljede¢i na£ni:

• ako na aplikaciju doe poruka "B41*\r", uklju£uje se crveno svjetlo u aplikaciji,

• ako na aplikaciju doe poruka "B40*\r", isklju£uje se crveno svjetlo u aplikaciji,

• ako na aplikaciju doe poruka "B51*\r", uklju£uje se ºuto svjetlo u aplikaciji,

• ako na aplikaciju doe poruka "B50*\r", isklju£uje se ºuto svjetlo u aplikaciji,

• ako na aplikaciju doe poruka "B61*\r", uklju£uje se zeleno svjetlo u aplikaciji,

• ako na aplikaciju doe poruka "B60*\r", isklju£uje se zeleno svjetlo u aplikaciji,

• ako na aplikaciju doe poruka "B71*\r", uklju£uje se plavo svjetlo u aplikaciji,

• ako na aplikaciju doe poruka "B80*\r", isklju£uje se plavo svjetlo u aplikaciji,

• ako na aplikaciju doe poruka formata "A;%u;%u;%u*\r", tada u navedenoj poruci:

znak 'A' ozna£ava da se primaju tri cjelobrojne vrijednosti namijenjene za trake zaprikaz napretka X, Y, Z.

prvi kvalikator "%u" cjelobrojna je vrijednost trake za prikaz napretka X £iji je rasponvrijednosti cijelih brojeva [0, 100].

prvi znak ';' separator je prvog i drugog broja.

drugi kvalikator "%u" cjelobrojna je vrijednost trake za prikaz napretka Y £iji jeraspon vrijednosti cijelih brojeva [0, 100].

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 181

drugi znak ';' separator je drugog i tre¢eg broja.

tre¢i kvalikator "%u" cjelobrojna je vrijednost trake za prikaz napretka Z £iji je rasponvrijednosti cijelih brojeva [0, 100].

znakovi "*\r" zaklju£ni su znakovi kako bismo mogli detektirati kraj poruke.

• ako na aplikaciju doe poruka formata "X;%u*\r", tada se cjelobrojna vrijednost "%u"postavlja na traku za prikaz napretka X.

• ako na aplikaciju doe poruka formata "Y;%u*\r", tada se cjelobrojna vrijednost "%u"postavlja na traku za prikaz napretka Y.

• ako na aplikaciju doe poruka formata "Z;%u*\r", tada se cjelobrojna vrijednost "%u"postavlja na traku za prikaz napretka Z.

• ako na aplikaciju doe poruka formata "P;%u;%u;%u;%u;%u;%u*\r", tada u navedenojporuci:

znak 'P' ozna£ava da se prima ²est cjelobrojnih vrijednosti namijenjenih za prikaz upolju podataka Values.

prvi kvalikator "%u" cjelobrojna je vrijednost koja se prikazuje u polju p11.

prvi znak ';' separator je prvog i drugog broja.

drugi kvalikator "%u" cjelobrojna je vrijednost koja se prikazuje u polju p21.

drugi znak ';' separator je drugog i tre¢eg broja.

tre¢i kvalikator "%u" cjelobrojna je vrijednost koja se prikazuje u polju p31.

tre¢i znak ';' separator je tre¢eg i £etvrtog broja.

£etvrti kvalikator "%u" cjelobrojna je vrijednost koja se prikazuje u polju p12.

£etvrti znak ';' separator je £etvrtog i petog broja.

peti kvalikator "%u" cjelobrojna je vrijednost koja se prikazuje u polju p22.

peti znak ';' separator je petog i ²estog broja.

²esti kvalikator "%u" cjelobrojna je vrijednost koja se prikazuje u polju p32.

znakovi "*\r" zaklju£ni su znakovi kako bismo mogli detektirati kraj poruke.

Sve navedene poruke aplikacija sa slike 10.4 obrauje svakih 50 ms. Preporuka je da se dvijeporuke prema aplikaciji ²alju u vremenskom razmaku od najmanje 50 ms. Konguracija serijskekomunikacije na ra£unalu moºe se postaviti pomo¢u prozora prikazanog na slici 10.5. Ovaj prozorotvorit ¢e se tako da u aplikaciji odaberete COM → Edit.

Slika 10.5: Konguracija serijske komunikacije na ra£unalu

182 Univerzalna asinkrona serijska komunikacija

Postavke mikroupravlja£a u sljede¢im vjeºbama bit ¢e sljede¢e:

• brzina prijenosa podataka: prema potrebi,

• broj podatkovnih bitova: 8,

• paritetni bit: onemogu¢en,

• Stop bit: 1.

U prozoru sa slike 10.5 bit ¢e potrebno mijenjati samo brzinu prijenosa podataka i COM Portkoji se koristi za serijsku komunikaciju. Dostupni COM portovi prikazuju se u podnoºju aplikacijena slici 10.4. Nakon ²to se kongurira serijska komunikacija na ra£unalu, potrebno je otvoritiserijski port za komunikaciju klikom mi²a na tipku Start COM. Ako je serijski port uspje²nootvoren, aplikacija je spremna za komunikaciju s vanjskim ureajem.

U inºenjerskoj praksi £esto se koriste terminali za testiranje serijske komunikacije. Jedantakav terminal jest Tera Term koji moºete preuzeti sa stranice https://ttssh2.osdn.jp/. Pripokretanju aplikacije Tera Term pojavit ¢e se prozor sa slike 10.6. Kao vrstu nove komunikacijepotrebno je odabrati serijsku komunikaciju (Serial). Za serijsku komunikaciju padaju¢i izbornikprikazuje sve dostupne COM portove na ra£unalu. Odaberite onaj port koji u svom opisu imaoznaku prilagodnog meusklopa CP2102. Nakon ²to je pokrenuta nova komunikacija (otvorenje COM port), potrebno je namjestiti postavke terminala tako da budu jednake postavkamana slici 10.7. Prozor sa slike 10.7 otvara se tako da u izborniku Setup odaberete podizbornikTerminal....

Slika 10.6: Pokretanje aplikacije (terminala) Tera Term

Slika 10.7: Pode²avanje terminala Tera Term

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 183

Kako smo ve¢ spomenuli, postavke serijske komunikacije moraju biti jednake na ureajimakoji meusobno komuniciraju. Pode²avanje postavki serijskog porta COM3 u terminalu TeraTerm prikazano je na slici 10.9.

Slika 10.8: Pode²avanje postavki serijskog porta COM3 u terminalu Tera Term

Prozor sa slike 10.8 otvara se tako da u izborniku Setup odaberete podizbornik Serialport.... Kona£no, pra¢enje komunikacije u terminalu Tera Term prikazano je na slici 10.9.Kori²tenje terminala vrlo je korisno u razvoju programskih rje²enja mikroupravlja£a zasnovanihna serijskoj komunikaciji zbog brºeg i jednostavnijeg testiranja.

Slika 10.9: Pra¢enje komunikacije u terminalu Tera Term

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku UART.zip. Na radnojpovr²ini stvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢i pritomdijakriti£ke znakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢ete stvoriti zvat ¢ese Ivica Ivic. Datoteku UART.zip raspakirajte u novostvorenu datoteku na radnoj povr²ini.Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini te dvostrukim klikom pokrenite VUB

184 Univerzalna asinkrona serijska komunikacija

mikroracunala.atsln u datoteci \\UART\vjezbe. U otvorenom projektu nalaze se sve vjeºbekoje ¢emo obraditi u poglavlju Univerzalna asinkrona serijska komunikacija. Vjeºbe ¢emopisati u datoteke s ekstenzijom *.cpp.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koja moºete koristiti za provjeru ispravnostiprogramskih zadataka.

Vjeºba 10.1.1

Napravite program kojim ¢ete slati i primati proizvoljne tekstualne poruke UART komunikacijommikroupravlja£a. U programu mikroupravlja£a denirajte dvije proizvoljne tekstualne porukekoje ¢ete slati pritiskom na tipkala spojena na pinove PD0 i PD1. Na ra£unalu je za slanje iprimanje tekstualnih poruka potrebno koristiti terminal Tera Term. Poslane poruke iz terminalapotrebno je prikazivati na LCD displeju. Znakovni niz koji ²aljemo na serijski port putemterminala zaklju£en je Carriage Return znakom ('\r') (vidi postavke na slici 10.7) kako bi se umikroupravlja£u detektirao kraj poruke koja pristiºe serijskom komunikacijom.

U projektnom stablu otvorite datoteku vjezba1011.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1011.cpp. Po£etni sadrºaj datoteke vjezba1011.cpp prikazan je programskimkodom 10.1.

Programski kod 10.1: Po£etni sadrºaj datoteke vjezba1011.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "LCD/lcd.h"

#include "UART/uart.h"

#include "Interrupt/interrupt.h"

#include "DigitalIO/DigitalIO.h"

void inicijalizacija ()

uart_init (19200); // inicijalizacija serijske komunikacije

lcd_init (); // konfiguriranje LCD displeja

interrupt_enable (); // omogu¢i globalni prekid

int main(void)

inicijalizacija ();

// stvaranje objekata za tipkala

DigitalInput Tipkalo_D0(D0); // pin PD0

DigitalInput Tipkalo_D1(D1); // pin PD1

Tipkalo_D0.pullup_on (); // pritezni otpornik na pinu PD0

Tipkalo_D1.pullup_on (); // pritezni otpornik na pinu PD1

while (1)

// provjera primljenih poruka

if(uart_read_all () == true)

lcd_clrscr ();

lcd_home ();

lcd_print("%s", uart_buffer);

// provjera padaju¢eg brida tipkala na PDO

if(Tipkalo_D0.isFalling_edge ())

uart_print("Serijska komunikacija je uspostavljena\r");

// provjera padaju¢eg brida tipkala na PD1

if(Tipkalo_D1.isFalling_edge ())

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 185

uart_print("Baud rate je %u\r", 19200);

return 0;

Funkcije koje se koriste za asinkronu serijsku komunikaciju denirane su u zaglavljuuart.h. Naredba kojom uklju£ujemo zaglavlje uart.h u datoteku koja se prevodi jest#include "UART/uart.h".

U programskom kodu 10.1 u funkciji inicijalizacija() nalazi se funkcijauart_init(uint32_t baud_rate) za konguriranje asinkrone serijske komunikacijemikroupravlja£a. Ova funkcija kao argument prima brzinu prijenosa podataka. Osimbrzine prijenosa podataka, funkcija uart_init(uint32_t ) postavlja sljede¢e parametre:

• broj podatkovnih bitova: 8,

• paritetni bit: onemogu¢en,

• Stop bit: 1,

• prekid za pristigle poruke: omogu¢en,

• pinovi RXD1 i TXD1: omogu¢eni.

Brzina prijenosa podataka u programskom kodu 10.1 postavljena je na 19200 b/s. Poruke¢emo na mikroupravlja£ slati iz terminala Tera Term, a ²alju se znak po znak. Na kraju porukepostavlja se zaklju£ni znak koji ozna£ava kraj pristigle poruke. Registar UDR1 ²irine je 8 bitovai u njega stane samo jedan znak (podatak od 8 bitova). Postavlja se pitanje kako primiti cijelutekstualnu poruku koja moºe biti proizvoljno duga£ka. U zaglavlju uart.h deklariran je nizznakova uart_buffer koji predstavlja meuspremnik znakova (engl. buer) koji se puni pomo¢uregistra UDR1. Parametri za meuspremnik znakova uart_buffer i deklaracija niza znakovauart_buffer prikazani su u programskom kodu 10.2.

Programski kod 10.2: Parametri za meuspremnik znakova uart_buffer

#define end_char '\r' // zaklju£ni znak -> znak '\r' je

// Carriage Return (CR) ASCII kod 0x0D

#define MESSAGE_LENGTH 50 // maksimalna duljina poruke

char uart_buffer[MESSAGE_LENGTH + 1]; // spremnik za dolazne poruke

Parametri u programskom kodu 10.2 redom su:

• end_char - denirana konstanta koja predstavlja zaklju£ni znak. Aplikacija sa slike 10.4te terminal Tera Term s postavkama na slici 10.7 kao zaklju£ni znak ²alje CarriageReturn znak s ASCII kodom 0x0D (specijalni znak u programskom jeziku C/C++ '\r').Zaklju£ni znak naj£e²¢e je znak koji se ne koristi u kreiranju tekstualne poruke (npr.'\r', '\n', '*', ';', ':').

• MESSAGE_LENGTH - denirana konstanta koja predstavlja maksimalnu duljinu tekstualneporuke koju ¢ete poslati na mikroupravlja£ i spremiti u meuspremnik znakovauart_buffer. Vrijednost se mijenja prema potrebi.

• uart_buffer - meuspremnik znakova koji se puni pomo¢u niza znakova koji pristiºu uregistar UDR1. Kada registar UDR1 primi zaklju£ni znak (u ovom slu£aju znak '\r' s ASCIIkodom 0x0D), meuspremnik znakova zaklju£uje se tzv. null znakom3.

3U programskom jeziku C/C++ niz znakova mora se zaklju£iti se null znakom kako bi prevoditelj znao gdjeje kraj znakovnog niza.

186 Univerzalna asinkrona serijska komunikacija

Ako serijskim portom pristiºe niz znakova "A;123;435*\rB41*\r", on ¢e predstavljati dvijeporuke. Prva poruka koja ¢e biti zapisana u uart_buffer jest "A;123;435*", a druga je "B41*".Primijetite kako zaklju£ni znak '\r' nije dio poruke koja se koristi u mikroupravlja£u.

Prekidna rutina koja se poziva kada novi znak preko pina RXD1 dolazi na mikroupravlja£ zovese USART1_RX_vect. Meuspremnik znakova uvijek £uva zadnju pristiglu poruku. Kada u registarUDR1 doe znak koji predstavlja po£etak nove poruke, on se u prekidnoj rutini USART1_RX_vectsprema na memorijsku lokaciju uart_buffer[0]. Sljede¢i se znak sprema na memorijsku lokacijuuart_buffer[1] i tako redom dok ne doe zaklju£ni znak. Prekidna rutina USART1_RX_vectnapisana je u datoteci uart.h i preporu£uje se njezino kori²tenje bez izmjene programskog kodaprekidne rutine. Programer mikroupravlja£a mijenja samo parametre prikazane programskimkodom 10.2.

U programskom kodu 10.1 u funkciji inicijalizacija() konguriran je LCD displej iglobalno su omogu¢eni prekidi funkcijom interrupt_enable(). U main() funkciji stvorenasu dva objekta koja predstavljaju tipkala spojena na pinove PD0 i PD1.

U while petlji koristi se funkcija uart_read_all(). Ova funkcija vra¢a vrijednost trueako je dostupna nova poruka u meuspremniku znakova uart_buffer, a ina£e vra¢a vrijednostfalse. Funkcija uart_read_all() detektira novu poruku kada je pristigao zaklju£ni znakdeniran konstantom end_char (u na²em slu£aju to je specijalni znak '\r'). Kada funkcijauart_read_all() vrati vrijednost true, pristigla poruka u meuspremniku uart_buffer ispisujese na LCD displej. Jasno je da poruke duºe od 16 znakova ne¢e biti potpuno prikazane na LCDdispleju.

Na padaju¢i brid signala tipkala spojenih na pinove PD0 i PD1 mikroupravlja£ na serijskiport (odnosno na pin TXD1) ²alje tekstualne poruke pomo¢u funkcije uart_print. Argumentifunkcije uart_print jednaki su argumentima funkcije printf (takoer i argumentima funkcijelcd_print). Dakle, funkcija uart_print koristi se na jednak na£in kao i funkcije printfi lcd_print. Ako pritisnemo tipkalo spojeno na pin PD0, tada ¢e se izvr²iti naredbauart_print("Serijska komunikacija je uspostavljena\r"). Ako pritisnemo tipkalospojeno na pin PD1, tada ¢e se izvr²iti naredba uart_print("Baud rate je %u\r", 19200), aporuka koju ¢e mikroupravlja£ poslati UART komunikacijom bit ¢e "Baud rate je 19200\r".U ovom slu£aju specijalni znak '\r' sluºi da prijemna strana (terminal ili aplikacija) zna da jestigao kraj poruke.

Prevedite datoteku vjezba1011.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4pomo¢u terminala Tera Term. Namjestite parametre terminala i serijske komunikacije za COMport pomo¢u prozora sa slika 10.7 i 10.8. Na slici 10.10 prikazan je rezultat serijske komunikacije,pri £emu je redom:

• jednom pritisnuto tipkalo spojeno na pin PD0,

• jednom pritisnuto tipkalo spojeno na pin PD1,

• jednom pritisnuto tipkalo spojeno na pin PD0,

• tri puta pritisnuto tipkalo spojeno na pin PD1,

• dva puta pritisnuto tipkalo spojeno na pin PD0,

• pomo¢u terminala na mikroupravlja£ poslana poruka "COM3" i pritisnut Enter (terminal²alje poruku "COM3\r"),

• pomo¢u terminala na mikroupravlja£ poslana poruka "VUB" i pritisnut Enter (terminal²alje poruku "VUB\r").

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 187

Slika 10.10: Pra¢enje komunikacije u terminalu Tera Term za programski kod 10.1

Poruke "COM3" i "VUB" prikazuju se na LCD displeju kako je prikazano na slici 10.11.

(a) Prva poruka ("COM3") (b) Druga poruka ("VUB")

Slika 10.11: Prikaz pristiglih poruka iz terminala Tera Term

Dio programskog koda kojim ¢ete uvijek provjeravati nalazi li se u meuspremniku znakovauart_buffer nova poruka prikazan je programskim kodom 10.3. Ovaj dio koda uvijek mora bitiu while petlji kako bi se neprestano provjeravalo je li dostupna nova poruka.

Programski kod 10.3: Izvoenje programskog koda na temelju pristigle poruke putem asinkroneserijske komunikacije

if(uart_read_all () == true)

// izvoenje programskog koda na temelju pristigle poruke

Pomo¢u asinkrone komunikacije poruke mogu razmjenjivati svi ureaji koji podrºavajusklopovlje UART. Na primjer, mikroupravlja£ moºe komunicirati s ra£unalom, s GSM modemom,s drugim mikroupravlja£em, s GPS modulom i drugim ureajima koji podrºavaju sklopovljeUART.

Poku²ajte kreirati druge proizvoljne poruke koje ²aljete pomo¢u mikroupravlja£a. Preveditedatoteku vjezba1011.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4. Testirajteprogram na razvojnom okruºenju s mikroupravlja£em ATmega32U4 pomo¢u terminala TeraTerm.

Zatvorite datoteku vjezba1011.cpp i onemogu¢ite prevoenje ove datoteke.

188 Univerzalna asinkrona serijska komunikacija

Vjeºba 10.1.2

Napravite program kojim ¢e se pomo¢u tipkala PD0, PD1, PF6 i PF7 u aplikaciji na slici 10.4uklju£ivati redom crvena LED dioda, ºuta LED dioda, zelena LED dioda i plava LED dioda narazvojnom okruºenju. Klikom mi²a na tipkalo u aplikaciji, putem serijske komunikacije, ²alje seniz znakova u obliku "Bxy\r" (korisni dio poruke jest "Bxy"), gdje je:

• 'B' - niz znakova koji ozna£uje port B,

• 'x' - znak koji odreuje poziciju pina na portu B ('x'= '4', '5', '6', '7'),

• 'y' - znak koji odreuje digitalno stanje pina ('y'= '0', '1' ),

• '\r' - specijalan znak (Carriage Return) koji denira kraj poruke i nije dio korisne poruke.

Na primjer, ako je pristigla poruka "B41\r" (korisni dio poruke jest "B41"), crvenu LEDdiodu treba uklju£iti, a ako je pristigla poruka "B40\r" (korisni dio poruke jest "B40"), crvenuLED diodu treba isklju£iti. Brzinu prijenosa podataka postavite na 19200 b/s. Poslane porukeiz aplikacije potrebno je prikazivati na LCD displeju.

U projektnom stablu otvorite datoteku vjezba1012.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1012.cpp. Po£etni sadrºaj datoteke vjezba1012.cpp prikazan je programskimkodom 10.4.

Programski kod 10.4: Po£etni sadrºaj datoteke vjezba1012.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "LCD/lcd.h"

#include "UART/uart.h"

#include "Interrupt/interrupt.h"

#include "DigitalIO/DigitalIO.h"

void inicijalizacija ()

uart_init (19200); // inicijalizacija serijske komunikacije

lcd_init (); // konfiguriranje LCD displeja

interrupt_enable (); // omogu¢i globalni prekid

int main(void)

inicijalizacija ();

// stvaranje objekata za LED diode

DigitalOutput LED_crvena(B4); // pin PB4 - crvena dioda

DigitalOutput LED_zuta(B5); // pin PB5 - ºuta dioda

DigitalOutput LED_zelena(B6); // pin PB6 - zelena dioda

DigitalOutput LED_plava(B7); // pin PB7 - plava dioda

char B, x, y;

while (1)

// provjera primljenih poruka

if(uart_read_all () == true)

lcd_clrscr ();

lcd_home ();

lcd_print("%s", uart_buffer);

B = uart_buffer [0];

x = uart_buffer [1];

y = uart_buffer [2];

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 189

// provjera prvog znaka

if (B == 'B')

// automat stanja koji obrauje ostatak poruke tipa "xy"

switch(x)

case '4':

if (y == '1') LED_crvena.on();

if (y == '0') LED_crvena.off();

break;

case '5':

if (y == '1') LED_zuta.on();

if (y == '0') LED_zuta.off();

break;

case '6':

if (y == '1') LED_zelena.on();

if (y == '0') LED_zelena.off();

break;

case '7':

if (y == '1') LED_plava.on();

if (y == '0') LED_plava.off();

break;

default:

break;

return 0;

Cilj vjeºbe jest uklju£iti digitalni izlaz temeljem pristigle poruke putem serijske komunikacije.Brzina prijenosa podataka u programskom kodu 10.4 postavljena je na 19200 b/s. Konguriranje LCD displej i globalno su omogu¢eni prekidi funkcijom interrupt_enable(). Aplikacija ¢eserijskom komunikacijom slati tekstualne poruke oblika "Bxy\r". Ova poruka ²alje se na na£inda se svaki znak ²alje zasebno i dodatno se na kraju poruke postavlja zaklju£ni znak "\r" kojiozna£ava kraj pristigle poruke.

U programskom kodu 10.4 u main() funkciji stvoreni su objekti tipa DigitalOutput koji supovezani s pinovima PB4, PB5, PB6 i PB7 na kojima su spojene redom crvena, ºuta, zelena iplava LED dioda.

U while petlji koristi se funkcija uart_read_all() za provjeru pristiglih poruka putemserijske komunikacije. Kada je pristigla nova poruka, ona se ispisuje na LCD displeju nana£in da ispisujemo sadrºaj meuspremnika uart_buffer. Poruka koja se iz aplikacije ²aljena mikroupravlja£ ima oblik "Bxy\r". Znak "\r" specijalni je znak koji se koristi za detekcijukraja poruke, ²to zna£i da korisni dio poruke koja se nalazi u meuspremniku uart_buffer imaoblik "Bxy". Pristiglu poruku iz meuspremnika uart_buffer raspakirali smo na pojedina£neznakove:

• B = uart_buffer[0] - znak koji denira kojem se portu pristupa (o£ekujemo znak 'B'),

• x = uart_buffer[1] - znak koji odreuje poziciju pina na portu (o£ekujemo znakove'4', '5', '6', '7'),

• y = uart_buffer[2] - znak koji odreuje digitalno stanje pina (o£ekujemo znakove'0', '1' ).

Ako se u varijabli B nalazi znak 'B', tada se izvodi takozvani automat stanja (standardniswitch case) koji provjerava varijablu x na sljede¢i na£in:

• ako je varijabla x jednaka znaku '4', tada ¢e se:

190 Univerzalna asinkrona serijska komunikacija

ako je varijabla y jednaka znaku '1', uklju£iti crvena LED dioda,

ako je varijabla y jednaka znaku '0', isklju£iti crvena LED dioda.

• ako je varijabla x jednaka znaku '5', tada ¢e se:

ako je varijabla y jednaka znaku '1', uklju£iti ºuta LED dioda,

ako je varijabla y jednaka znaku '0', isklju£iti ºuta LED dioda.

• ako je varijabla x jednaka znaku '6', tada ¢e se:

ako je varijabla y jednaka znaku '1', uklju£iti zelena LED dioda,

ako je varijabla y jednaka znaku '0', isklju£iti zelena LED dioda.

• ako je varijabla x jednaka znaku '7', tada ¢e se:

ako je varijabla y jednaka znaku '1', uklju£iti plava LED dioda,

ako je varijabla y jednaka znaku '0', isklju£iti plava LED dioda.

Ako se niti jedan uvjet ne zadovolji, to zna£i da je poruka koja je pristigla neispravna.Prevedite datoteku vjezba1012.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4.Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4 pomo¢u aplikacijesa slike 10.4. Namjestite parametre serijske komunikacije za onaj COM Port na kojem se nalaziCP2101 pomo¢u prozora sa slike 10.5 te otvorite serijski port klikom mi²a na tipku Start COM.

Poku²ajte pritiskati tipke PD0, PD1, PF6 i PF7 u aplikaciji sa slike 10.4 te pratite ²to sedogaa. Pristigle poruke mogu se obraditi i na na£in koji je prikazan u programskom kodu 10.5.

Programski kod 10.5: Novi sadrºaj datoteke vjezba1012.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "LCD/lcd.h"

#include "UART/uart.h"

#include "Interrupt/interrupt.h"

#include "DigitalIO/DigitalIO.h"

void inicijalizacija ()

uart_init (19200); // inicijalizacija serijske komunikacije

lcd_init (); // konfiguriranje LCD displeja

interrupt_enable (); // omoguci globalni prekid

// PB4 , PB5 , PB6 , PB7 konfigurirani kao izlazni pinovi

DDRB |= (1 << PB4) | (1 << PB5) | (1 << PB6) | (1 << PB7);

int main(void)

inicijalizacija ();

char B, x, y;

while (1)

// provjera primljenih poruka

if(uart_read_all () == true)

lcd_clrscr ();

lcd_home ();

lcd_print("%s", uart_buffer);

B = uart_buffer [0];

x = uart_buffer [1];

y = uart_buffer [2];

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 191

if (B == 'B' && (x >= '4' && x <= '7'))

if(y == '0' || y == '1')

set_port(PORTB , x - 48, y - 48);

return 0;

U programskom kodu 10.5 ne koristimo objekte za digitalne izlaze, ve¢ ih konguriramodirektno pomo¢u registra DDRB. Automat stanja iz programskog koda 10.4 zamijenjen je dvamauvjetovano izvoenim blokovima. Prvi uvjetovani blok ispituje je li znak u varijabli B jednakznaku 'B' i je li znak u varijabli x ve¢i od znaka '4', a manji od znaka '7'. S obzirom nato da su znakovi kodirani prema ASCII tablici, ovi znakovi mogu se usporeivati operatorimausporedbe. Drugi uvjetovani blok ispituje je li znak u varijabli y jednak '0' ili jednak '1'. Kadasu oba uvjeta zadovoljena, sigurni smo da je pristigla ispravna poruka.

U varijablama x i y nalaze znakovi s ASCII kodom brojeva 0 - 9. ASCII kod znaka '0' je 48 teje od varijable x potrebno oduzeti broj 48 kako bismo dobili poziciju pina kojem ºelimo promijenitistanje. Isto vrijedi i za varijablu y. Ovo je standardna pretvorba znakova dekadskog sustava ubrojeve dekadskog sustava. Prema navedenom, naredbom set_port(PORTB, x - 48, y - 48)mijenjamo stanje na pinu PBx.

Poruku oblika "Bxy\r" moºete poslati pomo¢u tekstualnog okvira za slanje poruka. Naprimjer, upi²ite u tekstualni okvir Message poruka "B41" te pritisnite tipku Send. Kada sepritisne tipka Send, poruci "B41" na kraj ¢e se dodati specijalni znak "\r". Pomo¢u tekstualnogokvira po²aljite proizvoljnu poruku. Ako poruka nije oblika "Bxy\r", ona ¢e se ispisati na LCDdispleju, dok se stanja LED dioda ne¢e mijenjati.

Promijenite u programskom kodu 10.5 brzinu prijenosa podataka s 19200 b/s na 57600 b/s.Prevedite datoteku vjezba1012.cpp u strojni kod i snimite ga na mikroupravlja£ ATmega32U4.Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4 pomo¢u aplikacijesa slike 10.4 bez mijenjanja postavki COM porta u aplikaciji.

Primijetit ¢ete da razli£ito pode²ene brzine na dvama ureajima koji komuniciraju serijskomkomunikacijom rezultiraju pogre²no poslanim porukama. Promijenite brzinu prijenosa podatakas 19200 b/s na 57600 b/s u aplikaciji sa slike 10.4 te ponovno testirajte program.

Zatvorite datoteku vjezba1012.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 10.1.3

Napravite program kojim ¢e se pomo¢u tipkala PD0, PD1 i PF6 u aplikaciji sa slike 10.4uklju£ivati redom crvena LED dioda, ºuta LED dioda i zelena LED dioda na razvojnomokruºenju. Klikom mi²a na tipkalo u aplikaciji, putem serijske komunikacije, ²alje se niz znakovau obliku "Bxy\r" (korisni dio poruke jest "Bxy") po istom principu kao u pro²loj vjeºbi. PlavaLED dioda mora mijenjati intenzitet u ovisnosti o vrijednosti kliza£a Slider u aplikaciji sa slike10.4 koriste¢i Phase Correct PWM na£in rada sklopa Timer/Counter0. Pomo¢u tipkala PF7 uaplikaciji sa slike 10.4 omogu¢uje se i onemogu¢uje generiranje PWM signala na pinu PB7 (pinna kojem je spojena plava LED dioda). Na primjer, ako je pristigla poruka "B71\r" (korisnidio poruke jest "B71"), na pinu PB7 generirat ¢e se PWM signal i plava LED dioda mijenjat ¢eintenzitet sukladno vrijednosti kliza£a, a ako je pristigla poruka "B70\r" (korisni dio poruke jest"B70"), plava LED dioda bit ¢e isklju£ena te ¢e biti onemogu¢eno generiranje PWM signala napinu PB7. Promjenom pozicije kliza£a u aplikaciji sa slike 10.4 serijskom komunikacijom ²aljese poruka oblika "S%u*\r". Na primjer, ako je pozicija kliza£a 125, tada ¢e poslana poruka biti"S125*\r" (korisni dio poruke jest "S125*"). Brzinu prijenosa podataka postavite na 38400 b/s.

192 Univerzalna asinkrona serijska komunikacija

Sve poruke zaklju£ane su specijalnim znakom '\r' (Carriage Return) koji denira kraj porukei nije dio korisne poruke. Poruke poslane iz aplikacije potrebno je prikazivati na LCD displeju.

U projektnom stablu otvorite datoteku vjezba1013.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1013.cpp. Po£etni sadrºaj datoteke vjezba1013.cpp prikazan je programskimkodom 10.6.

Programski kod 10.6: Po£etni sadrºaj datoteke vjezba1013.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "LCD/lcd.h"

#include "UART/uart.h"

#include "Interrupt/interrupt.h"

#include "DigitalIO/DigitalIO.h"

#include "Timer/timer.h"

void inicijalizacija ()

// inicijalizacija serijske komunikacije

lcd_init (); // konfiguriranje LCD displeja

interrupt_enable (); // omogu¢i globalni prekid

timer0_set_phase_correct_PWM ();

timer0_set_prescaler(TIMER0_PRESCALER_8);

timer0_OC0A_enable_non_inverted_PWM ();

int main(void)

inicijalizacija ();

// stvaranje objekata za LED diode

DigitalOutput LED_crvena(B4); // pin PB4 - crvena dioda

DigitalOutput LED_zuta(B5); // pin PB5 - ºuta dioda

DigitalOutput LED_zelena(B6); // pin PB6 - zelena dioda

DigitalOutput LED_plava(B7); // pin PB7 - plava dioda

char key_char , x, y;

uint8_t slider;

while (1)

// provjera primljenih poruka

if(uart_read_all () == true)

lcd_clrscr ();

lcd_home ();

lcd_print("%s", uart_buffer);

key_char = uart_buffer [0];

// provjera prvog znaka

if (key_char == 'B')

x = uart_buffer [1];

y = uart_buffer [2];

// automat stanja koji obrauje ostatak poruke tipa "xy"

switch(x)

case '4':

if (y == '1') LED_crvena.on();

if (y == '0') LED_crvena.off();

break;

case '5':

if (y == '1') LED_zuta.on();

if (y == '0') LED_zuta.off();

break;

case '6':

if (y == '1') LED_zelena.on();

if (y == '0') LED_zelena.off();

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 193

break;

case '7':

if (y == '1') LED_plava.enable ();

if (y == '0') LED_plava.disable ();

break;

default:

break;

if (key_char == 'S')

for(uint8_t i = 1; uart_buffer[i] != '*'; i++)

slider = slider * 10 + (uart_buffer[i] - 48);

OC0A_set_duty_cycle(slider /2.55);

slider = 0;

return 0;

U ovoj vjeºbi potrebno je napraviti program koji ¢e imati funkcionalnost programa izprethodne vjeºbe, izuzev upravljanja intenzitetom plave LED diode. U programskom kodu10.6 u funkciji inicijalizacija() napravite konguraciju asinkrone serijske komunikacije sbrzinom prijenosa od 38400 b/s. S obzirom na to da ¢e se mijenjati intenzitet plave LEDdiode koja je spojena na pin PB7, koristit ¢emo sklop Timer/Counter0 u Phase Correct na£inurada. Ovaj na£in rada konguriran je u funkciji inicijalizacija(). U beskona£noj whilepetlji ponovno se nalazi automat stanja koji £eka primljene poruke iz aplikacije sa slike 10.4.Razlika u automatu stanja koji se brine o uklju£enju LED dioda u programskom kodu 10.4i programskom kodu 10.6 jest u slu£aju kada je drugi pristigli znak u poruci oblika "Bxy\r"jednak '7'. U tom slu£aju omogu¢ujemo, odnosno onemogu¢ujemo objekt LED_plava koji jepovezan s izlaznim pinom PB7. Na taj na£in generiramo, odnosno ne generiramo PWM signal napinu PB7. Omogu¢avanje, odnosno onemogu¢avanje PWM signala moºe se provesti i funkcijamatimer0_OC0A_enable_non_inverted_PWM(), odnosno timer0_OC0A_disable().

Vrijednost kliza£a iz aplikacije ²alje se kao niz znakova oblika "S%u*\r". Da se pristiglaporuka ti£e promjene intenziteta plave LED diode pomo¢u kliza£a iz aplikacije sa slike 10.4,detektirat ¢emo tako ²to ¢e prvi znak u meuspremniku znakova usart_buffer biti jednak 'S'.Nakon znaka 'S' slijedi broj nepoznatog broja znamenaka (jedna, dvije ili tri) te znak '*' kojiu korisnom dijelu poruke denira kraj poslane vrijednosti s kliza£a.

Niz znakova koji predstavlja vrijednost kliza£a u aplikaciji kre¢e se u intervalu ["0", "255"].Taj niz znakova potrebno je pretvoriti u cijeli broj koji ¢e biti u intervalu [0, 255]. Pretvorbase provodi u for petlji izrazom slider = slider * 10 + (uart_buffer[i] - 48). Pokaºimopretvorbu niza znakova u cijeli broj na poruci "S125*"):

• key_char, odnosno usart_buffer[0] jednak je znaku 'S', stoga iza ovoga znakao£ekujemo cijeli broj nepoznatog broja znamenki.

• Varijabla slider ima po£etnu vrijednost 0. U prvoj iteraciji for petlje na pozicijiusart_buffer[1] nalazi se znak '1'. Od ovog znaka oduzima se 48 te ¢e se dobitibroj 1. Vrijednost varijable slider sada je 1. Da je sljede¢i znak u meuspremniku(usart_buffer[2]) jednak '*', pretvorba bi zavr²ila.

• U drugoj iteraciji for petlje na poziciji usart_buffer[2] nalazi se znak '2'. Od ovogznaka oduzima se 48 te ¢e se dobiti broj 2. Stara vrijednost varijable slider mnoºi se s10 i dodaje se 2 te je nova vrijednost varijable slider jednaka 12. Da je sljede¢i znak umeuspremniku (usart_buffer[3]) jednak '*', pretvorba bi zavr²ila.

194 Univerzalna asinkrona serijska komunikacija

• U tre¢oj iteraciji for petlje na poziciji usart_buffer[3] nalazi se znak '5'. Od ovogznaka oduzima se 48 te ¢e se dobiti broj 5. Stara vrijednost varijable slider mnoºi se s10 i dodaje se 5 te je nova vrijednost varijable slider jednaka 125. S obzirom na to da jesljede¢i znak u meuspremniku (usart_buffer[4]) jednak '*', pretvorba zavr²ava.

• Vrijednost varijable slider skalira se na interval [0.0, 100.0] te se skalirana vrijednostprosljeuje u funkciju OC0A_set_duty_cycle(slider/2.55) koja mijenja ²irinu impulsaPWM signala, odnosno mijenja intenzitet plave LED diode.

• Nakon postavljanja nove ²irine impulsa, varijabla slider postavlja se na vrijednost 0 kakobi bila spremna za novi izra£un vrijednosti kliza£a iz aplikacije sa slike 10.4.

Prevedite datoteku vjezba1013.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4pomo¢u tipki i kliza£a u aplikaciji sa slike 10.4. Namjestite parametre serijske komunikacije zadostupan COM Port na kojem se nalazi CP2102 pomo¢u prozora sa slike 10.5 te otvorite serijskiport klikom mi²a na tipku Start COM. Mijenjajte intenzitet plave LED diode pomo¢u kliza£a uaplikaciji sa slike 10.4.

Zatvorite datoteku vjezba1013.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 10.1.4

Napravite program kojim ¢ete osigurati sljede¢e funkcionalnosti:

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'P', mikroupravlja£aplikaciji mora poslati poruku "ATmega32U4",

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'C', mikroupravlja£aplikaciji mora poslati informaciju o stanju crvene LED diode spojene na pin PB4,

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'D', mikroupravlja£aplikaciji mora poslati informaciju o stanju tipkala spojenog na pin PD0,

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'A', mikroupravlja£aplikaciji mora poslati rezultat analogno-digitalne pretvorbe na pinu ADC5,

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'N', mikroupravlja£aplikaciji mora poslati napon potenciometra (na tri decimalna mjesta) koji je spojen napin ADC5,

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'T', mikroupravlja£aplikaciji mora poslati temperaturu koju mjeri NTC otpornik (na tri decimalna mjesta)koji je spojen na pin ADC4,

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'V', mikroupravlja£aplikaciji mora poslati vrijeme u sekundama od uklju£enja mikroupravlja£a,

• za sve druge znakove poslane pomo¢u aplikacije sa slike 10.4 na mikroupravlja£,mikroupravlja£ aplikaciji mora poslati "Neispravan unos!".

Crvena LED dioda mora mijenjati stanje svakih 1000 ms pomo¢u sklopa Timer/Counter1u normalnom na£inu rada. Brzinu prijenosa podataka postavite na 38400 b/s. Sve porukeaplikacije i mikroupravlja£a zaklju£ane su specijalnim znakom '\r' (Carriage Return) kojidenira kraj poruke i nije dio korisne poruke. Poruke poslane iz aplikacije potrebno je prikazivati

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 195

na LCD displeju.

U projektnom stablu otvorite datoteku vjezba1014.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1014.cpp. Po£etni sadrºaj datoteke vjezba1014.cpp prikazan je programskimkodom 10.7.

Programski kod 10.7: Po£etni sadrºaj datoteke vjezba1014.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

// uklju£ite potrebna zaglavlja

uint32_t vrijeme = 0;

DigitalOutput LED_crvena(B4); // pin PB4 - crvena dioda

ISR(TIMER1_OVF_vect)

TCNT1 = 0;

vrijeme ++; // mjerenje vremena rada uC-a

LED_crvena.toggle (); // promjena stanja crvene diode

void inicijalizacija ()

// inicijalizacija serijske komunikacije

// konfiguriranje LCD displeja

// konfiguriranje AD pretvorbe

// omogu¢i globalni prekid

// konfiguriranje tajmera 1

timer1_set_normal_mode ();

timer1_set_prescaler(TIMER1_PRESCALER_1024);

timer1_interrupt_OVF_enable ();

TCNT1 = 0;

int main(void)

inicijalizacija ();

DigitalInput Tipkalo_D0(D0); // pin PD0 - tipkalo

Tipkalo_D0.pullup_on (); // uklju£i pull up na PD0

uint16_t ADC_4 , ADC_5; // vrijednost AD pretvorbe na pinu ADC4 i ADC5

float T, U_ADC5; // temperatura i napon

while (1)

// provjera primljenih poruka

if(uart_read_all () == true)

lcd_clrscr ();

lcd_home ();

lcd_print("%s", uart_buffer);

// provjera da li je drugi znak '\0' - kraj stringa

if (uart_buffer [1] == '\0')

// automat stanja koji obrauje prvi znak poruke

switch(uart_buffer [0])

case 'P':

uart_print("ATmega32U4\r");

break;

case 'C':

// po²alji stanje crvene LED diode

break;

case 'D':

// po²alji stanje tipkala na PD0

break;

case 'A':

196 Univerzalna asinkrona serijska komunikacija

// napravite AD pretvorbu na ADC5

// po²aljite ADC5

break;

case 'N':

// napravite AD pretvorbu na ADC5

// izra£unajte i po²aljite napon U_ADC5

break;

case 'T':

// napravite AD pretvorbu na ADC4

// izra£unajte i po²aljite temperaturu

break;

case 'V':

// po²aljite vrijeme rada mikroupravlja£a

break;

default:

uart_print("Neispravan unos!\r");

break;

return 0;

esto je u praksi potrebno prezentirati neku varijablu sustava na zahtjev aplikacije. U ovojvjeºbi zahtjevi su znakovi koje ²aljemo na mikroupravlja£ koji povratno ²alje informacije izokoline sustava u kojoj se mikroupravlja£ nalazi.

U programskom kodu 10.7 potrebno je uklju£iti sva zaglavlja koja se koriste u vjeºbi("LCD/lcd.h", "UART/uart.h", "Interrupt/interrupt.h", "DigitalIO/DigitalIO.h","Timer/timer.h", "ADC/adc.h"). U funkciji inicijalizacija() kongurirajte UARTkomunikaciju s brzinom prijenosa 19200 b/s, LCD displej, analogno-digitalnu pretvorbu,omogu¢ite globalne prekide te kongurirajte sklop Timer/Counter1 u normalnom na£inu radapri kojem se prekidna rutina poziva svakih 1000 ms (jednu sekundu).

Prema funkcijama za inicijalizaciju sklopa Timer/Counter1 koje su pozvane u funkcijiinicijalizacija(), sklop Timer/Counter1 konguriran je kao tajmer u normalnom na£inurada s djeliteljem frekvencije radnog takta 1024 te je omogu¢en prekid sklopa Timer/Counter1.Vrijeme izmeu dvaju poziva prekidne rutine mora biti 1000 ms (tT1 = 1 s). Po£etnu vrijednostregistra TCNT1 izra£unat ¢emo pomo¢u korigirane relacije (8.2):

TCNT10 = 65536− tT1 ·F_CPU

PRESCALER= 65536− 1 · 16000000

1024= 49911. (10.3)

Po£etnu vrijednost iznosa 49911 potrebno je dodijeliti registru TCNT1 u funkcijiinicijalizacija() i u prekidnoj rutini sklopa Timer/Counter1. U main() funkciji prikazanoj uprogramskom kodu 10.7 nakon poziva funkcije inicijalizacija(), stvoren je objekt za tipkalospojeno na pin PD0 i deklarirane su varijable koje ¢e se koristiti u nastavku.

U beskona£noj while petlji provjera primljenih poruka provodi se pozivom funkcijeuart_read_all(). Ako je poruka pristigla, tada se ona najprije ispisuje na LCD displej. Nakontoga slijedi provjera je li na poziciji uart_buffer[1] znak '\0', s obzirom na to da su sviupiti koji dolaze iz aplikacije sa slike 10.4 u obliku jednog slova. Ako je u meuspremnikuart_buffer stigao samo jedan znak, on se obrauje automatom stanja (switch case blok). Uovisnosti o tome koji smo znak poslali na mikroupravlja£, on mora nazad poslati poruku sukladnospecikacijama vjeºbe. Na primjer, ako na mikroupravlja£ stigne znak 'P', mikroupravlja£ ¢eposlati poruku "ATmega32U4\r" pomo¢u funkcije uart_print("ATmega32U4\r");. Primijetiteda je poruka zaklju£ana znakom '\r', ²to je bitno za svaku poslanu poruku jer aplikacija sa slike10.4 o£ekuje poruku zaklju£anu znakom '\r'.

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 197

Zamijenite komentare u switch case bloku odgovaraju¢im pozivima funkcija, odnosnonaredbama:

• za case 'C': dodajte sljede¢i poziv funkcije:

uart_print("Stanje crvene diode je %d.\r", LED_crvena.state());

• za case 'D': dodajte sljede¢i poziv funkcije:

uart_print("Stanje tipkala D0 je %d.\r", Tipkalo_D0.state());

• za case 'A': dodajte sljede¢e dvije naredbe:

ADC_5 = adc_read(ADC5);

uart_print("ADC5 = %u.\r", ADC_5);

• za case 'N': dodajte sljede¢e tri naredbe:

ADC_5 = adc_read(ADC5);

U_ADC5 = ADC_5/1023.0*5.0;

uart_print("Napon na pinu ADC5 je %.3f V.\r", U_ADC5);

• za case 'T': dodajte sljede¢e tri naredbe:

ADC_4 = adc_read(ADC4);

T = 3435 / (log(ADC_4 / (1023.0 - ADC_4))+ 10.861)- 273.15;

uart_print("Temperatura je %.3f C.\r", T);

• za case 'V': dodajte sljede¢i poziv funkcije:

uart_print("Vrijeme rada uC je %lu s.\r", vrijeme);

Ukoliko po²aljete krivi znak pomo¢u aplikacije na mikroupravlja£, on ¢e vratiti poruku"Neispravan unos!". Varijabla vrijeme uve¢ava se za jedan u prekidnoj rutini sklopaTimer/Counter1 svaku sekundu. Na taj se na£in mjeri vrijeme rada mikroupravlja£a usekundama. U prekidnoj se rutini isto tako mijenja stanje crvene LED diode.

Prevedite datoteku vjezba1014.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4pomo¢u aplikacije sa slike 10.4. Namjestite parametre serijske komunikacije za COM Port nakojem se nalazi CP2102 pomo¢u prozora sa slike 10.5 te otvorite serijski port klikom mi²a natipku Start COM. Pomo¢u tekstualnog okvira Message unesite ºeljene poruke te po²aljite porukuklikom mi²a na tipku Send. Poruke mikroupravlja£a moºete provjeriti u dijalogu Receive Dialog(Rx).

Zatvorite datoteku vjezba1014.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 10.1.5

Potrebno je napraviti program kojim ¢e se pro²iriti zahtjevi vjeºbe 10.1.2. sljede¢imfunkcionalnostima:

• jednom u sekundi mikroupravlja£ serijskom komunikacijom na aplikaciju sa slike 10.4²alje poruku oblika "A;%u;%u;%u*\r", gdje tri cijela broja predstavljaju rezultatanalogno-digitalne pretvorbe na ADC4 pinu skaliran na cjelobrojni interval [0, 100], rezultatanalogno-digitalne pretvorbe na ADC5 pinu skaliran na cjelobrojni interval [0, 100] i vrijemerada mikroupravlja£a u sekundama kao modul broja 101.

198 Univerzalna asinkrona serijska komunikacija

• jednom u sekundi mikroupravlja£ serijskom komunikacijom na aplikaciju sa slike 10.4 ²aljeporuku oblika "P;%u;%u;%u;%u;%u;%u*\r", gdje su prva tri cijela broja jednaka 1, 4 i 5,a druga tri cijela broja predstavljaju vrijeme rada mikroupravlja£a u sekundama, rezultatanalogno-digitalne pretvorbe na ADC4 pinu i rezultat analogno-digitalne pretvorbe naADC5 pinu.

• na padaju¢i brid tipkala spojenog na pin PD0 mijenjati stanje crvene LED diode spojenena pinu PB4 te istovremeno mijenjati stanje crvene LED diode u aplikaciji sa slike 10.4slanjem poruka oblika "B40*\r" i "B41*\r".

• na padaju¢i brid tipkala spojenog na pin PD1 mijenjati stanje ºute LED diode spojene napinu PB5 te istovremeno mijenjati stanje ºute LED diode u aplikaciji sa slike 10.4 slanjemporuka oblika "B50*\r" i "B51*\r".

• na padaju¢i brid tipkala spojenog na pin PF6 mijenjati stanje zelene LED diode spojenena pinu PB6 te istovremeno mijenjati stanje zelene LED diode u aplikaciji sa slike 10.4slanjem poruka oblika "B60*\r" i "B61*\r".

• na padaju¢i brid tipkala spojenog na pin PF7 mijenjati stanje plave LED diode spojene napinu PB7 te istovremeno mijenjati stanje plave LED diode u aplikaciji sa slike 10.4 slanjemporuka oblika "B70*\r" i "B71*\r".

Dakle, stanja zi£kih i virtualnih LED dioda mogu se mijenjati i pomo¢u zi£kih tipkala ipomo¢u virtualnih tipkala neometano. Brzinu prijenosa podataka postavite na 19200 b/s. Sveporuke aplikacije i mikroupravlja£a zaklju£ane su specijalnim znakom '\r' (Carriage Return)koji denira kraj poruke i nije dio korisne poruke. Poruke poslane iz aplikacije potrebno jeprikazivati na LCD displeju.

U projektnom stablu otvorite datoteku vjezba1015.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1015.cpp. Po£etni sadrºaj datoteke vjezba1015.cpp prikazan je programskimkodom 10.8.

Programski kod 10.8: Po£etni sadrºaj datoteke vjezba1015.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "LCD/lcd.h"

#include "UART/uart.h"

#include "Interrupt/interrupt.h"

#include "DigitalIO/DigitalIO.h"

#include "Timer/timer.h"

#include "ADC/adc.h"

bool send_uart = false;

uint8_t send_uart_state = 0;

uint32_t vrijeme_16 = 0;

ISR(TIMER1_OVF_vect)

TCNT1 = 49911;

vrijeme_16 ++; // uve¢aj svakih 1/16 s

send_uart_state ++; // korak [0,1,2,3,...]

send_uart = true; // zahtjev za obradom svakih 1/16 s

void inicijalizacija ()

uart_init (19200); // inicijalizacija serijske komunikacije

lcd_init (); // konfiguriranje LCD displeja

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 199

adc_init (); // konfiguriranje AD pretvorbe

interrupt_enable (); // omogu¢i globalni prekid

// konfiguriranje tajmera 1

timer1_set_normal_mode ();

timer1_set_prescaler(TIMER1_PRESCALER_64);

timer1_interrupt_OVF_enable ();

TCNT1 = 49911;

int main(void)

inicijalizacija ();

// stvaranje objekata za LED diode

DigitalOutput LED_crvena(B4); // pin PB4 - crvena dioda

DigitalOutput LED_zuta(B5); // pin PB5 - ºuta dioda

DigitalOutput LED_zelena(B6); // pin PB6 - zelena dioda

DigitalOutput LED_plava(B7); // pin PB7 - plava dioda

DigitalInput Tipkalo_D0(D0); // pin PD0 - tipkalo

Tipkalo_D0.pullup_on (); // uklju£i pull up na PD0

DigitalInput Tipkalo_D1(D1); // pin PD1 - tipkalo

Tipkalo_D1.pullup_on (); // uklju£i pull up na PD1

DigitalInput Tipkalo_F6(F6); // pin PF6 - tipkalo

Tipkalo_F6.pullup_on (); // uklju£i pull up na PF6

DigitalInput Tipkalo_F7(F7); // pin PF7 - tipkalo

Tipkalo_F7.pullup_on (); // uklju£i pull up na PF6

char B, x, y; // za provjeru primljenih poruka

uint16_t ADC_4 , ADC_5; // vrijednost AD pretvorbe na pinu ADC4 i ADC5

uint16_t ADC_4_s , ADC_5_s; // skalirani ADC4 i ADC5 na [0, 100]

uint16_t vrijeme = 0;

uint16_t vrijeme_m = 0;

while (1)

// provjera primljenih poruka

if(uart_read_all () == true)

lcd_clrscr ();

lcd_home ();

lcd_print("%s", uart_buffer);

B = uart_buffer [0];

x = uart_buffer [1];

y = uart_buffer [2];

// provjera prvog znaka

if (B == 'B')

// automat stanja koji obrauje ostatak poruke tipa "xy"

switch(x)

case '4':

if (y == '1') LED_crvena.on();

if (y == '0') LED_crvena.off();

break;

case '5':

if (y == '1') LED_zuta.on();

if (y == '0') LED_zuta.off();

break;

case '6':

if (y == '1') LED_zelena.on();

if (y == '0') LED_zelena.off();

break;

case '7':

if (y == '1') LED_plava.on();

if (y == '0') LED_plava.off();

break;

default:

break;

200 Univerzalna asinkrona serijska komunikacija

ADC_4 = adc_read(ADC4);

ADC_4_s = ADC_4 / 10.23; // ADC_4 skaliran na [0, 100]

ADC_5 = adc_read(ADC5);

ADC_5_s = ADC_5 / 10.23; // ADC_5 skaliran na [0, 100]

vrijeme = vrijeme_16 / 16; // vrijeme u [s]

vrijeme_m = vrijeme % 101; // vrijeme modul na [0 ,100]

// if koji se obrauje svakih 1000/16 = 62.5 ms

if (send_uart)

// t1 = 62.5 ms

if (send_uart_state == 1)

uart_print("A;%u;%u;%u*\r", ADC_4_s , ADC_5_s , vrijeme_m);

// t3 = 187.5 ms

if (send_uart_state == 3)

uart_print("P;%u;%u;%u;%u;%u;%u*\r", 1, 4, 5, vrijeme ,

ADC_4 , ADC_5);

// if koji se obrauje na svaki paran poziv prekidne rutine

// (svakih 125 ms)

if (( send_uart_state % 2) == 0)

// na padaju¢i brid tipkala PD0 (kada se tipkalo pritisne)

if (Tipkalo_D0.isFalling_edge () == true)

if (LED_crvena.state())

uart_print("B40*\r"); // po²alji niz za crvena off

LED_crvena.off();

else

uart_print("B41*\r"); // po²alji niz za crvena on

LED_crvena.on();

// nastaviti za ostala tipkala prema programskom kodu 10.9

// kada proe 16 * 1000/16 = 1000 ms, broja£

// koraka se postavlja na 0

if (send_uart_state == 16)

send_uart_state = 0;

// obraen je if koji se obrauje svakih 1000/16 = 62.5 ms

send_uart = false;

return 0;

Dio programskog koda 10.8 koji obrauje primljene poruke oblika "Bxy\r" isti je kaoprogramski kod 10.4 iz vjeºbe 10.1.2. U ovoj su vjeºbi naspram vjeºbe 10.1.2. dodanebrojne funkcionalnosti. U funkciji inicijalizacija() kongurirani su serijska komunikacija,LCD displej, analogno-digitalna pretvorba i sklop Timer/Counter1 u normalnom na£inu rada.Takoer, globalno su omogu¢eni prekidi.

U main() funkciji stvoreni su objekti koji obrauju £etiri LED diode (objekti tipaDigitalOutput) i £etiri tipkala (objekti tipa DigitalInput). Svim objektima koji obraujuulaze (tipkala) uklju£en je pritezni otpornik. Deklarirane su i brojne cjelobrojne varijable koje

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 201

¢emo opisati u nastavku.

U beskona£noj while petlji prvi dio koda obrauje primljene poruke oblika "Bxy\r", ²tosmo objasnili u vjeºbi 10.1.2. S obzirom na zahtjeve denirane ovom vjeºbom, pripremljene suvrijednosti u sljede¢im cjelobrojnim varijablama:

• ADC_4 - varijabla u kojoj se nalazi rezultat analogno-digitalne pretvorbe na pinu ADC4.Ova varijabla poprima vrijednosti u intervalu [0, 1023].

• ADC_4_s - varijabla koja skalira vrijednosti varijable ADC_4 u cjelobrojni interval [0, 100]([0, 1023] ÷ 10.23 → [0, 100]).

• ADC_5 - varijabla u kojoj se nalazi rezultat analogno-digitalne pretvorbe na pinu ADC5.Ova varijabla poprima vrijednosti u intervalu [0, 1023].

• ADC_5_s - varijabla koja skalira vrijednosti varijable ADC_5 u cjelobrojni interval [0, 100]([0, 1023] ÷ 10.23 → [0, 100]).

• vrijeme - varijabla u kojoj se nalazi vrijeme rada mikroupravlja£a u sekundama.

• vrijeme_m - varijabla u kojoj se nalazi modul varijable vrijeme sa 101, ²to varijabluvrijeme, koja moºe poprimiti vrijednosti ve¢e od 100, smje²ta u cjelobrojni interval [0,100].

Poruke oblika "A;%u;%u;%u*\r" i "P;%u;%u;%u;%u;%u;%u*\r" na mikroupravlja£ se ²aljujednom u sekundi. Svakako je vaºno da razmak izmeu slanja dviju poruka istog oblika(npr. "A;%u;%u;%u*\r") uvijek bude jedna sekunda. Istovremeno je potrebno u stvarnomvremenu obraivati padaju¢e bridove na tipkalima. Slanje poruka na mikroupravlja£ bit ¢esinkronizirano pomo¢u tajmera. Koristit ¢emo konguraciju sklopa Timer/Counte1 iz prethodnevjeºbe, ali uz 16 puta manji djelitelj frekvencije radnoga takta. Takva konguracija tajmeraprekidnu ¢e rutinu ISR(TIMER1_OVF_vect) pozvati 16 puta u jednoj sekundi. U prekidnoj rutiniISR(TIMER1_OVF_vect) trima varijablama dodjeljuju se vrijednosti:

• vrijeme_16 - varijabla koja svoju vrijednost stalno uve¢ava za jedan pri svakom pozivuprekidne rutine ISR(TIMER1_OVF_vect). Ova varijabla uve¢a se za 16 svaku sekundu,stoga se varijabla vrijeme (vrijeme u sekundama) dobije tako da se varijabla vrijeme_16podijeli sa 16.

• send_uart_state - varijabla koja prolazi kroz 16 stanja (0,1,2,...,14,15,(16) 0,1,...) u jednojsekundi.

• send_uart - varijabla koja se postavlja u vrijednost true pri svakom pozivu prekidne rutineISR(TIMER1_OVF_vect), a sluºi za indikaciju da je obraena prekidna rutina, odnosno daje promijenjeno stanje send_uart_state.

Varijable send_uart i send_uart_state koriste se u funkciji tzv. automata stanja u whilepetlji. Naime, kod svakog poziva prekidne rutine ISR(TIMER1_OVF_vect) varijabla send_uartpostavlja se u vrijednost true. Slanje poruka s mikroupravlja£a uvjetovano je upravo varijablomsend_uart, ²to se moºe vidjeti u while petlji. Kada je varijabla send_uart jednaka true, tadau ovisnosti o stanju send_uart_state mikroupravlja£ ²alje odreenu poruku. Kada se slanjeporuka obradi, varijabla send_uart poprima vrijednost false. Slanje poruka obrauje se svakih62.5 ms (1000/16 ms).

Kada je stanje send_uart_state jednako 1, tada mikroupravlja£ ²alje poruku oblika"A;%u;%u;%u*\r". Ova poruka sadrºi rezultat analogno-digitalne pretvorbe na ADC4 pinuskaliran na cjelobrojni interval [0, 100], rezultat analogno-digitalne pretvorbe na ADC5 pinu

202 Univerzalna asinkrona serijska komunikacija

skaliran na cjelobrojni interval [0, 100] i vrijeme rada mikroupravlja£a u sekundama koje jemodul broja 101 (vidjeti programski kod 10.8). Navedeni podaci prikazivat ¢e na trakama zaprikaz napretka X, Y, Z na aplikaciji sa slike 10.4. Kada je stanje send_uart_state jednako 3,tada mikroupravlja£ ²alje poruku oblika "P;%u;%u;%u;%u;%u;%u*\r". Ova poruka sadrºi prvatri cijela broja s vrijednostima 1, 4 i 5 te druga tri cijela broja koji predstavljaju vrijeme radamikroupravlja£a u sekundama, rezultat analogno-digitalne pretvorbe na ADC4 pinu i rezultatanalogno-digitalne pretvorbe na ADC5 pinu (vidjeti programski kod 10.8). Navedeni podaciprikazivat ¢e se u polju podataka Values na aplikaciji sa slike 10.4. Obje poruke neprestanose ²alju svaku sekundu jer varijabla send_uart_state svaku sekundu neprestano prolazi krozstanja 1 i 3.

Kada varijabla send_uart_state poprimi parne vrijednosti (stanje 2,4,6,...,16), tada seobrauju padaju¢i bridovi tipkala. Dakle, padaju¢i bridovi tipkala obrauju se svakih 125 ms. Uprogramski kod 10.8 potrebno je dodati programski kod 10.9 kako bi se obradila tipkala spojenana pinove PD1, PF6 i PF7. Kada varijabla send_uart_state postigne vrijednost 16, tada seona odmah postavlja u vrijednost 0, ²to omogu¢uje stalnu izmjenu 16 stanja.

Programski kod 10.9: Niz naredaba koje obrauju pritisnuta tipkala na pinovima PD1, PF6 iPF7 te serijskom komunikacijom ²alju poruke kojima se uklju£uju LED diode u aplikaciji sa

slike 10.4

// na padaju¢i brid tipkala PD1 (kada se tipkalo pritisne)

if (Tipkalo_D1.isFalling_edge () == true)

if (LED_zuta.state())

uart_print("B50*\r"); // po²alji niz za zuta off

LED_zuta.off();

else

uart_print("B51*\r"); // po²alji niz za zuta on

LED_zuta.on();

// na padaju¢i brid tipkala PF6 (kada se tipkalo pritisne)

if (Tipkalo_F6.isFalling_edge () == true)

if (LED_zelena.state())

uart_print("B60*\r"); // po²alji niz za zelena off

LED_zelena.off();

else

uart_print("B61*\r"); // po²alji niz za zelena on

LED_zelena.on();

// na padaju¢i brid tipkala PF7 (kada se tipkalo pritisne)

if (Tipkalo_F7.isFalling_edge () == true)

if (LED_plava.state())

uart_print("B70*\r"); // po²alji niz za plava off

LED_plava.off();

else

uart_print("B71*\r"); // po²alji niz za plava on

LED_plava.on();

Prevedite datoteku vjezba1015.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4pomo¢u aplikacije sa slike 10.4. Namjestite parametre serijske komunikacije za COM Port nakojem se nalazi CP2102 pomo¢u prozora sa slike 10.5 te otvorite serijski port klikom mi²a natipku Start COM. Pritisnite tipkala, promijenite zakret potenciometra, zagrijete NTC otpornik

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 203

te pratite na aplikaciji sa slike 10.4 ²to se dogaa.

Teoretski, slanje podataka s mikroupravlja£a svaku sekundu mogli smo realizirati koriste¢ifunkciju _delay_ms(). Za²to je kori²tenje funkcije _delay_ms() uvijek lo²e u programskimrje²enjima mikroupravlja£a? Nikako nije dobro zaustaviti while petlju. Ako bismo ju zaustavilina jednu sekundu, tada poruke koje mikroupravlja£ primi unutar izvoenja funkcije ka²njenjane bi bile obraene iz razloga ²to se ne¢e izvr²iti dio koda u kojem provjeravamo je li stiglanova poruka (if(uart_read_all()== true)). Nadalje, ni tipkala se ne¢e obraivati ispravno.Uvijek ¢e slanje informacije o padaju¢em bridu kasniti jednu sekundu. U inºenjerskoj praksijedini ispravan na£in jest formirati while petlju koja ne¢e imati vremenska ka²njenja uzrokovanafunkcijom _delay_ms(). U tom slu£aju vremenski uvjetovane akcije morate provesti koriste¢itajmere u normalnom na£inu rada, kako je prikazano u ovoj vjeºbi.

Zatvorite datoteku vjezba1015.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

204 Univerzalna asinkrona serijska komunikacija

10.1.1 Zadaci - univerzalna asinkrona serijska komunikacija

Zadatak 10.1.1

Napravite program kojim ¢ete slati i primati proizvoljne tekstualne poruke UART komunikacijommikroupravlja£a. U programu mikroupravlja£a denirajte dvije proizvoljne tekstualne porukekoje ¢ete slati pritiskom na tipkala spojena na pinove PF6 i PF7. Na ra£unalu je za slanje iprimanje tekstualnih poruka potrebno koristiti terminal Tera Term. Poslane poruke iz terminalapotrebno je prikazivati na LCD displeju. Znakovni niz koji ²aljemo na serijski port putemterminala zaklju£en je Carriage Return znakom (ASCII kod 0x0D) (vidi postavke na slici 10.7)kako bi se u mikroupravlja£u detektirao kraj poruke koja pristiºe serijskom komunikacijom.

Zadatak 10.1.2

Napravite program kojim ¢e se pomo¢u tipkala PD0, PD1, PF6 i PF7 u aplikaciji na slici 10.4uklju£ivati redom crvena ('R') LED dioda, ºuta ('Y') LED dioda, zelena ('G') LED dioda iplava ('B') LED dioda na razvojnom okruºenju. Klikom mi²a na tipkalo u aplikaciji, putemserijske komunikacije, ²alje se niz znakova u obliku "xy\r" (korisni dio poruke jest "xy"), gdjeje:

• 'x' - znak koji odreuje boju LED diode ('x'= 'R', 'Y', 'G', 'B'),

• 'y' - znak koji odreuje digitalno stanje LED diode ('y'= '0', '1' ),

• '\r' - specijalan znak (Carriage Return) koji denira kraj poruke i nije dio korisne poruke.

Na primjer, ako je pristigla poruka "R1\r" (korisni dio poruke jest "R1"), crvenu LED diodutreba uklju£iti, a ako je pristigla poruka "R0\r" (korisni dio poruke jest "R0"), crvenu LEDdiodu treba isklju£iti. Brzinu prijenosa podataka postavite na 38400 b/s. Poruke poslane izaplikacije potrebno je prikazivati na LCD displeju.

Zadatak 10.1.3

Napravite program kojim ¢e se pomo¢u tipkala PD0, PD1 i PF6 u aplikaciji na slici 10.4uklju£ivati redom crvena LED dioda, ºuta LED dioda i zelena LED dioda na razvojnomokruºenju. Klikom mi²a na tipkalo u aplikaciji, putem serijske komunikacije, ²alje se niz znakovau obliku "xy\r" (korisni dio poruke je "xy") po istom principu kao u pro²lom zadatku. PlavaLED dioda mora mijenjati intenzitet u ovisnosti o vrijednosti kliza£a Slider u aplikaciji sa slike10.4 koriste¢i Fast PWM na£in rada sklopa Timer/Counter0. Pomo¢u tipkala PF7 u aplikacijina slici 10.4 omogu¢uje se i onemogu¢uje generiranje PWM signala na pinu PB7 (pin na kojemje spojena plava LED dioda). Na primjer, ako je pristigla poruka "B1\r" (korisni dio porukejest "B1"), na pinu PB7 generirat ¢e se PWM signal i plava LED dioda mijenjat ¢e intenzitetsukladno vrijednosti kliza£a, a ako je pristigla poruka "B0\r" (korisni dio poruke jest "B0"),plava LED dioda bit ¢e isklju£ena te onemogu¢eno generiranje PWM signala na pinu PB7.Promjenom pozicije kliza£a u aplikaciji sa slike 10.4 serijskom komunikacijom ²alje se porukaoblika "S%u*\r". Na primjer, ako je pozicija kliza£a 125, tada ¢e poslana poruka biti "S125*\r"(korisni dio poruke jest "S125*"). Brzinu prijenosa podataka postavite na 19200 b/s. Sveporuke zaklju£ane su specijalnim znakom '\r' (Carriage Return) koji denira kraj poruke inije dio korisne poruke. Poruke poslane iz aplikacije potrebno je prikazivati na LCD displeju.

10.1 Vjeºbe - univerzalna asinkrona serijska komunikacija 205

Zadatak 10.1.4

Napravite program kojim ¢ete osigurati sljede¢e:

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'F', mikroupravlja£aplikaciji mora poslati poruku "AVR porodica mikroupravljaca",

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'Z', mikroupravlja£aplikaciji mora poslati informaciju o stanju zelene LED diode spojene na pin PB6,

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'D', mikroupravlja£aplikaciji mora poslati informaciju o stanju tipkala spojenog na pin PD1,

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'A', mikroupravlja£aplikaciji mora poslati rezultat analogno-digitalne pretvorbe na pinu ADC4,

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'N', mikroupravlja£aplikaciji mora poslati napon na tri decimalna mjesta potenciometra koji je spojen na pinADC4,

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'O', mikroupravlja£aplikaciji mora poslati otpor potenciometra na tri decimalna mjesta koji je spojen na pinADC5,

• ako pomo¢u aplikacije sa slike 10.4 na mikroupravlja£ po²aljemo znak 'M', mikroupravlja£aplikaciji mora poslati vrijeme u minutama od uklju£enja mikroupravlja£a,

• za sve druge znakove poslane pomo¢u aplikacije sa slike 10.4 na mikroupravlja£,mikroupravlja£ aplikaciji mora poslati "Neispravan unos!".

Crvena LED dioda mora mijenjati stanje svakih 500 ms pomo¢u sklopa Timer/Counter3 unormalnom na£inu rada. Brzinu prijenosa podataka postavite na 19200 b/s. Sve porukeaplikacije i mikroupravlja£a zaklju£ane su specijalnim znakom '\r' (Carriage Return) kojidenira kraj poruke i nije dio korisne poruke. Poruke poslane iz aplikacije potrebno je prikazivatina LCD displeju.

Zadatak 10.1.5

Potrebno je napraviti program kojim ¢e se pro²iriti zahtjevi zadatka 10.1.2 sljede¢imfunkcionalnostima:

• svakih 500 ms mikroupravlja£ serijskom komunikacijom na aplikaciju sa slike 10.4²alje poruku oblika "A;%u;%u;%u*\r", gdje tri cijela broja predstavljaju rezultatanalogno-digitalne pretvorbe na ADC5 pinu skaliran na cjelobrojni interval [0, 100], rezultatanalogno-digitalne pretvorbe na ADC4 pinu skaliran na cjelobrojni interval [0, 100] i srednjuvrijednost skaliranih rezultata analogno-digitalne pretvorbe na pinovima ADC4 i ADC5.

• svakih 500 ms mikroupravlja£ serijskom komunikacijom na aplikaciju sa slike 10.4 ²aljeporuku oblika "P;%u;%u;%u;%u;%u;%u*\r", gdje su prva tri cijela broja jednaka 0, 5 i 4,a druga tri cijela broja predstavljaju vrijeme rada mikroupravlja£a u minutama, rezultatanalogno-digitalne pretvorbe na ADC5 pinu i rezultat analogno-digitalne pretvorbe naADC4 pinu.

206 Univerzalna asinkrona serijska komunikacija

• na rastu¢i brid tipkala spojenog na pin PD0 mijenjati stanje crvene LED diode spojenena pinu PB4 te istovremeno mijenjati stanje crvene LED diode u aplikaciji sa slike 10.4slanjem poruka oblika "B40*\r" i "B41*\r".

• na rastu¢i brid tipkala spojenog na pin PD1 mijenjati stanje ºute LED diode spojene napinu PB5 te istovremeno mijenjati stanje ºute LED diode u aplikaciji sa slike 10.4 slanjemporuka oblika "B50*\r" i "B51*\r".

• na rastu¢i brid tipkala spojenog na pin PF6 mijenjati stanje zelene LED diode spojenena pinu PB6 te istovremeno mijenjati stanje zelene LED diode u aplikaciji sa slike 10.4slanjem poruka oblika "B60*\r" i "B61*\r".

• na rastu¢i brid tipkala spojenog na pin PF7 mijenjati stanje plave LED diode spojene napinu PB7 te istovremeno mijenjati stanje plave LED diode u aplikaciji sa slike 10.4 slanjemporuka oblika "B70*\r" i "B71*\r".

Dakle, stanja zi£kih i virtualnih LED dioda mogu se mijenjati i pomo¢u zi£kih tipkala ipomo¢u virtualnih tipkala neometano. Brzinu prijenosa podataka postavite na 38400 b/s. Sveporuke aplikacije i mikroupravlja£a zaklju£ane su specijalnim znakom '\r' (Carriage Return)koji denira kraj poruke i nije dio korisne poruke. Poruke poslane iz aplikacije potrebno jeprikazivati na LCD displeju.

Poglavlje 11

Vanjski prekidi

Vanjski prekidi (engl. External Interrupts) jesu prekidi koji su izazvani vanjskim dogaajima.Vanjske dogaaje naj£e²¢e generiraju senzori na svome izlazu u obliku rastu¢ih (engl. rising)i padaju¢ih (engl. falling) bridova signala. Primjer takvih senzora jesu enkoderi, kapacitivnisenzori, induktivni senzori, krajnji prekida£i, tipkala i drugi. Izlazi senzora spajaju se na pinovemikroupravlja£a koji omogu¢uju detekciju rastu¢ih i padaju¢ih bridova signala. Ovi bridovisignala izazivaju prekide u mikroupravlja£u koji pozivaju prekidnu rutinu onog trenutka kada sebrid signala pojavi. U prekidnoj rutini mogu¢e je na odgovaraju¢i na£in odgovoriti na vanjskiprekid.

11.1 Vjeºbe - vanjski prekidi

Dvije su vrste prekida koji se mogu generirati na pinovima mikroupravlja£a ATmega32U4:vanjski prekidi (engl. External Interrupts - INT) i prekidi izazvani promjenom stanja na pinu(engl. Pin Change Interrupts - PCINT). Vanjski prekidi mikroupravlja£a ATmega32U4 mogu segenerirati na pinovima:

• INT0 (PD0),

• INT1 (PD1),

• INT2 (PD2),

• INT3 (PD3),

• INT6 (PE6).

Prekidi se na navedenim pinovima mogu generirati £ak i kada su pinovi kongurirani kaoizlazni pinovi, ²to omogu¢uje softverski prekid. Na pinovima INT0, INT1, INT2, INT3 i INT6zahtjev za prekid moºe generirati padaju¢i i/ili rastu¢i brid signala te niska razina signala, ²to jemogu¢e kongurirati za svaki vanjski prekid posebno. Vanjski prekid INT0, INT1, INT2 i INT3kongurira se u registru EICRA pomo¢u bitova ISCx1 i ISCx0 prema tablici 11.1. Prekid na pinuINT6 kongurira se u registru EICRB pomo¢u bitova ISC61 i ISC60 prema tablici 11.2.

Vanjski prekidi omogu¢uju se u registru EIMSK na sljede¢i na£in:

• vanjski prekid na pinu INT0 (PD0) bit ¢e omogu¢en ako u registar EIMSK na mjesto bitaINT0 upi²ete vrijednost 1,

208 Vanjski prekidi

• vanjski prekid na pinu INT1 (PD1) bit ¢e omogu¢en ako u registar EIMSK na mjesto bitaINT1 upi²ete vrijednost 1,

• vanjski prekid na pinu INT2 (PD2) bit ¢e omogu¢en ako u registar EIMSK na mjesto bitaINT2 upi²ete vrijednost 1,

• vanjski prekid na pinu INT3 (PD3) bit ¢e omogu¢en ako u registar EIMSK na mjesto bitaINT3 upi²ete vrijednost 1,

• vanjski prekid na pinu INT6 (PE6) bit ¢e omogu¢en ako u registar EIMSK na mjesto bitaINT6 upi²ete vrijednost 1,

Tablica 11.1: Konguracija za vanjski prekid na pinu INTx (PDx) (x = 0, 1, 2, 3)

ISCx1 ISCx0 Na£in rada za prekid INTx

0 0Niska razina signala na pinu INTx (PDx)

generira zahtjev za prekid

0 1Bilo koja logi£ka promjena signala na pinu

INTx (PDx) generira asinkroni zahtjev za prekid

1 0Padaju¢i brid signala na pinu INTx (PDx)

generira asinkroni zahtjev za prekid

1 1Rastu¢i brid signala na pinu INTx (PDx)

generira asinkroni zahtjev za prekid

Tablica 11.2: Konguracija za vanjski prekid na pinu INT6 (PE6)

ISC61 ISC60 Na£in rada za prekid INT6

0 0Niska razina signala na pinu INT6 (PE6)

generira zahtjev za prekid

0 1Bilo koja logi£ka promjena signala na pinuINT6 (PE6) generira zahtjev za prekid

1 0Padaju¢i brid izmeu dvaju uzoraka signala

na pinu INT6 (PE6) generira zahtjev za prekid

1 1Rastu¢i brid izmeu dvaju uzoraka signala

na pinu INT6 (PE6) generira zahtjev za prekid

Primjer omogu¢enja i konguracije vanjskih prekida INT0, INT1 i INT2 prikazan jeprogramskim kodom 11.1. Vanjski prekid INT0 konguriran je tako da oba brida signala napinu INT0 generiraju prekid. INT1 konguriran je tako da rastu¢i brid signala na pinu INT1generira prekid, dok je INT2 konguriran tako da padaju¢i brid signala na pinu INT2 generiraprekid. Na£ini na koji se generiraju prekidi denirani su u registru EICRA prema tablici 11.1.

Programski kod 11.1: Omogu¢enje i konguracija vanjskih prekida INT0, INT1 i INT2

// prvi na£in - INT0

EIMSK |= (1 << INT0); // omogu¢i prekid INT0

EICRA &= ~((1 << ISC01) | (1 << ISC00));

EICRA |= (0 << ISC01) | (1 << ISC00); // oba brida generiraju prekid INT0

// drugi na£in - INT1

set_bit_reg(EIMSK ,INT1); // INT1 = 1 // omogu¢i prekid INT1

// rastu¢i brid generira prekid INT1

set_bit_reg(EICRA ,ISC10); // ISC10 = 1

set_bit_reg(EICRA ,ISC11); // ISC11 = 1

// tre¢i na£in - INT2

int2_enable (); // omogu¢i prekid INT2

int2_set_falling_edge (); // padaju¢i brid generira prekid INT2

11.1 Vjeºbe - vanjski prekidi 209

Ukoliko se vanjski prekid ne omogu¢i, zahtjev za prekid ne¢e se generirati. Ako su vanjskiprekidi omogu¢eni, tada ¢e oni pozivati sljede¢e prekidne rutine:

• ISR(INT0_vect) - prekidna rutina koja se poziva kada se generira prekid pomo¢u pinaINT0 (PD0),

• ISR(INT1_vect) - prekidna rutina koja se poziva kada se generira prekid pomo¢u pinaINT1 (PD1),

• ISR(INT2_vect) - prekidna rutina koja se poziva kada se generira prekid pomo¢u pinaINT2 (PD2),

• ISR(INT3_vect) - prekidna rutina koja se poziva kada se generira prekid pomo¢u pinaINT3 (PD3),

• ISR(INT6_vect) - prekidna rutina koja se poziva kada se generira prekid pomo¢u pinaINT6 (PE6).

Kada se koriste vanjski prekidi na pinovima INT0 (PD0), INT1 (PD1), INT2 (PD2), INT3(PD3) i INT6 (PE6), tada pinove PD0, PD1, PD2, PD3 i PE6 postavite kao ulazne pinove1. Akopadaju¢e i rastu¢e bridove generiraju tipkala, krajnji prekida£i i senzori s otvorenim kolektorom,tada je potrebno uklju£iti pritezne otpornike na pinovima PD0, PD1, PD2, PD3 i PE6. U slu£ajusenzora s push-pull izlazom, pritezne otpornike nije potrebno uklju£iti. Primijetite da se, ukolikokoristite serijsku komunikaciju na mikroupravlja£u ATmega32U4, INT2 (PD2) i INT3 (PD3) nemogu koristiti kao vanjski prekidi.

Autor je pripremio brojne funkcije koje omogu¢uju jednostavnu konguraciju vanjskih prekidapomo¢u zaglavlja "interrupt.h" koje se nalazi u mapi "Interrupt". U nastavku je popisfunkcija koje se koriste za konguraciju vanjskih prekida:

• int0_enable() - funkcija koja omogu¢uje vanjski prekid na pinu INT0,

• int1_enable() - funkcija koja omogu¢uje vanjski prekid na pinu INT1,

• int2_enable() - funkcija koja omogu¢uje vanjski prekid na pinu INT2,

• int3_enable() - funkcija koja omogu¢uje vanjski prekid na pinu INT3,

• int6_enable() - funkcija koja omogu¢uje vanjski prekid na pinu INT6,

• int0_disable() - funkcija koja onemogu¢uje vanjski prekid na pinu INT0,

• int1_disable() - funkcija koja onemogu¢uje vanjski prekid na pinu INT1,

• int2_disable() - funkcija koja onemogu¢uje vanjski prekid na pinu INT2,

• int3_disable() - funkcija koja onemogu¢uje vanjski prekid na pinu INT3,

• int6_disable() - funkcija koja onemogu¢uje vanjski prekid na pinu INT6,

• int0_set_low_level() - funkcija koja vanjski prekid INT0 kongurira na na£in da niskarazina signala na pinu INT0 izaziva prekid,

• int1_set_low_level() - funkcija koja vanjski prekid INT1 kongurira na na£in da niskarazina signala na pinu INT1 izaziva prekid,

1Ovo je preporuka, iako ¢e se vanjski prekidi generirati i ako su pinovi PD2, PD3 i PB2 postavljeni kao izlaznipinovi.

210 Vanjski prekidi

• int2_set_low_level() - funkcija koja vanjski prekid INT2 kongurira na na£in da niskarazina signala na pinu INT2 izaziva prekid,

• int3_set_low_level() - funkcija koja vanjski prekid INT3 kongurira na na£in da niskarazina signala na pinu INT3 izaziva prekid,

• int6_set_low_level() - funkcija koja vanjski prekid INT6 kongurira na na£in da niskarazina signala na pinu INT6 izaziva prekid,

• int0_set_rising_falling_edge() - funkcija koja vanjski prekid INT0 kongurira nana£in da oba brida signala na pinu INT0 (i rastu¢i i padaju¢i) izazivaju prekid,

• int1_set_rising_falling_edge() - funkcija koja vanjski prekid INT1 kongurira nana£in da oba brida signala na pinu INT1 (i rastu¢i i padaju¢i) izazivaju prekid,

• int2_set_rising_falling_edge() - funkcija koja vanjski prekid INT2 kongurira nana£in da oba brida signala na pinu INT2 (i rastu¢i i padaju¢i) izazivaju prekid,

• int3_set_rising_falling_edge() - funkcija koja vanjski prekid INT3 kongurira nana£in da oba brida signala na pinu INT3 (i rastu¢i i padaju¢i) izazivaju prekid,

• int6_set_rising_falling_edge() - funkcija koja vanjski prekid INT6 kongurira nana£in da oba brida signala na pinu INT6 (i rastu¢i i padaju¢i) izazivaju prekid,

• int0_set_falling_edge() - funkcija koja vanjski prekid INT0 kongurira na na£in dapadaju¢i brid signala na pinu INT0 izaziva prekid,

• int1_set_falling_edge() - funkcija koja vanjski prekid INT1 kongurira na na£in dapadaju¢i brid signala na pinu INT1 izaziva prekid,

• int2_set_falling_edge() - funkcija koja vanjski prekid INT2 kongurira na na£in dapadaju¢i brid signala na pinu INT2 izaziva prekid,

• int3_set_falling_edge() - funkcija koja vanjski prekid INT3 kongurira na na£in dapadaju¢i brid signala na pinu INT3 izaziva prekid,

• int6_set_falling_edge() - funkcija koja vanjski prekid INT6 kongurira na na£in dapadaju¢i brid signala na pinu INT6 izaziva prekid,

• int0_set_rising_edge() - funkcija koja vanjski prekid INT0 kongurira na na£in darastu¢i brid signala na pinu INT0 izaziva prekid,

• int1_set_rising_edge() - funkcija koja vanjski prekid INT1 kongurira na na£in darastu¢i brid signala na pinu INT1 izaziva prekid,

• int2_set_rising_edge() - funkcija koja vanjski prekid INT2 kongurira na na£in darastu¢i brid signala na pinu INT2 izaziva prekid,

• int3_set_rising_edge() - funkcija koja vanjski prekid INT3 kongurira na na£in darastu¢i brid signala na pinu INT3 izaziva prekid,

• int6_set_rising_edge() - funkcija koja vanjski prekid INT6 kongurira na na£in darastu¢i brid signala na pinu INT6 izaziva prekid.

Prekidi izazvani promjenom stanja na pinu (PCINT prekidi) mikroupravlja£a ATmega32U4mogu se generirati na pinovima:

• PCINT0 (PB0),

11.1 Vjeºbe - vanjski prekidi 211

• PCINT1 (PB1),

• PCINT2 (PB2),

• PCINT3 (PB3),

• PCINT4 (PB4),

• PCINT5 (PB5),

• PCINT6 (PB6),

• PCINT7 (PB7).

Na navedenim pinovima prekid se moºe generirati £ak i kada su pinovi kongurirani kaoizlazni pinovi, ²to omogu¢uje softverski prekid. Zahtjev za PCINT prekid moºe generirati bilokoja promjena signala (rastu¢i i padaju¢i brid) na pinovima PCINT0 - PCINT7. Koji godod navedenih osam pinova izazove prekid, uvijek se poziva smo jedna prekidna rutina, i toISR(PCINT0_vect). PCINT prekidi omogu¢uju se u registru PCICR tako da na mjesto bita PCIE0upi²ete vrijednost 1. Koji ¢e od pinova PCINT0 - PCINT7 mo¢i generirati zahtjev za prekidodreuje se registrom PCMSK0 sa slike 11.1. Na primjer, ako ºelimo da nam PCINT2 (PB2) moºegenerirati prekid, tada ¢emo u registar PCMSK0 na mjesto bita PCINT2 upisati vrijednost 1.

Bit 7 6 5 4 3 2 1 0

PCMSK0 PCINT7 PCINT6 PCINT5 PCINT4 PCINT3 PCINT2 PCINT1 PCINT0

Slika 11.1: Registar PCMSK0

Autor je pripremio brojne funkcije koje omogu¢uju jednostavnu konguraciju PCINT prekidapomo¢u zaglavlja "interrupt.h" koje se nalazi u mapi "Interrupt". U nastavku je popisfunkcija koje se koriste za konguraciju PCINT prekida:

• pcint_enable() - funkcija koja omogu¢uje PCINT prekid,

• pcint_disable() - funkcija koja onemogu¢uje PCINT prekid,

• pcint_pin_enable(uint8_t pin) - funkcija koja omogu¢uje prekid na pinu kojije deniran argumentom pin (argument pin poprima predenirane vrijednostiPCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5, PCINT6, PCINT7 prikazane naslici 11.1),

• pcint_pin_disable(uint8_t pin) - funkcija koja onemogu¢uje prekid na pinu kojije deniran argumentom pin (argument pin poprima predenirane vrijednostiPCINT0, PCINT1, PCINT2, PCINT3, PCINT4, PCINT5, PCINT6, PCINT7 prikazane naslici 11.1),

• pcint_pin_enable_all() - funkcija koja omogu¢uje prekid na svim pinovima PCINT0 -PCINT7,

• pcint_pin_disable_all() - funkcija koja onemogu¢uje prekid na svim pinovima PCINT0- PCINT7.

U ovoj ¢e se vjeºbi za generiranje prekida koristiti tipkala spojena na pinove PD0 i PD1prema slici 4.5 te pinovi PB4 i PB5 na kojima su spojene LED diode prema slici 4.1 kako bismogenerirali softverski prekid.

212 Vanjski prekidi

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku Vanjski prekidi.zip. Naradnoj povr²ini stvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢ipritom dijakriti£ke znakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢ete stvoritizvat ¢e se Ivica Ivic. Datoteku Vanjski prekidi.zip raspakirajte u novostvorenu datotekuna radnoj povr²ini. Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini te dvostrukimklikom pokrenite VUB mikroracunala.atsln u datoteci \\Vanjski prekidi\vjezbe. Uotvorenom projektu nalaze se sve vjeºbe koja ¢emo obraditi u poglavlju Vanjski prekidi.Vjeºbe ¢emo pisati u datoteke s ekstenzijom *.cpp.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koja moºete koristiti za provjeru ispravnostiprogramskih zadataka.

Vjeºba 11.1.1

Napravite program kojim ¢ete:

• na pinu INT0 (PD0) brojati rastu¢e bridove signala tipkala spojenog na pin PD0,

• na pinu INT1 (PD1) brojati padaju¢e i rastu¢e bridove signala tipkala spojenog na pinPD1,

• na svaki rastu¢i brid signala na pinu INT1 promijeniti stanje crvene LED diode spojene napin PB4.

Vrijednosti broja£a bridova signala na pinovima INT0 i INT1 prikaºite na LCD displeju.

U projektnom stablu otvorite datoteku vjezba1111.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1111.cpp. Po£etni sadrºaj datoteke vjezba1111.cpp prikazan je programskimkodom 11.2.

Programski kod 11.2: Po£etni sadrºaj datoteke vjezba1111.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "LCD/lcd.h"

#include "Interrupt/interrupt.h"

int brojac_int0 = 0;

int brojac_int1 = 0;

bool lcd_update = true;

// prekidna rutina za vanjski prekid INT0

ISR(INT0_vect)

brojac_int0 ++;

lcd_update = true;

// prekidna rutina za vanjski prekid INT1

ISR(INT1_vect)

brojac_int1 ++;

lcd_update = true;

if(get_pin(PIND , PD1))

toggle_port(PORTB , PB4);

void inicijalizacija ()

11.1 Vjeºbe - vanjski prekidi 213

lcd_init (); // konfiguriranje LCD displeja

// konfiguracija prekida INT0

EIMSK |= (1 << INT0); // omogu¢i prekid INT0

// padaju¢i brid generira prekid na INT0

EICRA &= ~((1 << ISC01) | (1 << ISC00));

EICRA |= (1 << ISC01) | (0 << ISC00);

// konfiguracija prekida INT1

interrupt_enable (); // omogu¢i globalni prekid

// konfiguriranje ulaza PD0 i PD1 te izlaza PB4

DDRD &= ~((1 << PD0) | (1 << PD1));

PORTD |= (1 << PD0) | (1 << PD1);

DDRB |= (1 << PB4);

int main(void)

inicijalizacija ();

while (1)

if(lcd_update)

lcd_clrscr ();

lcd_home ();

lcd_print("INT0: %d\nINT1: %d", brojac_int0 , brojac_int1);

lcd_update = false;

asm("nop"); // instrukcija koja kasni jedan ciklus CPU -a

return 0;

Za generiranje vanjskih prekida INT0 i INT1 koristit ¢emo tipkala spojena na pinove PD0 iPD1. U programskom kodu 11.2 u funkciji inicijalizacija() vanjski prekid INT0 omogu¢enje u registru EIMSK tako da smo na mjesto bita INT0 u registru EIMSK upisali vrijednost 1. Vanjskiprekid INT0 konguriran je tako da se zahtjev za prekid generira na padaju¢i brid signala. Zaovu konguraciju, prema tablici 11.1 (x = 0), bit ISC00 u registru EICRA mora biti jednak 0, abit ISC01 u registru EICRA mora biti jednak 1.

Vanjskih prekid INT1 potrebno je kongurirati tako da se zahtjev za prekid generira naoba brida signala (rastu¢i i padaju¢i). U programski kod 11.2 u funkciju inicijalizacija()potrebno je dodati sljede¢i niz naredaba (ispod konguracije vanjskog prekida INT0):

• EIMSK |= (1 << INT1); - omogu¢enje vanjskog prekida INT1,

• EICRA &= ~((1 << ISC11)| (1 << ISC10)); - £i²¢enje stanja bitova ISC11 i ISC10 (²tonije nuºno napraviti ako se radi o prvoj konguraciji u programskom kodu),

• EICRA |= (0 << ISC11)| (1 << ISC10); - zahtjev za prekid generiraju i rastu¢i ipadaju¢i brid pa, prema tablici 11.1 (x = 1), bit ISC10 u registru EICRA mora biti jednak1, a bit ISC11 u registru EICRA mora biti jednak 0.

U programskom kodu 11.2 u funkciji inicijalizacija() dodatno je inicijaliziran LCDdisplej, globalno su omogu¢eni prekidi te su PD0 i PD1 kongurirani kao ulazni, a PB4 kaoizlazni pin.

Za brojanje bridova signala deklarirane su dvije globalne varijable brojac_int0 ibrojac_int1. Vrijednosti ovih varijabli uve¢avaju se u prekidnim rutinama na sljede¢i na£in:

214 Vanjski prekidi

• u prekidnoj rutini ISR(INT0_vect) vrijednost varijable brojac_int0 uve¢ava se za jedanna svaki padaju¢i brid signala na pinu INT0 (PD0) (svaki puta kad se pritisne tipkalo),

• u prekidnoj rutini ISR(INT1_vect) vrijednost varijable brojac_int1 uve¢ava se za jedanna svaki padaju¢i i na svaki rastu¢i brid signala na pinu INT1 (PD1) (svaki puta kada sepritisne i kada se otpusti tipkalo).

U while petlji vrijednosti broja£a bridova signala prikazuju se na LCD displeju, i to samoonda kada se dogodila promjena vrijednosti u varijablama brojac_int0 i brojac_int1. Dakle,ispis na LCD displej uvjetovan je logi£kom varijablom lcd_update koja se pri svakom pozivuprekidnih rutina ISR(INT0_vect) i ISR(INT1_vect) postavlja u vrijednost true. Nakon ispisanovih vrijednosti na LCD, varijabla lcd_update postavlja se u vrijednost false.

U while petlji pojavljuje se i jedna nova naredbe: asm("nop");. Radi se o instrukciji NOP(engl. no operation) koja u pravilu zakasni program mikroupravlja£a za jedan impuls radnogtakta (ka²njenje iznosa 1/F_CPU s). Za²to se ona ovdje nalazi? Naime, gcc prevoditelj radioptimizaciju programskog koda. Procjena optimizacije jest da ¢e se programski kod uvjetovanvarijablom lcd_update izvesti samo jednom u petlji. Iz tog ¢e razloga prevoditelj obrisati whilepetlju. Rezultat optimizacije bio bi zavr²etak programa nakon prvog ispisa na LCD displej jerbi funkcija main() s izvoenjem do²la do samoga kraja. Iako na prvu izgleda kako je prevoditeljnapravio propust, on je ipak optimizaciju odradio potpuno ispravno. Prevoditelj programskogkoda u jeziku C ili C++ ne razumije da ¢e prekidnu rutinu pozvati neki vanjski sklop i promijenitivarijablu lcd_update te se stoga ovakvi propusti prevoditelja u slu£aju optimizacije pojavljujusamo onda kada se koriste prekidne rutine. Umjesto naredbe asm("nop"), mogli smo koristiti ifunkciju _delay_us(1) koja bi opet osigurala da prevoditelj ne obri²e while petlju. Optimizacijukoju radi prevoditelj mogu¢e je isklju£iti, u tom se slu£aju programski kod 11.2 pri prevoenjuu strojni kod pove¢a to£no 2,5 puta. U slu£aju da vam se pri testiranju programa u£ini da jefunkcija main() zavr²ila s izvoenjem, a postoji mogu¢nost da prevoditelj optimizacijom obri²ewhile petlju, na kraj while petlje dodajte naredbu asm("nop") ili funkciju _delay_us(1). Autorprednost daje kori²tenju naredbe asm("nop") jer ¢e u na²em slu£aju ona 16 puta kra¢e zaustavitiwhile petlju.

Prevedite datoteku vjezba1111.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Pritisnite tipkala spojena na pinove PD0 i PD1 te promatrajte vrijednosti broja£a bridova signalana LCD displeju.

Obri²ite naredbu asm("nop") te ponovno prevedite datoteku vjezba1111.cpp u strojni kodi snimite ga na mikroupravlja£ ATmega32U4. Primijetite da se pritiskom tipkala PD0 i PD1stanje broja£a bridova signala ne mijenja. Ostavite i dalje obrisanu naredbu asm("nop").

Drugi, bolji, na£in kako sprije£iti prevoditelj da optimizira kod while petlje jestkori²tenje klju£ne rije£i volatile ispred tipa deklarirane varijable. Klju£na rije£volatile ima za cilj sprije£iti primjenu optimizacije programskog koda nad objektimakoji se mogu promijeniti na na£ine koje prevoditelj ne moºe utvrditi. Takav je slu£ajglobalnih varijabli koje se mijenjaju u prekidnim rutinama. Zamijenite deklaracijuglobalne varijable bool lcd_update = true deklaracijom volatile bool lcd_update = truete ponovno prevedite datoteku vjezba1111.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Primijetite da se pritiskom tipkala PD0 i PD1 stanje broja£a bridova signalasada mijenja. Preporuka je da se svakoj globalnoj varijabli koju mijenja prekidna rutina prijetipa deklaracije doda klju£na rije£ volatile.

Konguraciju vanjskih prekida mogu¢e je napraviti pomo¢u funkcija napisanih u zaglavlju"interrupt.h" koje se nalazi u mapi "Interrupt". Funkcije smo opisali u uvodnom djelu ovogpoglavlja. Zamijenite konguraciju vanjskih prekida INT0 i INT1 u datoteci vjezba1111.cppprogramskim kodom 11.3.

11.1 Vjeºbe - vanjski prekidi 215

Programski kod 11.3: Nova konguracija vanjskih prekida INT0 i INT1

// konfiguracija prekida INT0

int0_enable (); // omogu¢i prekid INT0

int0_set_falling_edge (); // oba brida generiraju prekid INT1

// konfiguracija prekida INT1

int1_enable (); // omogu¢i prekid INT1

int1_set_rising_falling_edge (); // oba brida generiraju prekid INT1

Prevedite datoteku vjezba1111.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Pritisnite tipkala spojena na pinove PD0 i PD1 te promatrajte vrijednosti broja£a bridova signalana LCD displeju.

Zatvorite datoteku vjezba1111.cpp i onemogu¢ite prevoenje ove datoteke.

Vjeºba 11.1.2

Napravite program kojim ¢ete na proizvoljan na£in uklju£ivati i isklju£ivati crvenu LED dioduspojenu na pin PB4 i zelenu LED diodu spojenu na pin PB6. Stanje crvene LED diode potrebnoje preslikati na ºutu LED diodu spojenu na pin PB5, a stanje zelene LED diode potrebno jepreslikati na plavu LED diodu spojenu na pin PB7 koriste¢i PCINT prekid. Dakle, PCINTprekid generirat ¢e se softverski, promjenom stanja na pinovima PB4 i PB6.

U projektnom stablu otvorite datoteku vjezba1112.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1112.cpp. Po£etni sadrºaj datoteke vjezba1112.cpp prikazan je programskimkodom 11.4.

Programski kod 11.4: Po£etni sadrºaj datoteke vjezba1112.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "Interrupt/interrupt.h"

#include "DigitalIO/DigitalIO.h"

DigitalOutput LED_crvena(B4);

DigitalOutput LED_zuta(B5);

DigitalOutput LED_zelena(B6);

DigitalOutput LED_plava(B7);

uint8_t pinb_old;

ISR(PCINT0_vect)

uint8_t pin_changed = pinb_old ^ PINB;

if (pin_changed & (1 << PB4))

LED_zuta.toggle ();

if (pin_changed & (1 << PB6))

if (( pinb_old & (1 << PB6)))

LED_plava.off();

else

LED_plava.on();

pinb_old = PINB;

216 Vanjski prekidi

void inicijalizacija ()

//omogu¢i PCINT prekide

pcint_enable ();

//omogu¢i prekide na pinovima PCINT4 (PB4) i PCINT6 (PB6)

pcint_pin_enable(PCINT4);

pcint_pin_enable(PCINT6);

pinb_old = PINB;

interrupt_enable (); // omogu¢i globalni prekid

int main(void)

inicijalizacija ();

uint8_t brojac = 0;

while (1)

brojac ++;

if (( brojac % 5) == 0) LED_crvena.toggle ();

if (( brojac % 9) == 0) LED_zelena.toggle ();

_delay_ms (100);

return 0;

PCINT prekidi u osnovi su namijenjeni za obradu rastu¢ih i padaju¢ih bridova signala senzoraspojenih na PCINT pinove koji se konguriraju kao ulazi. Ako PCINT pinove koristimo kao izlazei mijenjamo im stanja, tada je mogu¢e generirati softverski PCINT prekid. U programskom kodu11.4 stvoreni su globalni objekti tipa DigitalOutput koji su povezani s crvenom, ºutom, zelenomi plavom LED diodom koje su redom spojene na pinove PB4, PB5, PB6 i PB7.

U while petlji se stanje crvene LED diode mijenja svakih 500 ms, a stanje zelene LED diodesvakih 900 ms. Stanje crvene LED diode potrebno je preslikati na ºutu LED diodu, a stanje zeleneLED diode potrebno je preslikati na plavu LED diodu. Preslikavanje se mora dogoditi odmahpo promjeni stanja crvene i zelene LED diode. PCINT prekidi generiraju se pomo¢u pinova PB0- PB7 pozivaju¢i pritom prekidnu rutinu ISR(PCINT0_vect). Da bi zadovoljili zahtjeve vjeºbe,pinovi PB4 i PB6 na kojima su spojene crvena i zelena LED dioda moraju generirati PCINTprekide. U programskom kodu 11.4 u funkciji inicijalizacija() to je postignuto pozivomsljede¢ih funkcija:

• pcint_enable() - funkcija koja omogu¢uje PCINT prekid,

• pcint_pin_enable(PCINT4) - funkcija koja omogu¢uje da PCINT prekid generira pinPCINT4 (PB4),

• pcint_pin_enable(PCINT6) - funkcija koja omogu¢uje da PCINT prekid generira pinPCINT6 (PB6).

Navedene funkcije nalaze se u zaglavlju "interrupt.h" koje se nalazi u mapi "Interrupt".Vaºno je znati da preostalih ²est pinova na portu B ne¢e generirati prekide. U programskomkodu 11.4 u funkciji inicijalizacija() dodatno su globalno omogu¢eni prekidi te je u globalnuvarijablu pinb_old dodijeljena vrijednost registra PINB. Varijabla pinb_old koristi se kako bise u prekidnoj rutini detektiralo koji je pin na portu B izazvao prekid. Rastu¢i i padaju¢i brid

11.1 Vjeºbe - vanjski prekidi 217

signala na pinovima PB4 i PB6, prema konguraciji u programskom kodu 11.4, pozivaju prekidnurutinu ISR(PCINT0_vect). U prekidnoj rutini najprije se provjerava koji je pin na portu Bizazvao prekid pomo¢u naredbe pin_changed = pinb_old ^ PINB;. Ova naredba koristi bitovnioperator ex-ili. Dvoulazni logi£ki sklop ex-ili kao rezultat daje logi£ku jedinicu samo kada sumu ulazi razli£iti (jedan ulaz 0, drugi ulaz 1). Primjer detekcije pina PB4 koji je izazvao prekidprikazan je na slici 11.2.

U varijabli pin_changed vrijednost 1 imat ¢e samo ona pozicija bita gdje se dogodilapromjena u registru PINB u odnosu na prethodno stanje registra PINB koje se nalazi uvarijabli pinb_old. Provjerom varijable pin_changed sad je lako ustanoviti koji je pin izazvaoprekid. Je li prekid izazvala promjena signala na pinu PB4 provjerit ¢emo pomo¢u uvjetaif (pin_changed & (1 << PB4)). Ovaj uvjet bit ¢e zadovoljen samo ako bit na poziciji 4 uvarijabli pin_changed ima vrijednost 1.

1 1 0 1 1 1 1 0

=0 0 0 1 0 0 0 0

PINB

1 1 0 0 1 1 1 0pinb_old

pin_changed

^

Slika 11.2: Detekcija pina koji je izazvao prekid naredbom pin_changed = pinb_old ^ PINB;

U ovisnosti o tome koliko pinova na portu B izaziva prekide, toliko je u prekidnojrutini ISR(PCINT0_vect) potrebno imati provjera pina koji je izazvao prekid. Op¢enito,provjera za pin x (x = PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7) moºe se napraviti uvjetomif (pin_changed & (1 << x)).

Unutar uvjeta if (pin_changed & (1 << PB4)) ºuta LED dioda mijenja stanje. S obziromna to da su sve LED diode po£etno uga²ene, ova promjena stanja trenutno ¢e pratiti promjenustanja crvene LED diode. Je li prekid izazvala promjena signala na pinu PB6 provjeravamopomo¢u uvjeta if (pin_changed & (1 << PB6)). Unutar ovog uvjeta prikazano je na koji sena£in moºe detektirati rastu¢i ili padaju brid signala na pinu PB6. Naime, ako se dogodioPCINT prekid koji je izazvao pin PB6 i ako je stanje pina PB6 nisko, pin je pre²ao iz visokogstanja u nisko stanje i dogodio se padaju¢i brid. U suprotnom se dogodio rastu¢i brid. Uvjetomif ((pinb_old & (1 << PB6))) provjerava se je li staro stanje pina PB6 bilo visoko (imalovrijednost 1). Ukoliko je staro stanje bilo visoko, tada je padaju¢i brid signala na pinu PB6izazvao prekid te se plava LED dioda isklju£uje. U suprotnom se dogodio rastu¢i brid signalana pinu PB6 koji ¢e uklju£iti plavu LED diodu. Na kraju prekidne rutine ISR(PCINT0_vect)trenutno stanje registra PINB sprema se u varijablu pinb_old kako bi se pri novoj promjeni stanjasignala na nekom pinu porta B moglo detektirati koji je pin izazvao prekid.

Prevedite datoteku vjezba1112.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Pratite ²to se dogaa s crvenom i ºutom LED diodom te zelenom i plavom LED diodom.

Zakomentirajte poziv funkcija pcint_pin_enable(PCINT4) i pcint_pin_enable(PCINT6)te ponovno prevedite datoteku vjezba1112.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Primijetite da se stanja ºute i plave LED diode vi²e ne mijenjaju.

Zatvorite datoteku vjezba1112.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

218 Vanjski prekidi

11.1.1 Zadaci - vanjski prekidi

Zadatak 11.1.1

Napravite program kojim ¢ete:

• na pinu INT0 (PD0) brojati padaju¢e i rastu¢e bridove signala tipkala spojenog na pinPD0,

• na pinu INT1 (PD1) brojati padaju¢e bridove signala tipkala spojenog na pin PD1,

• na svaki padaju¢i brid signala na pinu INT0 promijeniti stanje plave LED diode spojenena pin PB7.

Vrijednosti broja£a bridova signala na pinovima INT0 i INT1 prikaºite na LCD displeju.

Zadatak 11.1.2

Napravite program kojim ¢ete na proizvoljan na£in uklju£ivati i isklju£ivati ºutu LED dioduspojenu na pin PB5. Stanje ºute LED diode potrebno je preslikati na plavu LED diodu spojenuna pin PB7 koriste¢i PCINT prekid. Dakle, PCINT prekid generirat ¢e se softverski, promjenomstanja na pinu PB5.

Poglavlje 12

Povezivanje odabranih elektroni£kih

modula na mikroupravlja£

Velik je broj elektroni£kih modula koji se mogu spojiti na mikroupravlja£ ATmega32U4. Uovoj vjeºbi odabrali smo sljede¢e elektroni£ke module:

• rotacijski enkoder,

• tranzistor kao sklopka i relej,

• ultrazvu£ni senzor HC-SR04,

• temperaturni senzor LM35,

• servomotor i

• RGB dioda.

Neki od elektroni£kih modula nalaze se na razvojnom okruºenju sa slike 3.1, dok seostali elektroni£ki moduli spajaju na konektore razvojnog okruºenja. Za svaki od navedenihelektroni£kih modula napravit ¢emo programski kod kojim ¢emo obraivati signale elektroni£kihmodula.

S mreºne stranice www.vub.hr/mikroracunala skinite datoteku Moduli.zip. Na radnojpovr²ini stvorite praznu datoteku koju ¢ete nazvati Va²e Ime i Prezime ne koriste¢i pritomdijakriti£ke znakove. Na primjer, ako je Va²e ime Ivica Ivi¢, datoteka koju ¢ete stvoriti zvat ¢ese Ivica Ivic. Datoteku Moduli.zip raspakirajte u novostvorenu datoteku na radnoj povr²ini.Pozicionirajte se u novostvorenu datoteku na radnoj povr²ini te dvostrukim klikom pokreniteVUB mikroracunala.atsln u datoteci \\Moduli\vjezbe. U otvorenom projektu nalaze se svenaredne vjeºbe koje ¢emo obraditi u poglavlju Povezivanje odabranih elektroni£kih modulana mikroupravlja£. Vjeºbe ¢emo pisati u datoteke s ekstenzijom *.cpp.

U datoteci s vjeºbama nalaze se i rje²enja vjeºbi koja moºete koristiti za provjeru ispravnostiprogramskih zadataka.

12.1 Rotacijski enkoder

Enkoderi op¢enito sluºe za mjerenje kutne i linearne pozicije te kutne i linearne brzine. Iz tograzloga postoje rotacijski i linearni enkoderi. Rotacijski enkoderi mjere kutnu brzinu i pozicijukuta, a linearni enkoderi mjere linearnu brzinu i linearnu poziciju.

220 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

Rotacijski enkoderi naj£e²¢e se koriste za mjerenje brzine vrtnje i pozicije kuta osovine radnogstroja. Ta osovina moºe biti povezana na rotor elektri£nog motora ili na neki prijenosnik uradnom stroju. Rotacijski enkoder kakav ¢emo mi koristiti u vjeºbi koristi se za zadavanjereferentne vrijednosti. Okretanjem rotacijskog enkodera u jednom smjeru referentna se vrijednostpove¢ava, a okretanjem u drugom smjeru referentna se vrijednost smanjuje. Shema spajanjarotacijskog enkodera na mikroupravlja£ ATmega32U4 prikazana je na slici 12.1. Kori²tenirotacijski enkoder ima dva kanala: A i B kanal koji generiraju niz impulsa koji su pomaknuti za90 (slika 12.2). Kanal A spojen je na pin PD0 (INT0), a kanal B spojen je na pin PD1 (INT1).Detektiranjem impulsa na kanalu A i B moºemo mjeriti i poziciju kuta i smjer vrtnje. KanalA i B spojeni su na vanjske prekide jer generirani impulsi na kanalu A i B mogu imati visokufrekvenciju pa je vaºno uhvatiti svaki impuls.

Dodatno, ovaj rotacijski enkoder ima tipkalo koje je spojeno na pin PF7, a kojim se moºeresetirati kutna pozicija rotacijskog enkodera. Kao ²to moºemo primijetiti, kanal A, kanal B itipkalo rotacijskog enkodera dijele iste pinove kao i tipkala koja smo dosad koristili u vjeºbama.Stoga, da bismo koristili rotacijski enkoder, kratkospojnike JP8, JP9 i JP10 potrebno je spojitiizmeu trnova 2 i 3 (slika 12.1).

+5V

GND

100n

10k

+5V

1uF

22p

22p

GND

GND

+5V

+5V

UGND

EC12E_SW

EC12E_SW

GND

GND

100n 100n

GNDGND

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2

C12

C13

134 2

S5

21

Q1

SW1

SW1

1 2 3

JP8

1 2 3

JP9

C7 C19

1 2 3

JP10

RESET

MISOMOSI

RXTX

AREF

D-D+

VUSB

SCK

PD6

PC7

PE6

PD7

PC6

PF1PF0

SS

S1

S2

S4

Slika 12.1: Shema spajanja rotacijskog enkodera na mikroupravlja£ ATmega32U4

Obrada impulsa koji se generiraju kanalima A i B nije jednostavan zadatak. Postoji vi²epristupa u obradi signala. Pristupi se razlikuju u obradi broja rastu¢ih i padaju¢ih bridovasignala na kanalu A i/ili kanalu B. Da bismo objasnili obradu signala i na taj na£in mjerenjekutne pozicije, pogledat ¢emo sliku 12.2.

Na slici 12.2 denirani su smjerovi: Smjer 1 i Smjer 2. Jedan je od smjerova rotacija enkoderau smjeru kazaljke na satu, a drugi je smjer rotacija enkodera u smjeru suprotnom od kazaljke nasatu. Na na²em je razvojnom okruºenju Smjer 1 rotacija suprotna od kazaljke na satu, a Smjer2 rotacija u smjeru kazaljke na satu.

Pri obradi impulsa s rotacijskog enkodera mogu se koristiti i rastu¢i i padaju¢i brid signalana kanalu A, a moºe se koristiti i samo rastu¢i brid signala na kanalu A. Razlika ¢e biti samo ufrekvenciji, odnosno u preciznosti mjerenja pozicije. U oba slu£aja, kanal A sluºi za generiranje

12.1 Rotacijski enkoder 221

impulsa i obrauje se kao vanjski prekid, dok kanal B sluºi za detektiranje smjera. Kada se nakanalu A obrauju i rastu¢i i padaju¢i brid signala, tada govorimo o na£inu kori²tenja rotacijskogenkodera u dva kvadranta. Ako se na kanalu A obrauje samo rastu¢i brid signala, tada govorimoo na£inu kori²tenja rotacijskog enkodera u jednom kvadrantu. Za obradu u jednom kvadrantuvrijedi:

• kada se na kanalu A detektira rastu¢i brid, a stanje kanala B je 0, tada je smjer vrtnjeSmjer 1,

• kada se na kanalu A detektira rastu¢i brid, a stanje kanala B je 1, tada je smjer vrtnjeSmjer 2.

Primijetimo da u ovom pristupu kanal B zapravo odreuje smjer vrtnje. Za Smjer 1 broja£impulsa (pozicije) moºemo smanjivati za jedan, a za Smjer 2 broja£ impulsa (pozicije) moºemopove¢avati za jedan.

A

B

Smjer 1 Smjer 2

0

1

0

1

0

1 1

0

Slika 12.2: Prikaz rastu¢ih i padaju¢ih bridova signala na kanalima A i B rotacijskog enkoderakoji su pomaknuti za 90

Za Smjer 1 i na£in rada u dva kvadranta vrijedi:

• kada se na kanalu A detektira rastu¢i brid, stanje kanala B jest 0,

• kada se na kanalu A detektira padaju¢i brid, stanje kanala B jest 1.

Za Smjer 2 i na£in rada u dva kvadranta vrijedi:

• kada se na kanalu A detektira rastu¢i brid, stanje kanala B jest 1,

• kada se na kanalu A detektira padaju¢i brid, stanje kanala B jest 0.

Primijetimo da u ovom pristupu kanal B ponovno odreuje smjer vrtnje. Postoji i na£in kori²tenjarotacijskog enkodera u £etiri kvadranta. U tom je slu£aju i na kanalu A i na kanalu B potrebnodetektirati i rastu¢e i padaju¢e bridove. Za Smjer 1 i na£in rada u £etiri kvadranta vrijedi:

• kada se na kanalu A detektira rastu¢i brid, stanje kanala B jest 0,

• kada se na kanalu B detektira rastu¢i brid, stanje kanala A jest 1,

• kada se na kanalu A detektira padaju¢i brid, stanje kanala B jest 1,

• kada se na kanalu B detektira padaju¢i brid, stanje kanala A jest 0.

222 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

Za Smjer 2 i na£in rada u £etiri kvadranta vrijedi:

• kada se na kanalu A detektira rastu¢i brid, stanje kanala B jest 1,

• kada se na kanalu B detektira padaju¢i brid, stanje kanala A jest 1.

• kada se na kanalu A detektira padaju¢i brid, stanje kanala B jest 0,

• kada se na kanalu B detektira rastu¢i brid, stanje kanala A jest 0,

Na£in rada u £etiri kvadranta zahtijeva da se kanali A i B obrauju pomo¢u vanjskih prekida.

Vjeºba 12.1.1

Napravite program kojim ¢ete pomo¢u rotacijskog enkodera zadavati referentnu vrijednost uintervalu od [0, 100]. Tipkalom na rotacijskom enkoderu referentna vrijednost postavlja sena 0. U prvom retku LCD displeja potrebno je ispisati referentnu vrijednost, a drugi redakLCD displeja potrebno je popunjavati (simulirati loading) u ovisnosti o referentnoj vrijednosti.Shema spajanja rotacijskog enkodera na mikroupravlja£ ATmega32U4 prikazana je na slici 12.1.

U projektnom stablu otvorite datoteku vjezba1211.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1211.cpp. Po£etni sadrºaj datoteke vjezba1211.cpp prikazan je programskimkodom 12.1.

Programski kod 12.1: Po£etni sadrºaj datoteke vjezba1211.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "LCD/lcd.h"

#include "Timer/timer.h"

#include "Interrupt/interrupt.h"

#include "DigitalIO/DigitalIO.h"

// ulazi za rotacijski enkoder

DigitalInput Encoder_ChannelA(D0);

DigitalInput Encoder_ChannelB(D1);

DigitalInput Encoder_PushButton(F7);

int8_t encoder_position = 0;

bool new_position = true;

#define ENCODER_LOW_LEVEL 0

#define ENCODER_HIGH_LEVEL 100

void encoder_inc_dec(bool direction)

// direction = true - Smjer 1, direction = false - Smjer 2

//Smjer 1 - u smjeru kazaljke na satu

//Smjer 2 - suprotno smjeru kazaljke na satu

if(direction == false)

if (encoder_position < ENCODER_HIGH_LEVEL)

encoder_position ++;

else

if(encoder_position > ENCODER_LOW_LEVEL)

encoder_position --;

12.1 Rotacijski enkoder 223

new_position = true;

// jednokvadrantni na£in rada , INT0 - rastu¢i brid

ISR(INT0_vect)

// direction = true - Smjer 1, direction = false - Smjer 2

bool direction;

direction = !Encoder_ChannelB.state ();

encoder_inc_dec(direction);

void inicijalizacija ()

lcd_init (); // konfiguracije LCD displeja

int0_enable (); // omogu¢i INT0

int0_set_rising_edge (); // rastu¢i brid generira prekid na INT0

// pritezni otpornici na ulazima za rotacijski enkoder

Encoder_ChannelA.pullup_on ();

Encoder_ChannelB.pullup_on ();

Encoder_PushButton.pullup_on ();

interrupt_enable ();

int main(void)

inicijalizacija ();

uint8_t loading = 0;

while (1)

if(new_position)

lcd_clrscr ();

lcd_home ();

lcd_print("%d\n", encoder_position);

loading = 16* encoder_position /100.0;

for(uint8_t i = 0; i < loading; i++)

lcd_char (255);

new_position = false;

if(Encoder_PushButton.isFalling_edge ())

encoder_position = 0;

new_position = true;

Rotacijski enkoder spojen je na sljede¢e pinove mikroupravlja£a ATmega32U4:

• kanal A rotacijskog enkodera spojen je na pin PD0 (INT0),

• kanal B rotacijskog enkodera spojen je na pin PD1 (INT1),

• tipkalo rotacijskog enkodera spojeno je na pin PF7.

U vjeºbi ¢emo prikazati na£ine rada enkodera i obradu signala u jednom kvadrantu, dvamakvadrantima i £etirima kvadrantima. U programskom kodu 12.1 prikazan je na£in rada enkoderau jednom kvadrantu. U ovom je na£inu rada na kanalu A potrebno detektirati rastu¢e bridove,a temeljem stanja signala na kanalu B odreuje se smjer vrtnje rotacijskog enkodera. S obziromna to da postoji potreba za detektiranjem rastu¢ih bridova signala na kanalu A koji je spojen napin PD0 (INT0), koristit ¢emo vanjski prekid INT0.

224 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

U programskom kodu 12.1 u funkciji inicijalizacija() vanjski prekid INT0 konguriranje tako da se prekidna rutina ISR(INT0_vect) poziva na rastu¢i brid signala na pinu INT0.Dodatno, globalno su omogu¢eni prekidi, konguriran je LCD displej te su za globalne objektetipa DigitalInput, koji su povezani s rotacijskim enkoderom, uklju£eni pritezni otpornici.

Na rastu¢i brid signala na kanalu A poziva se prekidna rutina ISR(INT0_vect). U prekidnojrutini nalazi se varijabla direction. Uloga ove varijable jest utvrditi smjer vrtnje rotacijskogenkodera. Varijabla direction mora imati vrijednost false za Smjer 2 (vrtnja u smjeru kazaljkena satu), odnosno vrijednost true za Smjer 1 (vrtnja u smjeru suprotnom od kazaljke na satu)(slika 12.2). Kada se pojavi rastu¢i brid na kanalu A i stanje kanala B jest 0, tada je smjer vrtnjejednak Smjeru 1, a varijabla direction imat ¢e vrijednost true. Kada se pojavi rastu¢i brid nakanalu A i stanje kanala B jest 1, tada je smjer vrtnje jednak Smjeru 2, a varijabla directionimat ¢e vrijednost false. Dakle, varijabla direction jednaka je invertiranom stanju kanala B.

Nakon ²to se odredi smjer vrtnje, poziva se funkcija encoder_inc_dec koja uve¢ava za jedanili smanjuje za jedan varijablu encoder_position. Ako varijabla direction ima vrijednostfalse, varijabla encoder_position uve¢ava se za jedan jer se rotacijski enkoder vrti usmjeru kazaljke na satu. U suprotnom se varijabla encoder_position smanjuje za jedan.Takoer, varijabla encoder_position ne moºe se uve¢ati iznad 100, niti smanjiti ispod 0,²to smo uvjetovali konstantama ENCODER_LOW_LEVEL i ENCODER_HIGH_LEVEL. Kada se obradipove¢avanje, odnosno smanjenje, varijable encoder_position, varijabla new_position poprimavrijednost true kako bismo u while petlji imali informaciju da je dostupna nova kutna pozicija ida ju je potrebno ispisati na LCD displej. Nova vrijednost varijable encoder_position ispisujese u prvom retku LCD displeja, a dodatno se u drugom retku LCD displeja ispisuje znak sASCII kodom 255 kojim se linearno popunjava drugi redak LCD displeja, u ovisnosti o varijabliencoder_position koja poprima vrijednosti iz intervala [0, 100]. U while petlji se vrijednostvarijable encoder_position postavlja na 0 kada se dogodi padaju¢i brid tipkala rotacijskogenkodera.

Prevedite datoteku vjezba1211.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Okre¢ite rotacijski enkoder u smjeru kazaljke na satu i u suprotnom smjeru te pratite kako sepove¢ava varijabla encoder_position. Pritisnite tipkalo rotacijskog enkodera. Za rotacijskienkoder koji se nalazi na razvojnom okruºenju na£in rada u jednom kvadrantu zapravo je inajbolje rje²enje. U nastavku ¢e biti pokazan na£in rada u dvama i £etirima kvadrantima kojisu vrlo vaºni kada se koriste opti£ki rotacijski enkoderi koje koristimo za pozicioniranje radnogstroja.

U programskom kodu 12.2 prikazani su prekidna rutina ISR(INT0_vect) i funkcijainicijalizacija() za na£in rada rotacijskog enkodera u dvama kvadrantima. Ovimprogramskim kodom potrebno je zamijeniti prekidnu rutinu ISR(INT0_vect) i funkcijuinicijalizacija() u datoteci vjezba1211.cpp. U ovom na£inu rada na kanalu A potrebnoje detektirati i rastu¢e i padaju¢e bridove. Smjer vrtnje rotacijskog enkodera dobit ¢e se natemelju stanja kanala A i stanja kanala B nakon ²to se pojavio rastu¢i odnosno padaju¢i bridsignala na kanalu A. S obzirom da postoji potreba za detektiranjem rastu¢ih i padaju¢ih bridovasignala na kanalu A koji je spojen na pin PD0 (INT0), koristit ¢emo vanjski prekid INT0.

Programski kod 12.2: Prekidna rutina ISR(INT0_vect) i funkcija inicijalizacija() za na£inrada rotacijskog enkodera u dvama kvadrantima

// dvokvadrantni na£in rada , INT0 - rastu¢i i padaju¢i brid

ISR(INT0_vect)

// direction = true - Smjer 1, direction = false - Smjer 2

bool direction;

direction = Encoder_ChannelA.state () ^ Encoder_ChannelB.state();

encoder_inc_dec(direction);

12.1 Rotacijski enkoder 225

void inicijalizacija ()

lcd_init (); // konfiguracije LCD displeja

int0_enable (); // omogu¢i INT0

int0_set_rising_falling_edge (); // oba brida generiraju prekid na INT0

// pritezni otpornici na ulazima za rotacijski enkoder

Encoder_ChannelA.pullup_on ();

Encoder_ChannelB.pullup_on ();

Encoder_PushButton.pullup_on ();

interrupt_enable ();

U programskom kodu 12.2 u funkciji inicijalizacija() vanjski prekid INT0 konguriranje tako da se prekidna rutina ISR(INT0_vect) poziva na oba brida signala (rastu¢i i padaju¢i)na pinu INT0. Ostale naredbe funkcije inicijalizacija() nisu promijenjene u odnosu naprogramski kod 12.1.

Na rastu¢i i padaju¢i brid signala na kanalu A poziva se prekidna rutina ISR(INT0_vect).U prekidnoj rutini ponovno se nalazi varijabla direction kojom se odreuje smjer vrtnjerotacijskog enkodera. Varijabla direction mora imati vrijednost false za Smjer 2 (vrtnjau smjeru kazaljke na satu), odnosno vrijednost true za Smjer 1 (vrtnja u smjeru suprotnomod kazaljke na satu) (slika 12.2). Ako se kreira kombinacijska tablica za varijablu direction,ovisno o stanju na kanalima A i B, primijetiti ¢ete da se varijabla direction moºe dobiti kaoex-ili funkcija stanja na kanalu A i kanalu B (vidi programski kod 12.2). Razlika u na£inu radau jednom i dvama kvadrantima samo je u kreiranju varijable direction.

Prevedite datoteku vjezba1211.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Okre¢ite rotacijski enkoder u smjeru kazaljke na satu i u suprotnom smjeru te pratite kako sepove¢ava varijabla encoder_position. Pritisnite tipkalo rotacijskog enkodera.

U programskom kodu 12.3 prikazane su prekidne rutine ISR(INT0_vect) i ISR(INT1_vect)te funkcija inicijalizacija() za na£in rada rotacijskog enkodera u £etirima kvadrantima.Ovim programskim kodom potrebno je zamijeniti prekidnu rutinu ISR(INT0_vect) i funkcijuinicijalizacija() u datoteci vjezba1211.cpp. U ovom na£inu rada na kanalu A i na kanaluB potrebno je detektirati i rastu¢e i padaju¢e bridove. Smjer vrtnje rotacijskog enkodera dobit¢e se na temelju stanja kanala A i stanja kanala B nakon ²to se pojavio rastu¢i odnosno padaju¢ibrid signala na kanalima A i B. S obzirom na to da postoji potreba za detektiranjem rastu¢ih ipadaju¢ih bridova signala na kanalu A koji je spojen na pin PD0 (INT0) i na kanalu B koji jespojen na pin PD1 (INT1), koristit ¢emo vanjske prekide INT0 i INT1.

Programski kod 12.3: Prekidne rutine ISR(INT0_vect) i ISR(INT1_vect) te funkcijainicijalizacija() za na£in rada rotacijskog enkodera u £etirima kvadrantima

// £etverokvadrantni na£in rada , INT0 i INT1 - rastu¢i i padaju¢i brid

ISR(INT0_vect)

// direction = true - Smjer 1, direction = false - Smjer 2

bool direction;

direction = Encoder_ChannelA.state () ^ Encoder_ChannelB.state();

encoder_inc_dec(direction);

ISR(INT1_vect)

// direction = true - Smjer 1, direction = false - Smjer 2

bool direction;

direction = !( Encoder_ChannelA.state () ^ Encoder_ChannelB.state());

encoder_inc_dec(direction);

226 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

void inicijalizacija ()

lcd_init (); // konfiguracije LCD displeja

int0_enable (); // omogu¢i INT0

int0_set_rising_falling_edge (); // oba brida generiraju prekid na INT0

int1_enable (); // omogu¢i INT1

int1_set_rising_falling_edge (); // oba brida generiraju prekid na INT1

// pritezni otpornici na ulazima za rotacijski enkoder

Encoder_ChannelA.pullup_on ();

Encoder_ChannelB.pullup_on ();

Encoder_PushButton.pullup_on ();

interrupt_enable ();

U programskom kodu 12.3 u funkciji inicijalizacija() vanjski prekidi INT0 i INT1kongurirani su tako da se prekidne rutine ISR(INT0_vect) i ISR(INT1_vect) pozivaju na obabrida signala (rastu¢i i padaju¢i). Ostale naredbe funkcije inicijalizacija() nisu promijenjeneu odnosu na programski kod 12.1.

Na rastu¢i i padaju¢i brid signala na kanalu A poziva se prekidna rutina ISR(INT0_vect),dok se na rastu¢i i padaju¢i brid signala na kanalu B poziva se prekidna rutina ISR(INT1_vect).U prekidnim rutinama nalazi se varijabla direction kojom se odreuje smjer vrtnje rotacijskogenkodera. Varijabla direction mora imati vrijednost false za Smjer 2 (vrtnja u smjeru kazaljkena satu), odnosno vrijednost true za Smjer 1 (vrtnja u smjeru suprotnom od kazaljke na satu)(slika 12.2).

Sada se kombinacijska tablica za varijablu direction u ovisnosti o stanjima na kanalu A ikanalu B mora kreirati za slu£aj kada se dogodi brid na kanalu A i za slu£aj kada se dogodibrid na kanalu B. Varijabla direction moºe se dobiti kao ex-ili funkcija stanja na kanalu A ikanalu B kada se pojavi brid na kanalu A (vidi programski kod 12.3). S druge strane, varijabladirection moºe se dobiti kao ex-nili funkcija (invertirana ex-ili) stanja na kanalu A i kanalu Bkada se pojavi brid na kanalu B (vidi programski kod 12.3).

Prevedite datoteku vjezba1211.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Okre¢ite rotacijski enkoder u smjeru kazaljke na satu i u suprotnom smjeru te pratite kako sepove¢ava varijabla encoder_position. Pritisnite tipkalo rotacijskog enkodera.

Zatvorite datoteku vjezba1211.cpp i onemogu¢ite prevoenje ove datoteke.

12.1.1 Zadatak - rotacijski enkoder

Zadatak 12.1.1

Napravite program kojim ¢ete pomo¢u rotacijskog enkodera zadavati referentnu vrijednost uintervalu od [0, 400] tako da se referentna vrijednost mijenja u koracima iznosa 4 (0, 4, 8,...,400). Tipkalom na rotacijskom enkoderu referentna vrijednost postavlja se na 200. U prvomretku LCD displeja potrebno je ispisati referentnu vrijednost, a drugi redak LCD displejapotrebno je popunjavati (simulirati loading) u ovisnosti o referentnoj vrijednosti. Shemaspajanja rotacijskog enkodera na mikroupravlja£ ATmega32U4 prikazana je na slici 12.1.

12.2 Tranzistor kao sklopka i relej 227

12.2 Tranzistor kao sklopka i relej

Bipolarni tranzistor kao sklopka £esto se koristi za uklju£enje i isklju£enje elektri£nih ureaja(tro²ila) frekvencijom ne ve¢om od 50 kHz. Za ve¢e frekvencije koristi se MOSFET tranzistor[4]. Iako se tranzistor kao sklopka £esto koristi, on ima i neke nedostatke:

• izlazni napon i struja tranzistora kao sklopke ograni£eni su,

• tranzistor kao sklopka na svom izlazu moºe uklopiti samo istosmjerni napon.

Ove probleme moºemo rije²iti pomo¢u releja. Releji su elektromehani£ke sklopke koje radena principu elektromagnetskog polja koje se javlja protjecanjem struje kroz zavojnicu releja.Elektromagnetsko polje uklapa ili isklapa metalnu kotvu te na taj na£in uklju£uje ili isklju£ujeelektri£ki ureaj (tro²ilo). Releji mogu uklopiti istosmjerni i izmjeni£ni napon te se mogudizajnirati za velike struje tro²ila. ivotni vijek releja ovisi o broju uklju£enja tro²ila, ²to mu je,uz malu frekvenciju rada, glavni nedostatak.

U nastavku ¢emo prikazati klasi£an primjer koji se koristi za uklju£enje i isklju£enjeizmjeni£nog tro²ila (u ovom slu£aju izmjeni£nog elektri£nog motora) pomo¢u mikroupravlja£a.Shema spajanja releja na mikroupravlja£ posredno pomo¢u tranzistora BC847 prikazana je naslici 12.3.

BC847

NPN

Relej

10 kΩ

Vcc

Motor

PD4 = 0

220V

50Hz

(a) Tranzistor u stanju zapiranja

BC847

NPN

Relej

10 kΩ

Vcc

Motor

PD4 = 1

220V

50Hz

(b) Tranzistor u stanju voenja

Slika 12.3: Shema spajanja releja na mikroupravlja£ posredno pomo¢u tranzistora BC847

Na slici 12.3 prikazan je bipolarni tranzistor koji kao tro²ilo uklju£uje i isklju£uje relej. Relejkao tro²ilo uklju£uje i isklju£uje izmjeni£ni motor. Pretpostavimo da je struja zavojnice releja(upravlja£ka struja) ve¢a od 40 mA. Tu struju ne moºe dati digitalni pin mikroupravlja£a pase kao posrednik u uklju£enju i isklju£enju releja koristi bipolarni tranzistor. Bazu tranzistorapotrebno je spojiti na digitalni pin mikroupravlja£a (na primjer pin PD4). Relej se postavlja ukolektorski krug tranzistora jer je s pozicije tranzistora relej tro²ilo. Paralelno s relejem potrebnoje spojiti diodu koja ²titi tranzistor od induciranog napona na zavojnici releja u trenutku njegovaisklju£enja. Pretpostavimo da je napon upravlja£kog kruga releja jednak Vcc (npr. Vcc = 5 V).

Kada na digitalni pin PD4 dovedemo nisko stanje (0 V), tranzistor ¢e biti u stanju zapiranja(slika 12.3a). U tom slu£aju kroz zavojnicu releja ne protje£e struja i relej je isklju£en. Ako jerelej isklju£en, prema slici 12.3a, izmjeni£ni je motor takoer isklju£en.

Kada na digitalni pin PD4 dovedemo visoko stanje (5 V), tranzistor ¢e biti u stanju voenja(slika 12.3b). U tom slu£aju kroz zavojnicu releja protje£e struja i relej je uklju£en. Ako je relejuklju£en, prema slici 12.3b, izmjeni£ni je motor takoer uklju£en

Ovaj primjer pokazuje nam da s malom upravlja£kom strujom moºemo upravljati velikomstrujom tro²ila. Shema spajanja bipolarnog tranzistora BC847 s relejem u kolektorskom kruguna mikroupravlja£ ATmega32U4 prikazana je na slici 12.4. Baza bipolarnog tranzistora BC847

228 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

spojena je na pin PD4 preko kratkospojnika JP5. Kratkospojnik je potrebno postaviti izmeutrnova 1 i 2. U kolektorskom krugu bipolarnog tranzistora BC847 nalazi se relej u paralelnomspoju s otpornikom i LED diodom koja svijetli kada je relej uklju£en. Relej na slici 12.4 ima trikontakta:

• NC (engl. Normally Closed) - kontakt koji je zatvoren sa zajedni£kim kontaktom kadarelej nije uklju£en,

• NO (engl. Normally Open) - kontakt koji je otvoren sa zajedni£kim kontaktom kada relejnije uklju£en,

• COM (engl. Common) - zajedni£ki kontakt.

+5V

GND

100n

10k

+5V

1uF

22p

22p

GND

10k BC847

GND

330

GND

+5V

+5V

+5V

ZF112

UGND

NC

COM

NO

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2

C12

C13

R50 T3

LED8

R51

134 2

S5

D1

21

K1

OS

P

K1

21

Q1

1 2 3

JP5

RESET

MISOMOSI

RXTX

TRIG

AREF

D-D+

VUSB

SCK

PD6

PC7

PE6

PD7

PC6

PF1PF0

SS

Slika 12.4: Shema spajanja bipolarnog tranzistora BC847 s relejem u kolektorskom krugu namikroupravlja£ ATmega32U4

Tro²ilo se na relej uvijek spaja izmeu kontakata NC i COM ili NO i COM, ovisno o logiciuklju£enja releja. Na primjer, ako je izmjeni£ni motor spojen izmeu kontakata NO i COM,tada ¢e izmjeni£ni motor biti uklju£en ako je na pinu PD4 visoko stanje (5 V). Ako je izmjeni£nimotor spojen izmeu kontakata NC i COM, tada ¢e izmjeni£ni motor biti uklju£en ako je napinu PD4 nisko stanje (0 V).

Vjeºba 12.2.1

Napravite program kojim ¢e se relej koji je spojen na pin PD4 uklju£ivati i isklju£ivati na sljede¢ina£in:

• relej se uklju£uje ako je tipkalo spojeno na pin PD0 bilo pritisnuto duºe od 5 s, a relej jeprethodno bio isklju£en,

• relej se isklju£uje ako je tipkalo spojeno na pin PD0 bilo pritisnuto duºe od 5 s, a relej jeprethodno bio uklju£en.

12.2 Tranzistor kao sklopka i relej 229

Shema spajanja bipolarnog tranzistora BC847 s relejem u kolektorskom krugu namikroupravlja£ ATmega32U4 prikazana je na slici 12.4.

U projektnom stablu otvorite datoteku vjezba1221.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1221.cpp. Po£etni sadrºaj datoteke vjezba1221.cpp prikazan je programskimkodom 12.4.

Programski kod 12.4: Po£etni sadrºaj datoteke vjezba1221.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "DigitalIO/DigitalIO.h"

int main(void)

// objekti za relej i tipkalo

DigitalOutput Relej(D4);

DigitalInput Tipkalo1(D0);

Tipkalo1.pullup_on ();

// pomo¢ne varijable kojima se prati vrijeme pritisnutog tipkala

uint16_t time_on = 0;

bool time_is_up = false;

while (1)

// ako je tipkalo pritisnuto i vrijeme od 5s nije isteklo

if(Tipkalo1.state() == false && !time_is_up)

time_on ++;

// kada se otpusti tipkalo

if(Tipkalo1.isRising_edge ())

time_is_up = false;

// ako je vrijeme ve¢e od 5s i relej je bio isklju£en

if(( time_on > 500) && (Relej.state() == false))

Relej.on();

time_is_up = true;

time_on = 0;

// ako je vrijeme ve¢e od 5s i relej je bio uklju£en

if(( time_on > 500) && (Relej.state() == true))

Relej.off();

time_is_up = true;

time_on = 0;

_delay_ms (10);

return 0;

Bipolarni tranzistor koji uklju£uje relej spojen je na pin PD4. Za potrebe upravljanja relejemstvoren je objekt Relej tipa DigitalOutput koji je povezan s pinom PD4. Uklju£ivanje relejaprovodit ¢e se tipkalom na pinu PD0, za ²to je stvoren objekt Tipkalo1 tipa DigitalInput.

U main() funkciji deklarirana je varijabla time_on koja se koristi za mjerenje isteka vremenai varijabla time_is_up koja detektira istek vremena. U while petlji ispituje se je li pritisnutotipkalo i je li vrijeme od zadanih 5 sekundi isteklo. U slu£aju zadovoljenja tih dvaju uvjeta,varijabla time_on uve¢ava se za 1. Ova varijabla uve¢ava se za 1 svakih 10 ms (ka²njenje uwhile petlji), ako je pritisnuto tipkalo i vrijeme od 5 s nije isteklo. Vrijeme iznosa 5 s iste¢i ¢ekada varijabla time_on poprimi iznos 500. Kada varijabla time_on dosegne vrijednost 500, tada:

• relej se uklju£uje ako je prethodno bio isklju£en,

230 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

• relej se isklju£uje ako je prethodno bio uklju£en.

Takoer, varijabla time_is_up poprima vrijednost true kako bi se zbog nastavljanja drºanjatipkala spojenog na pin PD0 sprije£ilo periodi£ko uklju£enje i isklju£enje releja. Ponovnapromjena stanja releja bit ¢e mogu¢a kada se tipkalo otpusti (na rastu¢i brid signala tipkala).

Prevedite datoteku vjezba1221.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£om ATmega32U4.Drºite tipkalo spojeno na pin PD0 najmanje 5 s. Istek vremena umjesto pomo¢u ka²njenja uwhile petlji moºe se mjeriti pomo¢u tajmera u normalnom na£inu rada. Kori²tenje tajmera zaistek vremena svakako je bolje rje²enje.

Zatvorite datoteku vjezba1221.cpp i onemogu¢ite prevoenje ove datoteke.

12.2.1 Zadatak - tranzistor kao sklopka i relej

Zadatak 12.2.1

Napravite program kojim ¢e se relej koji je spojen na pin PD4 uklju£ivati i isklju£ivati na sljede¢ina£in:

• relej se uklju£uje ako je tipkalo spojeno na pin PD1 bilo pritisnuto duºe od 8 s, a relej jeprethodno bio isklju£en,

• relej se isklju£uje ako je tipkalo spojeno na pin PD1 bilo pritisnuto duºe od 4 s, a relej jeprethodno bio uklju£en.

Shema spajanja bipolarnog tranzistora BC847 s relejem u kolektorskom krugu namikroupravlja£ ATmega32U4 prikazana je na slici 12.4.

12.3 Ultrazvu£ni senzor HC-SR04

Ultrazvu£ni senzor HC-SR04 koristi se za mjerenje udaljenosti u rasponu od 2 cm do 4 m,s precizno²¢u od 3 mm. Ovaj senzor ima zvu£nik koji ²alje ultrazvu£ne valove u prostor temikrofon koji prima reektirane ultrazvu£ne valove od prepreka u prostoru (slika 12.5).

Princip rada ultrazvu£nog senzora HC-SR04 prikazan je vremenskim dijagramom na slici 12.6[5]. Pomo¢u digitalnog pina mikroupravlja£a na ulazni pin Trig ultrazvu£nog senzora HC-SR04potrebno je poslati impuls ne kra¢i od 10 µs. Ovaj impuls sluºi za pokretanje mehanizmamjerenja ultrazvu£nog senzora HC-SR04. Zvu£nik ultrazvu£nog senzora HC-SR04 s oznakomT (engl. transmitter) u prostor ²alje ultrazvu£ni val, odnosno osam impulsa, frekvencijom 40kHz. Ultrazvu£ni val odbija se od prepreke i reektira na mikrofon s oznakom R (engl. receiver).Mikroupravlja£ koji se nalazi na ultrazvu£nom senzoru HC-SR04 obrauje reektirane valove tena izlazni pin Echo1 ultrazvu£nog senzora HC-SR04 generira impuls koji traje vrijeme tECHO.Vrijeme tECHO jednako je vremenu koje je potrebno ultrazvu£nom valu da od ultrazvu£nogsenzora HC-SR04 doe do prepreke i nazad, a potrebno ga je mjeriti pomo¢u mikroupravlja£a.

1Tip izlaza jest push-pull. Ovakav izlaz moºe se spojiti na ulaz mikroupravlja£a bez uklju£enja priteznogotpornika.

12.3 Ultrazvu£ni senzor HC-SR04 231

T

Prepreka

R

d

HC – SR04

Slika 12.5: Rasprostiranje ultrazvu£nog vala kroz prostor

Trig

T

Echo

t, [s]

8 impulsa frekvencija 40 kHz

impuls ne kraći od 10 μs

vrijeme da ultrazvučni val dođe od

senzora do prepreke i nazad

tECHO

t1 t2

t, [s]

t, [s]

Slika 12.6: Vremenski dijagram signala ultrazvu£nog senzora HC-SR04

Shema spajanja ultrazvu£nog senzora HC-SR04 na mikroupravlja£ ATmega32U4 prikazanaje na slici 12.7. Pin Trig ultrazvu£nog senzora HC-SR04 spojen je na pin mikroupravlja£a PD4preko kratkospojnika JP5 (kratkospojnik je potrebno postaviti izmeu trnova 2 i 3). Na pinmikroupravlja£a PE6 (INT6) spojen je pin Echo ultrazvu£nog senzora HC-SR04. Razlog tomujest to ²to se generirani signal na pinu Echo mora obraivati vanjskim prekidom. Povezivanjeultrazvu£nog senzora HC-SR04 s konektorom na razvojno okruºenje prikazano je na slici 12.8.Ultrazvu£ni senzor HC-SR04 nije sastavni dio razvojnog okruºenja na slici 3.1, ve¢ se spaja nadeniran konektor tako da su zvu£nik i mikrofon senzora okrenuti od plo£ice razvojnog okruºenja.

Udaljenost prepreke od ultrazvu£nog senzora HC-SR04 moºemo izra£unati pomo¢u relacije:

d =tECHO · vz

2, (12.1)

gdje je vz brzina zvuka u zraku koja iznosi 343 m/s na temperaturi od 20 C. Umnoºak tECHO ·vz u relaciji (12.1) dijeli se s 2 jer ultrazvu£ni val prevaljuje dvije udaljenosti od prepreke doultrazvu£nog senzora HC-SR04.

232 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

+5V

GND

100n

10k

+5V

1uF

GND

+5V22p

22p

GND

GND

+5V

+5V

UGND

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2

1234

HC-SR04

C12

C13

134 2

S5

21

Q1 1 2 3

JP5

RESET

MISOMOSI

RXTX

AREF

D-D+

VUSB

SCK

PD6

PC7

PE6

PD7

PC6

PF1PF0

RELEJ

SS

Slika 12.7: Shema spajanja ultrazvu£nog senzora HC-SR04 na mikroupravlja£ ATmega32U4

TR

HC

-SR

04

Vcc

Trig

Echo

GND

Slika 12.8: Povezivanje ultrazvu£nog senzora HC-SR04 s konektorom na razvojno okruºenje saslike 3.1

Ovisnost brzine zvuka u zraku o temperaturi zraka dana je relacijom:

vz = 331 + 0.6 · T, (12.2)

gdje je T temperatura zraka u C. Relacijom (12.2) moºe se napraviti korekcija brzine zvuka urelaciji (12.1) u ovisnosti o temperaturi zraka.

12.3 Ultrazvu£ni senzor HC-SR04 233

Vjeºba 12.3.1

Napravite program kojim ¢ete pomo¢u ultrazvu£nog senzora HC-SR04 mjeriti udaljenost doprepreke u prostoru sa i bez korekcije brzine zvuka. Mjerenu udaljenost prikaºite na LCDdispleju u centimetrima. Shema spajanja ultrazvu£nog senzora HC-SR04 na mikroupravlja£ATmega32U4 prikazana je na slici 12.7.

U projektnom stablu otvorite datoteku vjezba1231.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1231.cpp. Po£etni sadrºaj datoteke vjezba1231.cpp prikazan je programskimkodom 12.5.

Programski kod 12.5: Po£etni sadrºaj datoteke vjezba1231.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "LCD/lcd.h"

#include "Timer/timer.h"

#include "Interrupt/interrupt.h"

volatile uint32_t broj_impulsa = 0;

bool hcsr04_measured = false;

volatile bool hcsr04_triggered = false;

// prekidna rutina za INT6

ISR(INT6_vect)

// ako je brid rastuci

if(get_pin(PINE ,PE6) == 1)

TCNT1 = 0; // t1 = 0

else // ako je brid padajuci

broj_impulsa = TCNT1;

hcsr04_measured = true;

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

// inicijalizacija AD pretvorbe

// oba brida generiraju prekid INT6

int6_set_rising_falling_edge ();

int6_enable ();

// tajmer 1 u normalnom na£inu rada

timer1_set_normal_mode ();

timer1_set_prescaler(TIMER1_PRESCALER_8); //F_CPU /8

// konfiguracija pinova za hcsr04

output_port(DDRD ,PD4); // trigg pin (PD4) - izlazni pin

input_port(DDRE ,PE6); // echo pin (PE6) - ulazni pin

interrupt_enable (); // omogu¢i prekide

void hcsr04_trigg ()

set_port(PORTD , 4, 1);

_delay_us (20); // trigger impuls 20 us

set_port(PORTD , 4, 0);

hcsr04_triggered = true;

int main(void)

234 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

inicijalizacija ();

float d, d_cor; // udaljenost

float t_echo; // trajanje impulsa na Echo pinu

uint16_t time_delay = 0;

uint16_t ADC_4; // vrijednost AD pretvorbe na pinu ADC4

float T; // temperatura

float v_z; // brzina zvuka u zraku

while (1)

// ako nije poslan trigg i ako je istekla 1 s

if(! hcsr04_triggered && time_delay == 0)

hcsr04_trigg (); // po²alji trigg signal na hcsr04

// ako je mjerenje zavrseno

if(hcsr04_measured)

t_echo = broj_impulsa * 8.0 / F_CPU; // impuls Echo u s

v_z = 343.0; // brzina zvuka na 20 C

d = t_echo / 2.0 * v_z * 100.0; // udaljenost u cm

// napraviti dio programskog koda za korigiranu udaljenost

lcd_clrscr ();

lcd_home ();

lcd_print("d1 = %0.2f cm\n", d);

lcd_print("d2 = %0.2f cm", d_cor);

hcsr04_measured = false;

hcsr04_triggered = false;

_delay_ms (10);

// ako je prosla 1 s, vrati broja£ vremena na 0 s

if(++ time_delay > 100)

time_delay = 0;

Ulazni pin Trig ultrazvu£nog senzora HC-SR04 spojen je prema shemi na slici 12.7 na pinPD4. Na pinu PD4 generirat ¢emo impuls ne kra¢i od 10 µs koji pokre¢e mehanizam mjerenjaudaljenosti. U programskom kodu 12.5 za generiranje impulsa trajanja 20 µs na pinu Trig koristise funkcija hcsr04_trigg().

Proces mjerenja udaljenosti prepreke od ultrazvu£nog senzora HC-SR04 pokre¢emo pozivomfunkcije hcsr04_trigg() svaku sekundu. Ponovno na pametan na£in postavljamo ka²njenje uwhile petlju tako da petlja moºe brzo odreagirati na zahtjev za ispisom mjerenja. Ka²njenjepetlje je 10 ms, a funkciju hcsr04_trigg() pozivamo na svaku stotu iteraciju while petlje.

Impuls koji generira izlazni pin Echo ultrazvu£nog senzora HC-SR04 mjerit ¢emo pomo¢usklopa Timer/Counter1 u normalnom na£inu rada i vanjskog prekida na sljede¢i na£in:

• kada se pojavi rastu¢i brid signala na pinu Echo (slika 12.6), pokrenite mjerenje vremenapomo¢u tajmera postavljenjem po£etne vrijednosti registra TCNT1 na nulu,

• kada se pojavi padaju¢i brid signala na pinu Echo, pro£itajte vrijednost registra TCNT1 ispremite je u varijablu broj_impulsa,

• pomo¢u vrijednosti varijable broj_impulsa odredite vrijeme tECHO,

• udaljenost prepreke od ultrazvu£nog senzora HC-SR04 izra£unajte prema relaciji (12.1).

Trajanje jednog impulsa koji broji registar TCNT1 ovisi o djelitelju frekvencije radnog takta i

12.3 Ultrazvu£ni senzor HC-SR04 235

frekvenciji radnog takta, a moºe se izra£unati na sljede¢i na£in:

timpulsa =PRESCALER

F_CPU. (12.3)

Vrijeme trajanja impulsa na pinu Echo ultrazvu£nog senzora HC-SR04 moºemo izra£unatitako da ukupan broj impulsa koji je spremljen u varijablu broj_impulsa pomnoºimo s trajanjemjednog impulsa:

tECHO = broj_impulsa · timpulsa = broj_impulsaPRESCALER

F_CPU. (12.4)

Frekvencija radnog takta u na²em slu£aju iznosi 16 MHz, a za djelitelj frekvencije radnogtakta odabrat ¢emo 8. Uvrstimo sada navedene parametre u relaciju (12.4) kako bismo dobilitrajanje impulsa na pinu Echo:

tECHO = broj_impulsa8

16000000=

broj_impulsa

2000000. (12.5)

Temeljem izra£unatog vremena tECHO, udaljenost prepreke od ultrazvu£nog senzoraHC-SR04 moºe se izra£unati prema relaciji (12.1) uz konstantnu brzinu zvuka ili uz korekcijubrzine zvuka u ovisnosti o temperaturi koja se moºe dobiti relacijom (12.2). Udaljenost dobivenarelacijom (12.1) ima mjernu jedinicu m. Na² je zadatak prikazati udaljenost prepreke odultrazvu£nog senzora HC-SR04 u centimetrima pa ¢emo relaciju (12.1) pomnoºiti s konstantom100cm1m . Udaljenost prepreke od ultrazvu£nog senzora HC-SR04 u centimetrima bez korekcije

brzine zvuka moºe se dobiti prema relaciji:

d[cm] =tECHO

2· 343 · 100. (12.6)

Udaljenost prepreke od ultrazvu£nog senzora HC-SR04 u centimetrima s korekcijom brzinezvuka s obzirom na temperaturu zraka T moºe se dobiti prema relaciji:

d[cm] =tECHO

2· (331 + 0.6 · T ) · 100. (12.7)

U programskom kodu 12.5 u funkciji inicijalizacija() vanjski prekid INT6 konguriranje tako da se zahtjev za prekid generira na rastu¢i i padaju¢i brid signala. Za mjerenje vremenatECHO koristit ¢emo sklop Timer/Counter1 kao tajmer u normalnom na£inu rada. Djeliteljfrekvencije radnog takta postavljen je na vrijednost 8. U ovom slu£aju sklop Timer/Counter1ne treba generirati prekid prilikom preljeva u registru TCNT1 jer nam je potrebna samo informacijao broju impulsa u registru TCNT1. Takoer, u funkciji inicijalizacija() globalno su omogu¢eniprekidi te je pin PD4 konguriran kao izlazni, a pin PE6 (INT6) konguriran je kao ulazni pin.Pin Echo ultrazvu£nog senzora HC-SR04 izlazni je pin tipa push-pull pa nije potrebno uklju£itipritezni otpornik na pinu PE6.

Prekidna rutina ISR(INT6_vect) poziva se kod svakog padaju¢eg i rastu¢eg brida signalana pinu INT6 (PE6). Ako je brid signala na pinu INT6 (PE6) rastu¢i, to zna£i da je pripozivu prekidne rutine ISR(INT6_vect) stanje pina PE6 visoko. Ovu provjeru radimo pomo¢unaredbe if(get_pin(PINE,PE6)== 1). Ako je brid signala na pinu PE6 rastu¢i, po£etno stanjeregistra TCNT1 postavit ¢emo na nulu. Sljede¢i poziv prekidne rutine javit ¢e se pri padaju¢embridu na pinu INT6 (PE6). Kada se pojavi padaju¢i brid signala na pinu PE6, vrijednostregistra TCNT1 sprema se u varijablu broj_impulsa. U prekidnoj rutini ISR(INT6_vect) varijablahcsr04_measured postavlja se u vrijednost true kada je mjerenje vremena zavr²ilo. Ova varijablakoristi se u while petlji kako bi se izra£un udaljenosti i ispis udaljenosti provodio samo kada jedostupno novo mjerenje.

236 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

U while petlji udaljenost se zvu£nog senzora HC-SR04 od prepreke izra£unava u centimetrimapomo¢u relacija (12.5) i (12.6) te se na LCD displej ispisuje na dva decimalna mjesta. Brzinazvuka u ovom se slu£aju pretpostavlja konstantnom iznosa 343 m/s.

Programski kod 12.6 sluºi za mjerenje udaljenosti ultrazvu£nog senzora HC-SR04 od prepreke,uz korekciju brzine zvuka. Taj programski kod napi²ite u datoteku vjezba1231.cpp. Udaljenostultrazvu£nog senzora HC-SR04 od prepreke izra£unava se u centimetrima pomo¢u relacije (12.7),uz brzinu zvuka koja se izra£unava prema relaciji (12.2). Temperatura okoline mjeri se pomo¢uNTC otpornika, kako smo pokazali u vjeºbi 7.1.5. Zbog kori²tenja analogno-digitalne pretvorbe,potrebno je inicijalizirati AD pretvorbu i uklju£iti zaglavlje za AD pretvorbu.

Programski kod 12.6: Programski kod za mjerenje udaljenosti ultrazvu£nog senzora HC-SR04od prepreke korekcijom brzine zvuka

ADC_4 = adc_read(ADC4); // AD pretvorba na kanalu ADC4

// temperatura NTC otpornika

T = 3435 / (log(ADC_4 / (1023.0 - ADC_4)) + 10.861) - 273.15;

v_z = 331.0 + 0.6 * T; // brzina zvuka na temperaturi T

d_cor = t_echo / 2.0 * v_z * 100.0; // udaljenost u cm

Prevedite datoteku vjezba1231.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Usporedite udaljenosti od prepreka sa i bez korekcije brzine zvuka.

Zatvorite datoteku vjezba1231.cpp i onemogu¢ite prevoenje ove datoteke.

12.3.1 Zadatak - ultrazvu£ni senzor HC-SR04

Zadatak 12.3.1

Napravite program kojim ¢ete pomo¢u ultrazvu£nog senzora HC-SR04 mjeriti udaljenost doprepreke u prostoru s korekcijom brzine zvuka. Mjerenu udaljenost prikaºite na LCD displejuu mm. Uklju£enjem crvene LED diode signalizirajte da se prepreka od ultrazvu£nog senzoraHC-SR04 nalazi na udaljenosti manjoj od 100 mm. Shema spajanja ultrazvu£nog senzoraHC-SR04 na mikroupravlja£ ATmega32U4 prikazana je na slici 12.7.

12.4 Temperaturni senzor LM35

Temperaturni senzor LM35 visoko je precizni senzor temperature s mjernim opsegom od-55C do 150 C [6]. Ovaj senzor na izlaznom pinu Vout generira napon koji je proporcionalantemperaturi u okolini senzora s konstantom proporcionalnosti koja iznosi 10 mV/C, premarelaciji:

Vout = T · 10mVC

= T · 0, 01VC. (12.8)

Temperaturu iz relacije (12.8) moºemo izra£unati na sljede¢i na£in:

T = Vout · 100C

V. (12.9)

Na primjer, ako je izlazni napon temperaturnog senzora LM35 jednak 350 mV, temperaturau njegovoj okolini jest 35 C.

12.4 Temperaturni senzor LM35 237

Shema spajanja temperaturnog senzora LM35 na mikroupravlja£ ATmega32U4 prikazana jena slici 12.9. Ovaj na£in spajanja osnovni je i omogu¢uje mjerenje temperature u opsegu od 2C do 150 C, s konstantom proporcionalnosti koja iznosi 10 mV/C.

Pin Vout temperaturnog senzora LM35 moºe se spojiti na bilo koji analogni pinmikroupravlja£a ATmega32U4, a u na²em slu£aju spojen je na analogni pin ADC5 (PF5) prekokratkospojnika JP1 (kratkospojnik je potrebno spojiti izmeu trnova 1 i 2). Analogno-digitalnompretvorbom mjerimo napon na pinu Vout te pomo¢u relacije (12.9) izra£unamo temperaturu uokolini temperaturnog senzora LM35.

+5V

GND

100n

10k

+5V

1uF

+5V

GND

22p

22p

GND

GND

+5V

+5V

UGND

LM35CAZ

RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2POT1

C12

C13

134 2

S5

21

Q1

1 2 3

JP1

+VS1

GND3

VOUT 2

U1

RESET

MISOMOSI

RXTX

AREF

D-D+

VUSB

SCK

PD6

PC7

PE6

PD7

PC6

PF5

PF5

PF4PF1PF0

SS

Slika 12.9: Shema spajanja temperaturnog senzora LM35 na mikroupravlja£ ATmega32U4

Napon Vout temperaturnog senzora LM35 mjerit ¢emo pomo¢u analogno-digitalne pretvorbeprema sljede¢oj relaciji:

UADC5 =ADC5 · VREF

1023. (12.10)

Temperaturu T [C] temperaturnog senzora LM35 izra£unat ¢emo na sljede¢i na£in:

T = UADC5 · 100. (12.11)

Vjeºba 12.4.1

Napravite program kojim ¢ete pomo¢u temperaturnog senzora LM35 mjeriti temperaturuu njegovoj okolini. Mjerenu temperaturu prikaºite na LCD displeju u C. Shema spajanjatemperaturnog senzora LM35 na mikroupravlja£ ATmega32U4 prikazana je na slici 12.9.

U projektnom stablu otvorite datoteku vjezba1241.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1241.cpp. Po£etni sadrºaj datoteke vjezba1241.cpp prikazan je programskimkodom 12.7.

238 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

Programski kod 12.7: Po£etni sadrºaj datoteke vjezba1241.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "LCD/lcd.h"

#include "ADC/adc.h"

void inicijalizacija ()

// konfigurirajte ADC i LCD

int main(void)

inicijalizacija ();

uint16_t ADC_5; // vrijednost AD pretvorbe na pinu ADC5

float U_ADC5; // napon na pinu ADC5

const float V_REF = 5.0; // AVCC je referentni napon

float T; // temperatura u okolini senzora LM35

while (1)

ADC_5 = adc_read(ADC5);

// izra£unajte napon U_ADC5 i temperaturu T

lcd_clrscr ();

lcd_home ();

lcd_print("T = %0.2f%cC\n", T, 223);

_delay_ms (1000);

return 0;

U programskom kodu 12.7 u funkciji inicijalizacija() kongurirajte analogno-digitalnupretvorbu i LCD displej. U while petlji svakih se 1000 ms na LCD displeju ispisuje vrijednosttemperature u okolini temperaturnog senzora LM35. Za izra£unavanje napona na ADC5 pinu itemperature okoline temperaturnog senzora LM35 koristite relacije (12.10) i (12.11).

Prevedite datoteku vjezba1241.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba1241.cpp i onemogu¢ite prevoenje ove datoteke.

12.4.1 Zadatak - temperaturni senzor LM35

Zadatak 12.4.1

Napravite program kojim ¢ete pomo¢u temperaturnih senzora LM35 i NTC mjeriti temperaturuokoline. Mjerenu temperaturu prikaºite na LCD displeju u C. Shema spajanja temperaturnogsenzora LM35 na mikroupravlja£ ATmega32U4 prikazana je na slici 12.9, a shema spajanjatemperaturnog senzora NTC na mikroupravlja£ ATmega32U4 prikazana je na slici 7.1.

12.5 Servomotor 239

12.5 Servomotor

Servomotor je sustav koji se sastoji od istosmjernog motora, upravlja£ke elektronike kojasluºi za pozicioniranje izlazne osovine, prijenosnika snage koji okretanje rotora motora prenosina izlaznu osovinu i mjernog senzora pozicije (potenciometar, enkoder, ...). Dakle, servomotor jeistosmjerni motor koji je upravljan po poziciji. Servomotori manjih dimenzija (hobi servomotori)£esto se koriste u izradi prototipa robotskih ruku, robota inspiriranih prirodom, elemenatamobilnih robota koji se zakre¢u i sli£no. Za servomotore speci£ni su mala brzina okretanjai veliki moment na izlaznoj osovini [7]. Servomotor ima tri ºice (slika 12.10):

• smea ºica povezuje se na GND ili 0 V,

• crvena ºica povezuje se na VCC ili 5 V,

• naran£asta je ºica signalna ºica (signalna linija) i na nju se pomo¢u PWM signala ²aljereferentna vrijednost pozicije izlazne osovine.

Pozicioniranje servomotora provodi se pomo¢u periodi£kog signala (PWM signala) frekvencije50 Hz (period 20 ms). PWM signal (slika 12.11) koji se ²alje na servomotor generira se pomo¢umikroupravlja£a.

rina impulsa PWM signala odreuje zakret izlazne osovine. U pravilu bi pozicioniranjeservomotora trebalo funkcionirati na sljede¢i na£in (prema slici 12.11):

• ako ²irina PWM signala iznosi 1 ms (duty cycle iznosi 5 %), tada ¢e izlazna osovinaservomotora biti zakrenuta za 0,

• ako ²irina PWM signala iznosi 1,5 ms (duty cycle iznosi 7,5 %), tada ¢e izlazna osovinaservomotora biti zakrenuta za 90,

• ako ²irina PWM signala iznosi 2 ms (duty cycle iznosi 10 %), tada ¢e izlazna osovinaservomotora biti zakrenuta za 180.

PWM (PB5)

VCC (5 V)

GND (0 V)

Slika 12.10: Povezivanje servomotora s napajanjem i mikroupravlja£em

240 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

1 ms (0.5 ms)

1.5 ms

2 ms (2.5 ms)

20 ms

50 Hz

90°

180°

Slika 12.11: Pozicioniranje servomotora

irina impulsa za zakret izlazne osovine iznosa 0 i 180 £esto se razlikuje od ²irine impulsadenirane slikom 12.11. Naime, kod nekih proizvoa£a ²irina impulsa PWM signala za zakretizlazne osovine iznosa 0 iznosi oko 0,5 ms, a ²irina PWM signala za zakret izlazne osovine iznosa180 iznosi oko 2,5 ms. Iz tog je razloga vaºno testirati servomotor kako bi se utvrdila minimalnai maksimalna ²irina impulsa. irina impulsa TD [ms] za zadani zakret α moºe se za servomotorna slici 12.11 odrediti prema relaciji:

TD [ms] = 1 +1

180α [] (12.12)

irina PWM signala duty [%] za zadani zakret α moºe se odrediti prema relaciji:

duty [%] =TD

20ms= 5% +

5%

180α [] (12.13)

irina impulsa TD [ms] za zadani zakret α za servomotore koji se ne pona²aju prema slici12.11 moºe se odrediti relacijom:

TD [ms] = Tmin +Tmax − Tmin

180α [] (12.14)

gdje su:

• Tmin - ²irina impulsa za zakret izlazne osovine iznosa 0,

• Tmax - ²irina impulsa za zakret izlazne osovine iznosa 180.

irina PWM signala duty [%] za zadani zakret α moºe se odrediti prema relaciji:

duty [%] =TD

20ms= dutymin [%] +

dutymax [%]− dutymin [%]

180α [] (12.15)

gdje su:

• dutymin - ²irina impulsa PWM signala za zakret izlazne osovine iznosa 0,

12.5 Servomotor 241

• dutymax - ²irina impulsa PWM signala za zakret izlazne osovine iznosa 180.

Shema spajanja servomotora i potenciometra na mikroupravlja£ ATmega32U4 prikazana jena slici 12.12. Signalna linija servomotora (naran£asta ºica) spojena je na pin PB5 (OC1A) jerse na tom pinu moºe generirati PWM signal frekvencije 50 Hz.

programming connector

pinout Arduino LEONARDO

USB

napajanje

konektor_za_LCD_16x2

sedam segmentni displeji (CC)

TX/RX diode

HC-SR04

LM35

NTC

communication

USB to UART

relej

BUZZ

USB za CP2102

SPI connector

FDN304P

+5V

GND

100n

10k

+5V

GND

1uF

22R

22R

GND

MC33269ST-3.3T3

REG1117

+5V

GND

LMV358M

LMV358M

100n

10u-tantal10u-tantal

GND

GND

GND

GND GND

100n

GND

1k

GND

GND

+5V

74HC595D

GND

1k 1k

+5V +5V

GND

+5V

4k7

+5V

GND

GND

+5V

+5V

GND

330

330

330

330

330

330

330

330

74HC595D

GND

330

330

330

330

330

330

330

330

74HC595D

GND

330

330

330

330

330

330

330

330

74HC595D

GND

330

330

330

330

330

330

330

330

CP2102GND

100n1uF

GND

100n

22p

22p

GND

10kBC847

+5V

+5V

GND

330

GND

AL11P

GND

GND

+5V

+5V+5V

+5V

GND GND

GND

+5V

+5V

330

+5V

GND

+5V

GND

+5V

GND

100n

100n

100n

100n

ZF1122510-

GND

+5V

GND

+5V

UGND

22R

22R

10k

10k

GND

10u-tantal10k

GND

+5V

GND

+5V+5V

+5V+5V

EC12E_SW

EC12E_SW

GND GND

330330

GNDGND

100n

100n

GNDGND

+5V

100n

MKDSN1,5/3-5,08

LM35CAZ

10103594-0001LF 10103594-0001LF

+5V

ECHO -

VSSVDDV0RSRWE

D4D5D6D7AK

12345678

123456

12345678 1

23456789

10RESET13

VCC14

VCC234

GND15

GND223

GND335

GND443

AVCC24

AVCC244

XTAL117

XTAL216

UVCC2

D-3

D+4

UGND5

UCAP6

VBUS7

AREF 42

(SS/PCINT0)PB0 8

(PCINT1/SCLK)PB1 9

(PDI/PCINT2/MOSI)PB2 10

(PDO/PCINT3/MISO)PB3 11

(PCINT4/ADC11)PB4 28

(PCINT5/OC1A/OC4B/ADC12)PB5 29

(PCINT6/OC1B/OC4B/ADC13)PB6 30

(PCINT7/OC0A/OC1C/RTS)PB7 12

(OC3A/OC4A)PC6 31

(ICP3/CLK0/OC4A)PC7 32

(OSC0B/SCL/INT0)PD0 18

(SDA/INT1)PD1 19

(RXD1/INT2)PD2 20

(TXD1/INT3)PD3 21

(ICP1/ADC8)PD4 25

(XCK1/CTS)PD5 22

(T1/OC4D/ADC9)PD6 26

(T0/OC4D/ADC10)PD7 27

(HWB)PE2 33

(INT6/AIN0)PE6 1

(ADC0)PF0 41

(ADC1)PF1 40

(ADC4/TCK)PF4 39

(ADC5/TMS)PF5 38

(ADC6/TDO)PF6 37

(ADC7/TDI)PF7 36

ATMEGA32U4

C1

R1

C2

R6

R7

1

IN3 OUT 42

IC1

VIN3 VOUT 2

GN

D1

IC3

2

31

IC4A

84

6

57

IC4B

C3

C4C5

C8R10

123456789

10111213141516

LCD

QB 1

QC 2

QD 3

QE 4

QF 5

QG 6

QH 7

SCL10 SCK11

RCK12

G13

SER14 QA 15

QH* 9

CC

CC

dp

abcdefg10 9 2 6 7

3

41

5 8

DIS1

LED5 LED6

R11 R12

LED7

AE

S

1234

HC-SR04

12

NTC

123

SERVO

R17

R18

R19

R20

R21

R22

R23

R24

R25

QB 1

QC 2

QD 3

QE 4

QF 5

QG 6

QH 7

SCL10 SCK11

RCK12

G13

SER14 QA 15

QH* 9

CC

CC

dp

abcdefg10 9 2 6 7

3

41

5 8

DIS2

R26

R27

R28

R29

R30

R31

R32

R33

QB 1

QC 2

QD 3

QE 4

QF 5

QG 6

QH 7

SCL10 SCK11

RCK12

G13

SER14 QA 15

QH* 9

CC

CC

dp

abcdefg10 9 2 6 7

3

41

5 8

DIS3

R34

R35

R36

R37

R38

R39

R40

R41

QB 1

QC 2

QD 3

QE 4

QF 5

QG 6

QH 7

SCL10 SCK11

RCK12

G13

SER14 QA 15

QH* 9

CC

CC

dp

abcdefg10 9 2 6 7

3

41

5 8

DIS4

R42

R43

R44

R45

R46

R47

R48

R49

REGIN7

VDD6

GND3

VBUS8

D+4

D-5

RST 9

SUSPEND 12

SUSPEND 11

RI 2

DCD 1

DTR 28

DSR 27

TXD 26

RXD 25

RTS 24

CTS 23GNDEXP GNDM

IC8

1234

RX/TX

C9C10

C11

C12

C13

R50T3

D SG

T4

2 1F1

LED8

R51

+ -

SP1

134 2

S5

GN

DV

CC

816

IC2P

GN

DV

CC

816

IC5P

GN

DV

CC

816

IC6P

GN

DV

CC

816

IC7P

R56

D1

C16

C17

C18

C15

21

K1

OS

P

K1

21Q1

X1-1 X1-2

X1-3 X1-4

X1-5 X1-6

X1-7 X1-8

X1-9 X1-10

1 2 3

JP11

AE

SR14

1 2 3

JP4

1 3

2

X2

L2

R8

R9

123

JP3

123

JP5

R16

R15C6R57

123456

JP7

2 1F2

SW1

SW1

312

4 S1312

4 S2

R58R59

C7

C19

D3

C14X3-1

X3-2

X3-3

U1

+VS1

GND3

VOUT 2

J111

22

33

44

55

SHIELDS1*6

J511

22

33

44

55

SHIELDS1*6

AE

SR52

+5V

RESET

RESET

RESET

MISO

MISO

MOSI

MOSI

RX

RX

RX

RX

TX

TX

TX

TX

LM35

LM35 POT

POT

TRIG

AREF

AREF

D-

D-

D+

D+

VUSB

VUSB

VUSB

VUSB

VIN

VIN

+3,3

+3,3

+3,3

SCK

SCK

PB4PB5PB6PB7PD6

PD6

PD6

PC7

PC7

PC7

PC7

PD1

PD1

PD0

PD0

PE6

PE6

PE6

PD7

PD7

PD7

PC6

PC6

PC6

PD4

PF7PF6PF5PF4PF1

PF1

PF1

PF1 PF1

PF1 PF1

PF0

PF0

PF0

PF0

PF0

PF0

PF0

BUZZ

NTC

RELEJ

OE OE

OE OE

OE

UGND

USB-VCC

D1-

D1-

D1+

D1+

RX-CP2102

RX-CP2102

RX-CON

RX-CON

TX-CON

TX-CON

TX-CP2102

TX-CP2102

SS

SS

S1

RO1

S2

RO2 RO_SW

++

+

NCIOREF

3V35V

GNDGNDVIN

RESET

A0(PF7)A1(PF6)A2(PF5)A3(PF4)A4(PF1)A5(PF0)

RX(PD2)TX(PD3)2(PD1)~3(PD0)4(PD4)~5(PC6)~6(PD7)7(PE6)

8(PB4)~9(PB5)~10(PB6)~11(PB7)~12(PD6)~13(PC7)GNDAREFSDA(PD1)~SCL(PD0)

MOSI

RESET

SCK

MISO

GND

PB7PB6PB5PB4

PB5

Slika 12.12: Shema spajanja servomotora i potenciometra na mikroupravlja£ ATmega32U4

Potenciometar je spojen na pin ADC5 preko kratkospojnika JP11 na na£in da je kratkospojnikpostavljen izmeu trnova 2 i 3. Spajanje servomotora na razvojno okruºenje sa slike 3.1 prikazanoje na slici 12.13. Potrebno je voditi ra£una da se konektor servomotora ispravno okrene, kako jeprikazano na slici (vodite se bojama ºica).

Slika 12.13: Spajanje servomotora na razvojno okruºenje sa slike 3.1

Vjeºba 12.5.1

Napravite program kojim ¢ete:

• pomo¢u potenciometra upravljati zakretom izlazne osovine servomotora u rasponu od 0

do 180 te na temelju tih zakreta prona¢i minimalnu i maksimalnu ²irinu impulsa PWMsignala za zadane zakrete izlazne osovine,

242 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

• napraviti funkciju koja ¢e primati zakret izlazne osovine servomotora u rasponu od 0 do180 te odreivati ²irinu impulsa PWM signala za zadane zakrete,

• napraviti proizvoljno kontinuirano zakretanje izlazne osovine servomotora.

Shema spajanja servomotora i potenciometra na mikroupravlja£ ATmega32U4 prikazana je naslici 12.12.

U projektnom stablu otvorite datoteku vjezba1251.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1251.cpp. Po£etni sadrºaj datoteke vjezba1251.cpp prikazan je programskimkodom 12.8.

Programski kod 12.8: Po£etni sadrºaj datoteke vjezba1251.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "ADC/adc.h"

#include "Timer/timer.h"

#include "LCD/lcd.h"

#define DUTY_MIN 2.0 // ²irina PWM signala za kut 0

#define DUTY_MAX 12.5 // ²irina PWM signala za kut 180

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

adc_init (); // inicijalizacija AD pretvorbe

// timer 1 kao PWM 50 Hz

timer1_set_prescaler(TIMER1_PRESCALER_64);

timer1_set_phase_correct_PWM_ICR1 (2500);

timer1_OC1A_enable_non_inverted_PWM ();

DDRB |= (1 << PB5); // izlazni pin za servomotor (OC1A)

int main(void)

inicijalizacija ();

uint16_t ADC_5;

float duty , angle;

while (1)

ADC_5 = adc_read(ADC5); // AD pretvorba na pinu ADC5

// D = [2.0, 12.5] (0.4 ms - 2.5 ms)

duty = DUTY_MIN + (DUTY_MAX - DUTY_MIN) * ADC_5 / 1023.0;

// postavi duty cycle na kanalu OC1A

OC1A_set_duty_cycle(duty , PWM_ICR1);

lcd_clrscr ();

lcd_home ();

lcd_print("duty = %0.3f\n", duty);

_delay_ms (500);

return 0;

Prvi i osnovni cilj u ovoj vjeºbi jest osigurati generiranje PWM signala frekvencije 50 Hz.Signalna linija servomotora spojena je na pin PB5 (OC1A) koji kao alternativnu primjenuima generiranje PWM signala pomo¢u sklopa Timer/Counter1. Sklop Timer/Counter1 moºegenerirati PWM signal ºeljene frekvencije i u Fast PWM na£inu rada i u Phase Correct na£inu

12.5 Servomotor 243

rada. Vr²na vrijednost do koje registar TCNT1 broji u oba PWM na£ina rada pode²ava seregistrom ICR1. U ovoj vjeºbi koristit ¢emo Phase Correct na£in rada. Frekvencija PWM signalana pinu OC1A za Phase Correct na£in rada moºe se izra£unati prema sljede¢oj relaciji:

F_pcPWM =F_CPU

PRESCALER · (2 · PWM_ICR1)=

F_CPUPRESCALER · (2 · ICR1)

. (12.16)

Vrijednost registra ICR1 za zadanu frekvenciju moºe se iz relacije (12.16) izra£unati na sljede¢ina£in:

ICR1 =F_CPU

PRESCALER · 2 · F_pcPWM. (12.17)

Za pozicioniranje servomotora potrebno je generirati PWM signal frekvencije 50 Hz, pa ¢evrijednost registra ICR1 uz djelitelj frekvencije radnog takta iznosa 64 biti:

ICR1 =F_CPU

PRESCALER · 2 · F_pcPWM=

16000000

64 · 2 · 50= 2500. (12.18)

Postavljanje sklopa Timer/Counter1 u Phase Correct na£in rada te postavljanje vrijednostiregistra ICR1 na iznos 2500 provodi se funkcijom timer1_set_phase_correct_PWM_ICR1(2500).U programskom kodu 12.8 u funkciji inicijalizacija() kongurirani su analogno-digitalnapretvorba, LCD displej, sklop Timer/Counter1 u Phase Correct na£in rada te je pin PB5postavljen kao izlaz.

U while petlji postavlja se ²irina PWM signala za upravljanje pozicijom servomotora premarelaciji (12.15), uz izmjenu da je omjer α/180 zamijenjen omjerom ADC_5/1023.0. KonstanteDUTY_MIN i DUTY_MAX koriste se za odreivanje ²irine PWM signala kod zakreta izlazne osovineiznosa 0 i 180. Trenutne vrijednosti konstanti jesu:

• DUTY_MIN iznosi 2,0, ²to odgovara ²irini impulsa od 0,4 ms,

• DUTY_MAX znosi 12,5, ²to odgovara ²irini impulsa od 2,5 ms.

Prvi zadatak koji moramo napraviti jest utvrditi koja je minimalna (za 0), a koja maksimalna(za 180) ²irina impulsa PWM signala. Prevedite datoteku vjezba1251.cpp u strojni kodi snimite ga na mikroupravlja£ ATmega32U4. Testirajte program na razvojnom okruºenju smikroupravlja£em ATmega32U4. Pomo¢u potenciometra je potrebno zakrenuti izlaznu osovinuservomotora na 0. Na LCD displeju pro£itajte vrijednost ²irine impulsa PWM signala koju jepotrebno dodijeliti konstanti DUTY_MIN. Za servomotor koji je kori²ten pri testiranju ove vjeºbe,konstanta DUTY_MIN iznosi 2,38. Vrijednost 2,38 potrebno je dodijeliti konstanti DUTY_MIN uprogramskom kodu 12.8. Nakon toga je pomo¢u potenciometra potrebno zakrenuti izlaznuosovinu servomotora na 180. Na LCD displeju pro£itajte vrijednost ²irine impulsa PWM signalakoju je potrebno dodijeliti konstanti DUTY_MAX. Za servomotor koji je kori²ten pri testiranjuove vjeºbe konstanta DUTY_MAX iznosi 10,96. Vrijednost 10,96 potrebno je dodijeliti konstantiDUTY_MAX u programskom kodu 12.8. Bitno je razumjeti da ¢e ove konstante biti razli£ite zarazli£ite proizvoa£e servomotora.

irina impulsa za konstantu DUTY_MIN iznosa 2,38 jest 0,476 ms, a ²irina impulsa za konstantuDUTY_MAX iznosa 10,96 jest 2,192 ms. Moºemo primijetiti da se ove ²irine impulsa razlikuju od²irina deniranih slikom 12.11. Prevedite datoteku vjezba1251.cpp u strojni kod i snimite ga namikroupravlja£ ATmega32U4. Primijetite da sada puni opseg zakreta potenciometra odgovaraopsegu zakreta izlazne osovine servomotora od 0 do 180.

244 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

Sljede¢i korak jest napraviti funkciju koja ¢e primati zakret izlazne osovine servomotora urasponu od 0 do 180 te postaviti ²irinu impulsa PWM signala za zadane zakrete. Funkcija jeprikazana programskim kodom 12.9.

Programski kod 12.9: Funkcija za zakretanje izlazne osovine servomotora za ºeljeni kut

void set_servo_angle(float angle)

float duty = DUTY_MIN + (DUTY_MAX - DUTY_MIN) / 180 * angle;

OC1A_set_duty_cycle(duty , PWM_ICR1);

Dodajte programski kod 12.9 u datoteku vjezba1251.cpp. Funkcijaset_servo_angle(float angle) izra£unava i postavlja ²irinu PWM signala prema relaciji(12.15). U datoteci vjezba1251.cpp zamijenite while petlju programskim kodom 12.10. NaLCD displeju sada ispisujemo kut izlazne osovine, a potenciometrom zadajemo referentnuvrijednost kuta i ²aljemo ga u funkciju set_servo_angle(float angle).

Programski kod 12.10: Novi sadrºaj while petlje u datoteci vjezba1251.cpp

while (1)

ADC_5 = adc_read(ADC5); // AD pretvorba na pinu ADC5

angle = ADC_5 / 1023.0 * 180;

set_servo_angle(angle);

lcd_clrscr ();

lcd_home ();

lcd_print("kut = %0.2f%c\n", angle , 223);

_delay_ms (500);

Prevedite datoteku vjezba1251.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Potenciometrom zadajte referentnu vrijednost kuta iznosa 90. Iako bi se zakrettrebao linearno mijenjati promjenom ²irine impulsa, to ponekad nije tako. Primijetite da izlaznaosovina nije postigla kut od 90. Jedno od mogu¢ih rje²enja za smanjivanje odstupanja jestuvoenje nove konstante DUTY_MID koja ¢e imati vrijednost ²irine PWM impulsa za zakret izlazneosovine iznosa 90. Ovaj postupak zahtijeva vra¢anje korak unazad kako biste na LCD displejupro£itali kolika je ²irina impulsa PWM signala za zakret izlazne osovine iznosa 90. Za servomotorkoji je kori²ten pri testiranju ove vjeºbe konstanta DUTY_MID iznosi 6,037. Napravite konstantuDUTY_MID u datoteci vjezba1251.cpp te joj dodijelite vrijednost 6,037.

Sada se moºe napraviti nova funkcija za zakretanje izlazne osovine servomotora (programskikod 12.11). Promjena kuta sada je podijeljena u dva raspona: 0 do 90 i 90 do180. Dodajte programski kod 12.9 u datoteku vjezba1251.cpp. Zamijenite poziv funkcijeset_servo_angle(float angle) pozivom funkcije set_servo_angle_2(float angle).

Programski kod 12.11: Novi sadrºaj datoteke vjezba1251.cpp

void set_servo_angle_2(float angle)

float duty;

if(angle <= 90)

duty = DUTY_MIN + (DUTY_MID - DUTY_MIN) / 90 * angle;

else

duty = DUTY_MID + (DUTY_MAX - DUTY_MID) / 90 * (angle - 90);

OC1A_set_duty_cycle(duty , PWM_ICR1);

Prevedite datoteku vjezba1251.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Potenciometrom zadajte referentnu vrijednost kuta iznosa 90. Sada bi izlaznaosovina trebala posti¢i zakret iznosa 90.

12.5 Servomotor 245

Kona£no, sada moºemo napraviti proizvoljno kontinuirano zakretanje izlazne osovineservomotora. U datoteku vjezba1251.cpp napi²ite programski kod 12.12. Ovaj programskikod kontinuirano mijenja zakret osovine na sljede¢i na£in:

• na zakretu izlazne osovine iznosa 0 servomotor se zaustavlja u trajanju od 500 ms i mijenjamu se smjer vrtnje,

• kontinuirano se mijenja zakret izlazne osovine od 0 do 90,

• na zakretu izlazne osovine iznosa 90 servomotor se zaustavlja u trajanju od 500 ms,

• kontinuirano se mijenja zakret izlazne osovine od 90 do 180,

• na zakretu izlazne osovine iznosa 180 servomotor se zaustavlja u trajanju od 500 ms imijenja mu se smjer vrtnje,

• svi se koraci neprestano ponavljaju.

Programski kod 12.12: Novi sadrºaj datoteke vjezba1251.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "ADC/adc.h"

#include "Timer/timer.h"

#include "LCD/lcd.h"

#define DUTY_MIN 2.38 // ²irina PWM signala za kut 0

#define DUTY_MAX 10.96 // ²irina PWM signala za kut 180

#define DUTY_MID 6.037 // ²irina PWM signala za kut 90

void set_servo_angle_2(float angle)

float duty;

if(angle <= 90)

duty = DUTY_MIN + (DUTY_MID - DUTY_MIN) / 90 * angle;

else

duty = DUTY_MID + (DUTY_MAX - DUTY_MID) / 90 * (angle - 90);

OC1A_set_duty_cycle(duty , PWM_ICR1);

void set_servo_angle(float angle)

float duty = DUTY_MIN + (DUTY_MAX - DUTY_MIN) / 180 * angle;

OC1A_set_duty_cycle(duty , PWM_ICR1);

void inicijalizacija ()

lcd_init (); // inicijalizacija LCD displeja

adc_init (); // inicijalizacija AD pretvorbe

// timer 1 kao PWM 50 Hz

timer1_set_prescaler(TIMER1_PRESCALER_64);

timer1_set_phase_correct_PWM_ICR1 (2500);

timer1_OC1A_enable_non_inverted_PWM ();

DDRB |= (1 << PB5); // izlazni pin za servomotor (OC1A)

int main(void)

inicijalizacija ();

uint8_t i;

246 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

// direction = true - gibanje od 0 do 180

// direction = false - gibanje od 180 do 0

bool direction = true;

while (1)

// postavi zakret na servomotor

set_servo_angle_2(i);

// ako je zakret 0, pri£ekaj 500 ms i promijeni smjer

if(i == 0)

direction = true;

_delay_ms (500);

// ako je zakret 90, pri£ekaj 500 ms

if(i == 90) _delay_ms (500);

// ako je zakret 180, pri£ekaj 500 ms i promijeni smjer

if(i == 180)

direction = false;

_delay_ms (500);

// ako je direction = true pove¢avaj zakret , ina£e smanjuj

if(direction)

i++;

else

i--;

_delay_ms (10);

return 0;

Prevedite datoteku vjezba1251.cpp u strojni kod i snimite ga na mikroupravlja£ATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4.Napravite druga£iji obrazac pona²anja zakreta izlazne osovine servomotora i testirajte ga narazvojnom okruºenju s mikroupravlja£em ATmega32U4.

Zatvorite datoteku vjezba1251.cpp i onemogu¢ite prevoenje ove datoteke.

12.5.1 Zadatak - servomotor

Zadatak 12.5.1

Napravite program kojim ¢ete zakretom izlazne osovine servomotora upravljati aplikacijomsa slike 10.4 pomo¢u kliza£a Slider. Shema spajanja servomotora i potenciometra namikroupravlja£ ATmega32U4 prikazana je na slici 12.12.

12.6 RGB dioda

RGB dioda sastoji se od triju LED dioda u jednom ku¢i²tu (slika 12.14). Naziv RGB dolazi odcrvene (R), zelene (G) i plave (B) LED diode koje se nalaze u zajedni£kom ku¢i²tu. Mije²anjemovih triju boja u razli£itim intenzitetima mogu se dobiti sve mogu¢e boje. Intezitet pojedineLED diode moºe se mijenjati PWM signalom na svakoj od anoda RGB diode. Ako sve diodesvijetle punim intenzitetom, svjetlost koju ¢e davati RGB dioda bit ¢e bijela. RGB dioda sa slike12.14 jest dioda sa zajedni£kom katodom.

12.6 RGB dioda 247

R

G

BR

GB

0 V

0 V

Slika 12.14: RGB dioda

Shema spajanja RGB diode na mikroupravlja£ ATmega32U4 prikazana je na slici 4.1.Kratkospojnik JP4 potrebno je postaviti izmeu trnova 2 i 3.

Vjeºba 12.6.1

Napravite program kojim ¢ete pomo¢u aplikacije sa slike 10.4 mijenjati intenzitet RGB diodepomo¢u kliza£a R, G i B u okviru Sliders. Pritiskom na tipku Send RGB aplikacija ¢e pomo¢userijskog porta poslati poruku formata "R%u;%u;%u*\r", pri £emu kvalikatori "%u" poprimajuvrijednosti u rasponu [0, 100], a predstavljaju ²irinu impulsa PWM signala koji upravljajuintenzitetom R, G i B LED diode. Crvena (R) LED dioda spojena je na OC1A pin, zelena (G)LED dioda spojena je na OC1B pin, a plava (B) LED dioda spojena je na OC1C pin. Ako je namikroupravlja£ pristigla poruka "R50;0;90*\r", tada ¢e ²irina impulsa PWM signala na pinuOC1A biti 50 %, na pinu OC1B 0 %, a na pinu OC1C 90 %.

U projektnom stablu otvorite datoteku vjezba1261.cpp. Omogu¢ite samo prevoenjedatoteke vjezba1261.cpp. Po£etni sadrºaj datoteke vjezba1261.cpp prikazan je programskimkodom 12.13.

Programski kod 12.13: Po£etni sadrºaj datoteke vjezba1261.cpp

#include <avr/io.h>

#include "AVR VUB/avrvub.h"

#include <util/delay.h>

#include "LCD/lcd.h"

#include "uart/uart.h"

#include "Interrupt/interrupt.h"

#include "Timer/timer.h"

void inicijalizacija ()

lcd_init (); // konfiguracija LCD displeja

uart_init (19200); // UART konfiguracija

// tajmer 1 u Phase Correct na£inu rada

timer1_set_prescaler(TIMER1_PRESCALER_64);

timer1_set_phase_correct_PWM_8bit ();

// neinvertiraju¢i PWM na kanalima OC1A , OC1B i OC1C

timer1_OC1A_enable_non_inverted_PWM ();

timer1_OC1B_enable_non_inverted_PWM ();

timer1_OC1C_enable_non_inverted_PWM ();

// izlazni pinovi PB5 (R), PB6 (G), PB7 (B)

DDRB |= (1 << PB5) | (1 << PB6) | (1 << PB7);

interrupt_enable ();

int main(void)

248 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

inicijalizacija ();

uint8_t RGB[3] = 0, 0, 0;

while (1)

if(uart_read_all ())

lcd_clrscr ();

lcd_home ();

lcd_print("%s\n", uart_buffer);

if(uart_buffer [0] == 'R')

RGB [0] = 0;

RGB [1] = 0;

RGB [2] = 0;

// £itanje poruke tipa R26 ;14;88*

for(uint8_t i = 1, j = 0; uart_buffer[i] != '*'; i++)

if (uart_buffer[i] != ';')

RGB[j] = RGB[j] * 10 + (uart_buffer[i] - 48);

else

j++;

// postavite ²irine PWM impulsa na pinovima OC1A , OC1B i OC1C

OC1A_set_duty_cycle(RGB[0], PWM_8BIT);

OC1B_set_duty_cycle(RGB[1], PWM_8BIT);

OC1C_set_duty_cycle(RGB[2], PWM_8BIT);

// ispis pojedinih ²irina impulsa

lcd_print("%u %u %u *", RGB[0], RGB[1], RGB [2]);

U programskom kodu 12.13 u funkciji inicijalizacija() kongurirani su LCD displej iserijska komunikacija. S obzirom na to da je crvena (R) LED dioda spojena na OC1A pin,zelena (G) LED dioda na OC1B pin, a plava (B) LED dioda na OC1C pin, na ovim je pinovimapotrebno generirati PWM signal. Koristiti ¢emo sklop Timer/Counter1 u Phase Correct na£inurada s djeliteljem frekvencije radnoga takta iznosa 64. Na pinovima OC1A, OC1B i OC1Comogu¢eni su neinvertirani PWM signali. Takoer, pinovi OC1A (PB5), OC1B (PB6) i OC1C(PB7) postavljeni su kao izlazni pinovi.

U main() funkciji deklarirano je polje podataka RGB s trima elementa. Svaki elementpolja predstavljat ¢e ²irinu impulsa PWM signala u rasponu [0, 100]. U while petlji £eka sepristigla poruka u meuspremnik uart_buffer. Kada poruka doe, iz nje je potrebno izvu¢ivrijednosti intenziteta pojedine LED diode. Prvi znak u poruci jest 'R'. Sljede¢i dio porukedo znaka ';' jest ²irina impulsa PWM signala za crvenu LED diodu. Kroz pristiglu porukuprolazimo pomo¢u for petlje koja pretvara niz znakova koji predstavljaju ²irinu impulsa PWMsignala u cijeli broj. Kada for petlja naie na znak ';', tada znamo da nakon ovog znakastiºe sljede¢a ²irina impulsa PWM signala za zelenu LED diodu. Na isti na£in dolazimo i do²irine PWM signala za plavu LED diodu. Kada se odrede sve ²irine impulsa PWM signalaza pinove OC1A, OC1B i OC1C, funkcijama OC1A_set_duty_cycle(RGB[0], PWM_8BIT),OC1B_set_duty_cycle(RGB[1], PWM_8BIT), i OC1C_set_duty_cycle(RGB[2], PWM_8BIT)postavljamo ²irinu impulsa PWM signala na pinove OC1A, OC1B i OC1C.

Prevedite datoteku vjezba1261.cpp u strojni kod i snimite ga na mikrokontrolerATmega32U4. Testirajte program na razvojnom okruºenju s mikroupravlja£em ATmega32U4pomo¢u aplikacije sa slike 10.4. Namjestite parametre serijske komunikacije za COM Port nakojem se nalazi CP2102 pomo¢u prozora sa slike 10.5 te otvorite serijski port klikom mi²a na

12.6 RGB dioda 249

tipku Start COM. Namjestite kliza£e R, G i B u okviru Sliders na ºeljene vrijednosti i pritisnitetipku Send RGB.

Zatvorite datoteku vjezba1261.cpp i onemogu¢ite prevoenje ove datoteke. Zatvoriteprogramsko razvojno okruºenje Atmel Studio 7.

12.6.1 Zadatak - RGB dioda

Zadatak 12.6.1

Napravite program kojim ¢ete pomo¢u aplikacije sa slike 10.4 mijenjati intenzitet RGB diodepomo¢u poruke formata "RGB%u*%u*%u:\r", pri £emu kvalikatori "%u" poprimaju vrijednostiu rasponu [0, 200], a predstavljaju ²irinu impulsa PWM signala koji upravljaju intenzitetomR, G i B LED diode. Poruka se unosi pomo¢u tekstualnog okvira Message i pritiskom natipku Send. Crvena (R) LED dioda spojena je na OC1A pin, zelena (G) LED dioda spojenaje na OC1B pin, a plava (B) LED dioda spojena je na OC1C pin. Ako je na mikroupravlja£pristigla poruka "RGB40*80*180:\r", tada ¢e ²irina impulsa PWM signala na pinu OC1A biti20 %, na pinu OC1B 40 %, a na pinu OC1C 90 %. Za generiranje PWM signala koristite sklopTimer/Counter1 u Fast na£inu rada.

250 Povezivanje odabranih elektroni£kih modula na mikroupravlja£

Bibliograja

[1] Atmel, ATmega16U4/ATmega32U4: 8-bit Microcontroller with16/32K bytes of ISP Flash and USB Controller. Microchip,https://www.microchip.com/wwwproducts/en/ATmega32u4, 2016.

[2] XIAMAN OCULAR, www.elmicro.com/les/lcd/gdm1602a_datasheet.pdf, Specication ofLCD Module GDM1602A, 2005.

[3] Z. Vrhovski, Predavanja iz kolegija MIKRORAUNALA. Veleu£ili²te u Bjelovaru, Bjelovar,2020.

[4] G. Gridling and B. Weiss, Introduction to Microcontrollers. Vienna University of Technology,Institute of Computer Engineering, Vienna, 2007.

[5] ELEC Freaks, http://www.elecfreaks.com/store/download/product/Sensor/HC-SR04/HC-SR04_Ultrasonic_Module_User_Guide.pdf, HC-SR04 User Guide, 2013.

[6] TEXAS INSTRUMENTS, http://www.ti.com/lit/ds/symlink/lm35.pdf, LM35 PrecisionCentigrade Temperature Sensors, 2013.

[7] How to Mechatronics, https://howtomechatronics.com/how-it-works/how-servo-motors-work-how-to-control-servos-using-arduino/, How Servo Motor Works & How To Control Servosusing Arduino, 2018.

252 BIBLIOGRAFIJA