Software projekti
 

C++ 8051 - ARB 8051

BIBLIOTEKA KLASA I FUNKCIJA - I DEO

Postoji li šansa da izradu programa za mikrokontrolere vršimo iz nekog višeg programskog jezika a da opet stvaramo optimalan izvršni kod, da možemo da izvučemo maksimum iz našeg mikrokontrolera, da koristimo sve njegove resurse? Možemo li generisati kod za mikrokontroler bez asemblera ili specijalizovanog kros-kompajlera koristeći sopstvenu notaciju ili onu koja je prilagođena konkretnom problemu? Odgovori na ova pitanja nalaze se u seriji članaka o programskoj biblioteci ARB 8051.

Osnovna ideja koja je vodila tvorca ove biblioteke klasa i funkcija bila je upravo u tome da potvrdno odgovori na oba postavljena pitanja. Jedno od prvih pitanja koje se postavilo tom prilikom jeste pitanje izbora programskog jezika. Jezik koji je ispunjavao sve postavljene uslove i koji je bio idealno programsko okruženje za ostvarenje posta-vljenog zadatka bio je i ostao C++. Bez namere da se šire upuštamo u filozofiju ovog programskog jezika, neophodno je navesti neka njegova svojstva. Kao i svaki objektno orijentisani jezik podržava mehanizme nasleđivanja, realizacije konstruktorskih i destruktorskih funkcija a ono što ga čini posebno pogodnim za ovu priliku jeste mogućnost da novoformiranim objektima dodelimo ( gotovo ista ) svojstva koja imaju standardni tipovi podataka, a preklapanje operatora prvenstveno to obezbeđuje. To znači da umesto mnemoničke oznake add a,r1 pišemo a+r1, umesto mov a,r1 bilo bi a=r1, činila je ovu ideju još privlačnijom. Svakako, to nije jedini razlog zbog kojeg smatramo primenu programske biblioteke ARB poželjnom u odnosu na druge programske alate. Drugi važan razlog je blokovska organizacija programa realizovanog pomoću ove programske biblioteke. To je okolnost koja dodatno olakšava (dosta neugodan) postupak programiranja. Najviše radi toga, biblioteka ARB 8051 se u ranijim predstavljanjima pojavljivala pod svojim radnim imenom - Blok51.

ARB 8051 je uspešno testiran na sledećim C/C++ kompajlerima: Borland C/C++ 3.1; 4.5 i 5.0.

Pre nego što pređemo na konkretne primere, važno je ukazati na sličnosti i razlike između programiranja uz pomoć ARB 8051 i drugih oblika programiranja, asemblera i viših programskih jezika. Najvažnija sličnost sa asemblerom jeste u tome što se svaka linija programa može prevesti na odgovarajuću asemblersku instrukciju, u našem slučaju na jednu iz seta instrukcija Intel-ovog mikrokontrolera 8051. Drugim rečima korišćenjem biblioteke klasa i funkcija ARB 8051 možemo realizovati optimalne izvršne kodove kao da smo program stvarali u nekom od kros-asemblera. Na drugoj strani zahvaljujući ogromnoj snazi jezika C/C++ dolazimo do mogućnosti da realizujemo sopstvene klase i funkcije i tako formiramo programsku notaciju sličnu onoj iz viših programskih jezika. Time konačno dajemo potvrdan odgovor na pitanja postavljena u uvodu ovog članka. Osim toga, ista ili slična notacija može da se primeni na više različitih mikrokontrolera pa ARB postaje univerzalno programsko oruđe u poslovima programiranja mikrokontrolera. Za sada će biti predstavljena biblioteka ARB za već pomenutu Intel-ovu familiju mikrokontrolera 8051 (i druge kompatibilne mikrokontrolere na nivou procesora kao što je mikrokontroler firme ATMEL na primer) ali u perspektivi možemo računati na pojavljivanje istovetne softverske podrške i za druge popularne mikrokontrolere.

Primer koji će, nadamo se, uspešno demonstrirati snagu metoda ARB (listing 1 i 2) treba isključivo posmatrati kao jedno-stavnu prezentaciju onoga što je do sada rečeno. Uporedni prikazi programskih sekvenci izvornih kodova u asembleru i ARB-u imaju za cilj da bez mnogo reči ilustruju većinu svojstava programske bi-blioteke ARB.

Listing 1
ulaz mov a,r3
       inc r3
       setb psw.4
       mov @r0,a
       cjne r3,#01h,izlaz
       dec r3
       clr psw.4
       clr a
       jnz ulaz
izlaz
Listing 2
{
blok x;
a=r3;
++r3;
psw(4)=visok;
*r0=a;
x.napusti(r3!=0x01);
-- r3;
psw(4)=nizak;
a=0;
x.opet(a);
}

Potpuno ekvivalentan deo primenom biblioteke klasa i funkcija u ARB 8051 je predstavljen na listingu 2. zahvaljujući već pomenutom svojstvu ove biblioteke da se svaka instrukcija mikrokontrolera 8051 može jednoznačno prevesti na odgovarajuću programsku liniju C++ programa.

Šta nam zapravo donosi ARB? Umesto imena pojedinih instukcija, tj. skraćenih opisa akcija pojedinih instrukcija , koristimo operatorsku notaciju koja je, mora se to priznati, mnogo prihvatljivija i za iskusne korisnike pojedinih mikrokontrolera. Drugo, delovi programa su organizovani u blokove što dodatno olakšava proces programiranja. Treće, mnogobrojne instrukcije relativnog skoka zamenjene su sa tri osnovne blokovske funkcije ( napusti(), opet(), proboj() ) i jednom samostalnom funkcijom skok(). Blokovske funkcije napusti() i opet() podsećaju na C naredbe break i continue, a funkcija proboj() u kombinaciji sa funkcijom osim() na izvestan način simulira postojanje standardne naredbe if…else. Samostalna funkcija skok() odražava potrebu za postojanjem naredbe tipa goto , koja je ipak nezamenljiva kada je u pitanju sistemsko programiranje, u kakvo svakako spada i programiranje za mikrokontrolere.

Treba naglasiti (što se inače ne vidi iz datih primera) da postoje imenovani i neimenovani blokovi, da se blokovi mogu razbijati u segmente, da je moguće uskakati iz segmenta u segment itd.

Pozivanje samostalne funkcije skok() je vezano upravo za tzv. imenovane blokove što znači da je reč o instrukciji skoka na početak bloka čija je deklaracija : blok ImeBloka(IDENTIFIKATOR) gde je IDENTIFIKATOR celobrojna konstanta čija se de-klaracija mora oba-viti na po-četku programa. Osim toga metod ARB omogućava i vrlo fleksibilno korišćenje instrukcija poziva potprograma, instrukcije dugog skoka, instrukcije rotacije sadržaja akumulatora kao i specifične instrukcije kao što je međuregistarska razmena sadržaja, rotacija niblova, decimalno podešavanje itd. Kada je u pitanju pozivanje programskih rutina treba uočiti da ARB podržava pozivanje procedura predajom vrednosti identifikatora bloka procedure kao i predajom imena procedure čime se dolazi do značajne mogućnosti formiranja sopstvenih biblioteka potprograma. Sve ovo potkrepićemo jednim konkretnim primerom iz prakse kao što je komunikacija između računara i mikrokontrolerskog uređaja. Biće predstavljen program koji je u potpunosti realizovan u ARB-u i koji je potvrđen u praksi a radi se o transferu niza znakova iz računara u uređaj i obrnuto. Izvršenje programa čiji je izvorni kod smešten u datoteci string.cpp treba da obezbedi prijem niza čiji prvi i poslednji znaci ( 0x04 i 0x05 ) treba da mirokontroleru signaliziraju startovanje odnosno okončavanje procesa prijema niza.
Prihvat stringa i njegovo smeštanje u internu memoriju obavlja prekidna rutina Prijem() dok se u prekidnoj rutini Slanje() vrši samo postavljanje bita ti(Transmit Interrupt flag) a vraćanje stringa PC-u obavlja rutina Odgovor().

Funkcijaizbor“string.a01”,INTEL_HEX) obavlja specificiranje “izvršnog” fajla u kome se nalazi kod odgovarajućeg formata, određen drugim parametrom ove funkcije. Ukoliko se ova funkcija izostavi krajnji proizvod prevođenja , povezivanja i izvršenja programa string biće sadržan u datoteci aout.a01. Ukoliko je izabrana opcija INTEL_HEX dobijamo kao krajnji produkt tekstualnu datoteku istoimenog formata koja je veoma pogodna za kasniju obradu. Pored ovoga, postoji i mogućnost generisanja odgovarajuće binarne datoteke. Programskom linijom LB=0, smeštamo izvršni kod od lokacije 0h a deklaracijom blokovske promenljive Start i kasnijom definicijom pomoću funkcije oblik() odlučujemo se za “razbijeni” (razlomljeni) memorijski blok koji se izvršava prilikom resetovanja mikrokontrolera kao i u slučaju dešavanja interapta.

U prvom slučaju program se izvršava od linije : blok GlavniProgram(MAIN) a u drugom u zavisnosti od vrednosti bitova ri odnosno ti. U glavnom programu obavlja se neophodno konfigurisanje mikrokontrolera ( funkcija Inic() ), dodeljivanje adrese stringa ( u našem slučaju r0 koji ukazuje na internu memoriju ) da bi na kraju program upao u mrtvu petlju. U prekidnim rutinama, kao što je već rečeno, mikrokontroler komunicira sa glavnim računarom.
Za potrebe testiranja ovog programa, autor je razvio malu PC aplikaciju ( monitor.exe ) koja obavlja slanje stringa na odgovarajući serijski port a zatim njegovo čitanje i prikazivanje. U potprogramu Prijem() vrši se čuvanje sadržaja registara acc i psw,ispitivanje svakog primljenog znaka, njihovo smeštanje, ažuriranje pokazivača kao i pozivanje potprograma Odgovor gde se obavlja vraćanje znakova PC-u. Između svaka dva vraćanja mikrokontroler pravi pauzu kako bi se dozvolilo serijskom interfejsu mikrokontrolera da korektno obavi slanje karaktera. Ovaj program ilustruje većinu svojstava metoda ARB. Za dobre poznavaoce asemblera razumevanje ove sintakse neće predstavljati neki poseban problem. Takođe, i za one kojima je bliže programiranje u nekom višem programskom jeziku pogodnosti koje pruža ovaj metod su veoma značajne.

Listing - monitor.c
#include <stdio.h>

#include "arb8051.h"
void Pauza(unsigned int t1,unsigned int t2);
void Odgovor(void);
void Inic(void);
void Prijem(void);
void Slanje(void)
{
ti=nizak;
reti();
}
void Petlja(void)
{
blok t;
t.opet();
}
const int AdrString=0x60;
const int PrviZnak=0x04;
const int ZadnjiZnak=0x05;
main()
{
izbor("string.a01",INTEL_HEX);
  LB=0;
{
  blok Start;
  Start.oblik(RAZLOMLJEN);
  Start(0);
    skok(MAIN);
  Start(SINT);
    skok(ri,Prijem);
    skok(ti,Slanje);
}
    {
    blok GlavniProgram(MAIN);
    Inic();
    r0=AdrString;
    Petlja();
  }
  return 0;
  }

void Prijem(void)
{
acc>>sp; // push acc
psw>>sp; // push psw
    {
    blok Odluka;
    a=sbuf;
    Odluka.proboj(a!=ZadnjiZnak);
      poziv(Odgovor);
      r0=AdrString;
    Odluka.osim();
      *r0=a;
      ++r0;
      Odluka.napusti(a!=PrviZnak);
      r0=AdrString;
    }
ri=nizak;
psw<<sp; // pop psw
acc<<sp; // pop acc
reti();
}
void Inic(void)
{
ie="10010000";
sp=0x40;
th1=0xf3;
tmod=0x20;
tcon=0x40;
ip=0x10;
scon=0x50;
}
void Pauza(unsigned int t1,unsigned int t2)
{
r3=t1;
blok vreme1;
    r2=t2;
    {
    blok vreme2;
    vreme2.opet(r2.BeforeDec()); // djnz r2,$
    }
vreme1.opet(r3.BeforeDec());
return;
{
void Odgovor(void)
}
*r0=ZadnjiZnak;
r0=AdrString;
  {
  blok priv;
  a=*r0;
  sbuf=a;
  Pauza(0x9f,0xff);
  ++r0;
  priv.opet(a!=ZadnjiZnak);
  sbuf=ZadnjiZnak;
  Pauza(0x9f,0xff);
  }
ret();
}

Daljim razmišljanjem dolazi se do najmanje dve ideje:

  1.  Podrška ARB-a i za druge mikrokontrolere,
  2. dalji razvoj ove programske biblioteke čiji bi krajnji cilj bio stvaranje sintakse prilagođene krajnjem korisniku (PLC orijentisani programski jezici)

O ovim i drugim mogućnostima ove programske biblioteke biće više reči u narednim brojevima časopisa.


Pročitajte više o ovoj temi
Funkcije u ARB 8051
Klase 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