31. januarja, 2010

Kratka šola programiranja mikrokontrolerjev

Opazili boste, da smo na začetku programa definirali, katera vrata bodo vhodna oziroma izhodna. Nato smo na PORTB vpisali vrednost 255, kar je binarno 1111 1111. To smo naredili zato, da vse LEDice ugasnemo. Zdaj že poznamo Do-Loop zanko, v kateri se nahaja IF ELSE stavek. Program je jasen: v kolikor bo logično stanje na priključku Portd.0 = 0 potem se izvede prvi del IF stavka, v nasprotnem primeru pa drugi.

 

Pozorni bralci ste opazili neskladje med zadnjim stavkom in programom. V programu je zapisano If Pind.0=0, mi smo pa zapisali, če bo stanje na priključku Portd.0=0. Oboje je prav in začetnikom v programiranju sprva dela malce težav. Tukaj bo pomagalo nekaj znanja o notranji zgradbi AVR mikrokontrolerjev. AVRji imajo 3 registre, ki so vezani na posamezni priključek. Obstajajo PORTx, PINx in DDRx registri. DDRx register je namenjen temu, da AVR-ju določimo ali bo določeni priključek vhodni ali izhodni. V kolikor postavimo DDRx na 0, bo določen priključek definiran kot vhodni, če postavimo DDRx na 1, bo taisti priključek izhodni.

Slike PZBA PZBA 11i - Kratka šola programiranja mikrokontrolerjev

KLIK za povečavo

Slike PZBA PZBA 11j - Kratka šola programiranja mikrokontrolerjev

KLIK za povečavo

V PORTx register vpišemo vrednost na posameznem priključku, medtem ko iz PINx registra beremo vrednost na posameznem priključku, ki je na shemi označen kot Portx.y. Če bi namesto pisanega stavka If Pind.0=0 napisali If Portd.0=0, bi pravzaprav brali vrednost, ki smo jo nazadnje vpisali na Portd.0. Avtor Bascoma nam je definicijo priključkov poenostavil z ukazom CONFIG, kjer definiramo ali je posamezni priključek vhod ali izhod, kot je razvidno v programu.

Ko boste omenjeni program prevedli in z njim sprogramirali mikrokontroler, boste videli, da sprva utripa LEDica na priključku PortB.1. Če pritisnemo tipko SW1, bo začela utripati LEDica na PortB.0. Pri tem boste verjetno opazili, da se v primeru, da pritisnemo tipko ko je vklopljena LEDica, le-ta ne ugasne. Razlog za to je v tem, da moramo mikrokontrolerju za vsak trenutek njegovega delovanja definirati program zelo natančno. Zgoraj opisani program namreč postavi logične enice na začetku programa (Portb = 255). V nadaljevanju programa pa tega ne naredimo več. Zato bi kazalo, da bo program popravili tako, da bi logične enice vpisali v Do-Loop zanki, kot kaže naslednji program.

Config Portb = Output
Config Portd.0 = Input
Dim Ledica As Bit
Dim Tipka As Bit
$regfile = "attiny2313.dat"
Do
Portb = 255
If Pind.0 = 0 Then
   Portb.0 = Ledica
   Ledica = Not Ledica
   Wait 1
   Else
   Portb.1 = Ledica
   Ledica = Not Ledica
   Wait 1
End If
Loop
Slike PZBA PZBA 11k - Kratka šola programiranja mikrokontrolerjev

KLIK za povečavo

Slike PZBA PZBA 11l - Kratka šola programiranja mikrokontrolerjev

KLIK za povečavo

Kot smo opazili nam program lepo deluje, vendar se v tem lepem delovanju skriva past, ki jo elektroniki poznamo pod besedo odskakovanje. Kaj mislim s tem? Vsaka tipka ali stikalo nista idealna, kar se odraža v odskakovanju kontakta. To pomeni, da stikalo ne preklopi iz logične 1 v 0 v trenutku pač pa je vmes veliko preskakovanja iz 1 v 0 in obratno. Tega odskakovanja ponavadi ne zaznamo, saj današnje naprave s programsko opremo ta efekt uspešno preprečujejo. V našem primeru je program tako napisan, da ignorira odskakovanje. V kolikor pa bi napisali malce drugačen program bi ugotovili, da stik na tipkah prav neprijetno odskakuje, kar mikrokontroler z lahkoto zazna. In to odskakovanje lahko povzroči zaplete pri naši napravah. Zato so programerji izumili način, ki preprečuje neželeno zaznavanje odskakovanja. Ponavadi se odskakovanje programsko reši tako, da program spremlja stanje tipke v določenem časovnem intervalu – npr 100 milisekund. V kolikor program ugotovi, da je tipka v npr. 100 milisekundah res pritisnjena, potem je to znak, da je stikalo res preklopilo. V Bascomu bomo to elegantno rešili z uporabo ukaza Debounce. Sintaksa ukaza debounce je sledeča:

Debounce Pinx.y, stanje, ime subrutine, sub

Tags: