Asistent

Osnove
mikroprocesorskih
sistemov


Računalniško
načrtovanje vezij II
  Laboratorijske vaje
    Samostojni zagon
Inicializacija
mikrokrmilnika

Časovnik
Zunanje prekinitve
Prekinitve
Ura realnega časa in
zapis v pomnilnik flash

A/D in D/A pretvorba
Asinhrona zaporedna komunikacija
Vodilo I2C

Mikroprocesorji
v elektroniki

Zunanje prekinitve

Besedilo vaje: Izdelajte program, ki bo štel število impulzov dveh pravokotnih zunanjih signalov. Vsak impulz prvega signala naj števec poveča za ena, impulz drugega signala pa naj ga zmanjša za ena. Trenutno stanje števca prikazujte na prikazovalniku LCD. Za generiranje obeh pravokotnih signalov uporabite tipki T0 in T1. Tako bo program prišteval pritiske tipke T0 in odšteval pritiske tipke T1.

Razlaga: Program napišete v razvojnem okolju, ki teče na osebnem računalniku. Pripravljen delovni prostor (angl. workspace) z vsemi pripadajočimi datotekami najdete tukaj. Opis datotek, ki se nahajajo v paketu, najdete v uvodu razlage prve vaje (samostojni zagon), datoteka vic.c pa je opisana v tretji vaji (časovnik). Dodani sta datoteki extint.c in extint.h, kjer se nahaja koda za nastavljanje zahtev po zunanjih prekinitvah. Lastno kodo, ki izvaja to vajo, dodate v datoteko main.c, kjer se nahaja tudi prazna definicija funkcije main(). Najprej morate mikrokrmilnik inicializirati, kar naredite s klicem funkcije init() v funkciji start_up() v datoteki startup.c. Za njeno uporabo morate vključiti datoteko init.h. Opis funkcije init() prav tako najdete v razlagi prve vaje (samostojni zagon). Pri tej vaji ne potrebujemo nobenega izhodnega pina. Tako ob inicializaciji vse pine vrat port0 definiramo kot vhodne.

Za štetje dveh vlakov impulzov moramo dva pina vrat port0 določiti kot vhodna pina za zunanje prekinitve. Podrobnejšo razlago, katere pine je mogoče uporabiti v ta namen, najdete v skripti. Pri tem bodite posebej pazljivi pri pinih p0.9, p0.16 in p0.20 (na starejših Šarmih z zaporedno številko manjšo od 50000 tudi pri pinu p0.1). Pin p0.9 je mogoče definirati kot vhodni pin za zunanje prekinitve, vendar na učnem razvojnem sistemu Šarm temu ni povsem tako. Z električne sheme lahko razberemo, da je omenjeni pin zvezan na izhod prilagodilnika nivojev MAX232. Zaradi tega lahko zunanje prekinitve na omenjenem pinu zahteva le prilagodilnik nivojev MAX232. Podobno velja za pina p0.16 in p0.20, ki ju uporablja prikazovalnik LCD.

Pine določimo za vhode zunanjih prekinitev s pomočjo funkcije extint_init(), ki je že napisana v datoteki extint.c. Funkcijo extint_init() kličemo iz funkcije start_up(), kjer so zbrane vse inicializacije. Za njeno uporabo morate vključiti datoteko extint.h. Deklaracija funkcije extint_init() je naslednja:

  void extint_init(int pins, int wake, int sensitivity, int trig);

Argumenti funkcije extint_init() podajajo nastavitve zunanjih prekinitev:

   - pins ... maska s konfiguracijo pinov uporabljenih za zunanje prekinite (možna je poljubna kombinacija zastavic:
   P0_1_EINT0 ... prekinitev EINT0 na pinu p0.1,
P0_3_EINT1 ... prekinitev EINT1 na pinu p0.3,
P0_7_EINT2 ... prekinitev EINT2 na pinu p0.7,
P0_9_EINT3 ... prekinitev EINT3 na pinu p0.9,
P0_14_EINT1 ... prekinitev EINT1 na pinu p0.14,
P0_15_EINT2 ... prekinitev EINT2 na pinu p0.15,
P0_16_EINT0 ... prekinitev EINT0 na pinu p0.16,
P0_20_EINT3 ... prekinitev EINT3 na pinu p0.20 in
P0_30_EINT3 ... prekinitev EINT3 na pinu p0.30.),
- wake ... maska omogočenih dvigov procesorskega jedra (možna je poljubna kombinacija zastavic EXTWAKEi, ki omogočijo dvig procesorskega jedra iz ustavljenega stanja ob zahtevi EINTi, i = 0, 1, 2, ali 3),
- sensitivity ... maska frontno proženih zunanjih prekinitev (možna je poljubna kombinacija zastavic EXTMODEi, ki namesto privzetega proženja s stanjem nastavijo frontno proženje prekinitve EINTi, i = 0, 1, 2, ali 3) in
- trig ... maska zunanjih prekinitev proženih z visokim stanjem, oziroma naraščajočo fronto, odvisno od argumenta sensitivity (možna je poljubna kombinacija zastavic EXTPOLARi, ki namesto privzetega proženja z nizkim stanjem/padajočo fronto nastavijo proženje prekinitve EINTi z visokim stanjem/naraščajočo fronto, i = 0, 1, 2, ali 3).

Izbrani zunanji prekinitvi bosta prožili tipki T0 in T1, ki sta vezani na pina p0.12 in p0.13. Ob pritisku tipke napetost pade iz visokega v nizko stanje. Zato moramo zunanji prekinitvi nastaviti tako, da sta proženi s padajočo fronto. Vhodna pina zunanjih prekinitev moramo s tipkama seveda povezati z žicama.

Preostane nam še postavitev vektorskega nadzornika prekinitev, kar naredimo s klicem funkcije vic_init(). Opis funkcije vic_init() najdete v razlagi tretje vaje (časovnik). Nastavimo ga tako, da izbrani zunanji prekinitvi ob postavitvi zahteve tudi dejansko sprožita vsaka svojo prekinitev. V ta namen potrebujemo dve prekinitveni funkciji, ki pripadata vsaka svoji prekinitvi. Pritiski na tipko T0 bodo povzročili izvršitev prve, pritiski na T1 pa druge funkcije. Algoritma obeh funkcij prikazuje slika spodaj. S tem je glavni program, ki pravzaprav vsebuje le nastavitve, zaključen. Končamo ga z neskončno zanko.

Obe prekinitveni funkciji sta sila preprosti. Prva poveča in prikaže trenutno vrednost števca, druga ga zmanjša in ravno tako prikaže. Števec mora biti globalna spremenljivka, tako da je v obeh funkcijah viden. Za prikaz na prikazovalniku LCD uporabimo gonilnik lcd_driver_1(), ki smo ga spoznali že v prvi vaji (samostojni zagon). Gonilnik je priložen v datoteki main.c. Ob vsakem klicu na prikazovalnik LCD izpiše vsebino niza, na katerega kaže globalni kazalec lcd_string. V obeh funkcijah je potrebno v ta namen narediti niz s trenutno vrednostjo števca.

Z izvršitvijo funkcije je trenutna zahteva po zunanji prekinitvi obdelana, zato jo umaknemo. V našem primeru to storimo z vpisom ene izmed v naprej definiranih konstant EINTi (glej datoteko extint.h) v register EXTINT. Podrobnejšo razlago najdete v skripti.