Softver

Autor: Dragan Golubović, dipl. ing.

 

rangr@eunet.yu

Klase u ARB51

Treći nastavak iz serije o objektno orijentisanom progra-mskom interfejsu – ARB 8051 biće posvećen realno naj-interesantnijem i najmoćnijem svojstvu ove biblioteke, a to je mogućnost formiranja sopstvenih objekata i sopstvene programske sintakse. Ljubitelji mikrokontrolera, a ujedno po-znavaoci programskog jezika C++ ovom bibliotekom dobijaju gotovo neograničene mogućnosti da svoje najčešće korišćene strukture podataka i procedure vezane za njih grupišu u odgovarajuće klase i tako znatno unaprede svoju programersku produktivnost. Ovo područje primene biblioteke ARB predstavlja po našem mišljenju potencijalno njenu najperspektivniji domen gde druge alatke – asembleri i C kroskompajleri ne mogu da u potpunosti odgovore na sve naše zahteve.

 

Dok primeri predstavljeni u brojevima 3 i 4 časopisa “Mikroelektronika” ne zahtevaju neko naročito znanje iz viših programskih jezika (razumevanje nekih primera ne zahteva gotovo nikakvo znanje iz C/C++!), za praćenje narednog teksta podrazumevaće se poznavanje osnovnih postulata objektno orijentisanog programiranja. Integrisano kolo 8255 je dobro poznato svima onima koji su imali potrebu da prošire broj ulazno-izlaznih portova mikrokontrolera 8051.

Naš prvi primer, prikazan u datoteci ppi.h, demonstriraće mogućnost pristupa internim registrima ovog kola na način koji će poboljšati inače najranjiviju osobinu svakog sistemskog programera – produktivnost. Registri 8255 se po pravilu postavljaju u memorijsku mapu mikrokontolera i pristupa im se tako što se najpre postavi adresa u neki registar – pokazivač (dptr,r0,r1) a zatim izvrši instrukcija transfera na relaciji spoljna memorija – akumulator. To praktično znači da se ovim registrima pristupa posredno, pomoću dve instrukcije. Formiranjem objekta ppi stvorićemo priliku da sa programerskog stanovišta ovim registrima pristupamo kao registrima mikrokontrolera.
Objekat tipa ppi sadrži samo jedan skriveni podatak (int index) kojim se definiše lokacija pojedinog registra u odnosu na adresu kola (npr. PPI_ADR=0x4010). Konstruktorskom funkcijom ppi(int a) stvaramo 4 objekta tipa ppi i to na sledeći način:

ppi portA(0),portB(1),portC(2),control(3);

Podrazumeva se, naravno ,da registru control inicijalno dodelimo takvu vrednost kojom će se ovo kolo konfigurisati u pogledu orijentacije portova A,B i C. Za programsku liniju oblika:

control=”10000000”;

“brine” operatorska funkcija operator=(char *str),dok je za izraz portA=0x50; zadužena operatorska funkcija operator=(int podatak). Funkcija operator reg &() obavlja prisilnu konverziju objekta ppi u reg što nam omogućava da imamo izraz oblika:

a=portC;

Ovo sve zapravo znači da varijabli tipa ppi možemo direktno dodeljivati celobrojnu vrednost ali i akumulatoru dodeljivati sadržaj nekog od registara portA,portB ili portC. Zahvaljujući biblioteci ARB, posmatrano iz ugla programera, ovim registrima pristupamo kao da su integralni delovi mikrokontrolera. Naravno, ovu pogodnost obezbedićemo u svim našim budućim programima uključivanjem zaglavlja “ppi.h”!

Listing 1: Datoteka ppi.h
const int PPI_ADR=0x4010;
class ppi {
int index;
public:
ppi(int a){index=a;}
ppi operator=(int podatak);
ppi operator=(char *str);
operator reg &(){dptr=PPI_ADR+index;return *dptr;}
};
ppi ppi::operator=(int podatak)
{
dptr=PPI_ADR+index;
a=podatak;
*dptr=a;
return *this;
}
ppi ppi::operator=(char *str)
{
dptr=PPI_ADR+index;
a=str;
*dptr=a;
return *this;
}

Pre nego pređemo na drugi primer, pozabavićemo se još jednim aspektom programske biblioteke ARB, koji do sada nismo pominjali. Reč je o pokazivačima (pointer). ARB, pored standardnih, poseduje i sopstveni skup pokazivačkih varijabli. U skladu sa arhitekturom mikrokontrolera možemo deklarisati pokazivače na interni RAM,eksterni RAM, pokazivače na programsku memoriju,kao i pokazivače tipa direct i flag.
ARB 8051 podržava sledeće izraze:

pointer<xram>x(dptr);//dptr->ekst. RAM
pointer<iram> y(r0); // r0->interni RAM
pointer<code>z(pc);// pc->prog. memoriju
pointer<direct> pDirect;
pointer<flag> pFlag;

Pored ovoga, ovim varijablama je dodeljen odgovarajući skup operatora (‘*’,’++’,’—‘,’[]’,’=’), u saglasju sa setom instrukcija mikrokontrolera. Posebno ćemo rasvetliti poslednja dva slučaja. Varijablama ‘pDirect’ i ‘pFlag’ nije pridružen nijedan registar koji obavlja pokazivačku funkciju za razliku od predhodnih slučajeva. Promenljivim ovog tipa možemo dodeljivati celobrojnu vrednost (pDirect=10), uvećavati ih ili umanjivati (++pflag,—pDirect), dodeljivati ulogu indeksne promenljive (pDirect[5] ili (pDirect+10)) i naravno, ovim varijablama dodeljivati ulogu pokazivača (*pFlag=visok). U pojedinim situacijama, kao u našem sledećem primeru, upotreba pokazivača je poželjna, štaviše neophodna. Pretpostavimo sledeći slučaj: potrebno je upravljati radom jednog ili više motora. Mikrokontroler vrši uključivanje i isključivanje motora, obavlja očitavanje njegove (njihove) brzine i eventualno, na displeju prikazuje trenutnu brzinu motora. Za naš krajnje pojednostavljen primer, prihvatićemo da se podatak o brzini sprema u lokaciju direktno adresiranu privatnom promenljivom ‘BrzinaMotora’, a da se startovanje ( i stopiranje rada ) motora obavlja preko bita direktno adresiranog varijablom ‘Prekidac’. Dakle, imamo jednu strukturu podataka koja se sastoji od jednog objekta ‘direct’ i jednog tipa ‘flag’. Budući da je moguće postojanje više objekata tipa ‘motor’, treba obezbediti da se podaci novih objekata ne preklapaju sa podacima starih, pa se stoga uvodi celobrojna javna varijabla static int BrojMotora koja čuva informaciju o tome koliko je objekata tipa ‘motor’ do tog momenta formirano. Očitavanje brzine se vrši u pridruženoj funkciji ‘CitajBrzinu()’ (koja je u našem slučaju prazna) i koja u principu zavisi od hardverske konfiguracije uređaja. Stvaranje objekta je prepušteno konstruktorima motor() i motor(int a). U prvom slučaju struktura podataka se skladišti u skladu sa vrednošću varijable ‘BrojMotora’, a u drugom se pozicija strukture određuje eksplicitno preko celobrojnog parametra ‘a’. “Prijateljska” funkcija ‘Obrada()’, u for petlji, objedinjuje izvršenja svih funkcija ‘CitajBrzinu()’ nezavisno koliko je objekata tipa ‘motor’ do tog momenta formirano.

Listing 2. Datoteka motor.h
#include <stdio.h>
#include "arb8051.h"
const int ADR_BRZINA=0x40;
const int ADR_PREKIDAC=0x90;
class motor {
pointer<direct> BrzinaMotora;
pointer<flag> Prekidac;
public:
static int BrojMotora;
motor(void);
motor(int a);
čmotor(){--BrojMotora;}
void CitajBrzinu(void){}
direct & Brzina(void){return *BrzinaMotora;}
void Start(void){*Prekidac=visok;}
void Stop(void){*Prekidac=nizak;}
friend void Obrada(void);
};
int motor::BrojMotora=0;
motor::motor(void)
{
BrzinaMotora=ADR_BRZINA+BrojMotora;
Prekidac=ADR_PREKIDAC+BrojMotora;
++BrojMotora;
}
motor::motor(int a)
{
BrzinaMotora=ADR_BRZINA+a;
Prekidac=ADR_PREKIDAC+a;
++BrojMotora;
}
void Obrada(void)
{
for(int i=0;i<motor::BrojMotora;i++)
{
motor * pMotor=new motor(i);
pMotor->CitajBrzinu();
delete pMotor;
}
return ;
}

Stvaranjem klase ‘motor’, sebi donosimo silna olakšanja u postupku programiranja. Više ne moramo da vodimo računa o tome gde je bit-prekidač za pojedini motor,niti u kojoj smo lokaciji smestili podatak o trenutnoj brzini nekog motora.

Zaključak: biblioteka ARB nudi novi pogled na programiranje mikrokontrolera. Sistematski rad na stvaranju novih biblioteka funkcija i klasa doprinosi spajanju dva sveta: asemblera i viših programskih jezika. Pomisao da u sistemski orijentisanom okruženju posedujemo objekte kao što su na primer celi i decimalni brojevi, real-time objekti i procedure, PLC varijable čine inspirativnim sve buduće napore usmerene ka stvaranju komfornijeg i produktivnijeg programiranja za mikrokontrolere.

Pročitajte više o ovoj temi
Biblioteka klasa i funkcija za 8051 
Funkcije u ARB 8051
ARB PIC16F84 

C o p y r i g h t  1998 mikroElektronika. All Right Reserved. Za sva pitanja obratite se redakciji