MIKROPROCESORSKI SISTEMI

DOMAĆI ZADATAK BROJ 4

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Sistem za laboratorijsko uzgajanje biljaka

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

                                                                                      Autori

                                                       

        Beograd,                                            Vujović Ivana       81 96

15.02.2001.                                        Kovačević Miloš   250 97

 

 

                                                         

 

 

0.      Režimi rada sistema i serijska veza sa nadzornim centrom

 

          Sistem je projektovan da radu u dva režima:

-          Automatski režim - sistem jednom prima dozvoljene vrednosti klimatskih parametara (temperatura,...) od nadzornog centra, za dan i noć, i automatski podešava sve parametre prema primljenim podacima, sve dok ne dobije nove podatke ili ne pređe u ručni režim.

-          Ručni režim - sistem prima pojedinačne komande od nadzornog centra za podešavanje pojedinačnih parametara (npr. uključi ventil za vodu) i prosleđuje ih spoljašnjim klima uređajima.

Bez obzira na režim rada, sistem na svakih sat vremena, i na specijalan zahtev, nadzornom centru šalje sve trenutne klimatske parametre, kao i tačno vreme i datum.

          Serijska veza ka nadzornom centru se inicira svakih sat vremena i na specijalan zahtev nadzornog centra u bilo kom trenutku. Podaci se šalju kao bajtovi, sledećim redosledom: Temperatura, Vlažnost zemljišta, Vlažnost vazduha, Osvetljenje, sat, dan, mesec i godina. Osvetljenje se šalje kao bajt čiji je broj jedinica jednak vrednosti osvetljenja (0x00=0, 0x01=1, 0x03=2, 0x7=3, 0x0F=4). U toku ovog procesa slanja trenutnih podataka nadzorni centar ne sme slati sistemu nikakve komande!

          Serijsku vezu u ka sistemu nadzorni centar može da inicira u bilo kom trenutku, osim za vreme prethodno opisane komunikacije. Nadzorni centar može da šalje sledeće komande (bajtove) sistemu:

0b0000 0000 = uđi u automatski režim i čekaj nove vrednosti podataka

(14 bajtova po sledećem redosledu):

                                   Tmin, Tmax, VZmin,VZmax, VVmin,VVmax, Osv - prvo za dan pa onda za noć. (traženo Osvetljenje je u istom formatu kao i u komunikaciji suprotnim smerom)

          0b0000 0001 = uđi u automatski režim i radi po prethodnim podacima

 

          0b0100 0000 = pošalji mi trenutne vrednosti klimatskih parametara                

 

          0b10GH LLLL = ručna komanda:

                                                G - grejač, H - gladnjak, LLLL - lampe

                                      1 na mestu nekog bita znači da dati uređaj treba uključiti, a

                                      0 znači da ga treba isključiti

          0b11xx ZSVF = ručna komanda:

                                                Z - ventil za vodu

                                      1 na mestu nekog bita znači da dati uređaj treba uključiti, a

                                      0 znači da ga treba isključiti

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.      Korišćene komponente

 

 

komponenta

komada

opis

8051

1

Mikrokontroler

74HC373

1

Adresni leč

DS12887

1

Spoljašnji digitalni časovnik sa baterijom (vreme i datum su  

 tačno inicijalizovani pre ubacivanja u sistem)

8255

2

Paralelni portovi za slanje signala ka klima uređajima

 i prijem parametara od mernih uređaja preko A/D konvertera

6264

4

8K8 RAM kapaciteta 8KB

27C256

1

32K8 EPROM kapaciteta 32KB

MSM38128A

1

Spoljni adresni PROM 16K8 kapaciteta 16KB

Rxx

X

Otpornici

Cxx

X

Kondenzatori

D4..0

5

Signalizacione LE diode, vezane na interni Port1 (nižih 5b)

 

 

          Memorijski i ulazno/izlazni adresni prostori su preslikani u  jedan.Adresa su raspodeljene na sledeći način:

RAM1: 0000:1FFFh

RAM2: 2000:3FFFh

RAM3: 4000:5FFFh

RAM4: 6000:7FFFh

 

ROM:   00000: 07FFFh (PSENcmpl=0)

 

 12887: 8000:807Fh

8255': 9000:9003h

8255": A000:A003h

 

 

 

Sadžaj adresnog PROMa MSM38128A je sledeći:

 

A15

A14

A13

A12

A11

A10

A9

A8

A7

A6

A5

A4

A3

A2

RAM1

RAM2

RAM3

RAM4

CS5'

cpl

C55"

cpl

C87

cpl

x

A13

A12

A11

A10

A9

A8

A7

A6

A5

A4

A3

A2

A1

Ao

O0

O1

O2

O3

O4

O5

O6

O7

0

0

0

X

X

X

X

X

X

X

X

X

X

X

1

0

0

0

1

1

1

X

0

0

1

X

X

X

X

X

X

X

X

X

X

X

0

1

0

0

1

1

1

X

0

1

0

X

X

X

X

X

X

X

X

X

X

X

0

0

1

0

1

1

1

X

0

1

1

X

X

X

X

X

X

X

X

X

X

X

0

0

0

1

1

1

1

X

1

0

0

0

0

0

0

0

0

X

X

X

X

X

0

0

0

0

1

1

0

X

1

0

0

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

1

X

1

0

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

1

X

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.      Program

 

#include <reg51.h>   /* inicijalizuje adrese svih registara i bitova */

 

#define ukljuciGrejac    *tempOsvKom|=0x20

#define iskljuciGrejac   *tempOsvKom&=0xDF

#define ukljuciHladnjak  *tempOsvKom|=0x10

#define iskljuciHladnjak *tempOsvKom&=0xEF

#define podesiSvetlo *tempOsvKom&=0xF0;*tempOsvKom|=OsvNom

#define zalivaj          *vlazKom|=0x08

#define neZalivaj      *vlazKom&=0xF7

#define susiZemlju    *vlazKom|=0x04

#define neSusiZemlju *vlazKom&=0xFB

#define vlaziVazduh  *vlazKom|=0x02

#define neVlaziVazduh         *vlazKom&=0xFD

#define susiVazduh   *vlazKom|=0x01

#define neSusiVazduh          *vlazKom&=0xFE

 

#define Tmin            podaci[7*noc-1]

#define Tmax           podaci[7*noc-2]

#define VZmin          podaci[7*noc-3]

#define VZmax         podaci[7*noc-4]

#define VVmin          podaci[7*noc-5]

#define VVmax         podaci[7*noc-6]

#define OsvNom       podaci[7*noc-7]       /* zahtevano (nominalno) osvetljenje */

 

 

char data podaci [14];   /* Osv,VVmax,VVmin,VZmax,VZmin,Tmax,Tmin za noc pa za dan*/

int  xdata izlazak [12]    /* vreme izlaska Sunca u minutima za svaki mesec */ 

 = {405,390,380,370,360,350,360,370,380,390,400};

int  xdata zalazak [12]   /* vreme zalaska Sunca u minutima za svaki mesec */

 = {980,1000,1020,1040,1060,1080,1100,1080,1060,1040,1000};

char data brojac;                         /* brojac prenetih bajtova pri prijemu serijskom vezom*/

char data noc     =2;                    /* noc=2 <=> dan , noc=1 <=> noc */

bit         manual   =0;                   /* rucni rezim */

bit         automatic=0;                  /* automatski rezim */

bit         osvezi   =0;                    /* centar trazi nove podatke */

char xdata * minuta =0x8002;        /* registri eksternog casovnika */

char xdata * sati   =0x8004;         

char xdata * dan    =0x8007;

char xdata * mesec  =0x8008;

char xdata * godina =0x8009;

char xdata * secal  =0x8001;         /* alarm */

char xdata * minal  =0x8003;

char xdata * hral   =0x8005;

char xdata * ra12887=0x8010;       /* kontrolni i statusni registri */

char xdata * rb12887=0x8011;

char xdata * rc12887=0x8012;

char xdata * temp   =0xA000;        /* trenutna temperatura */

char xdata * vlazZem=0x9000;       /* trenutna vlaznost zemljista */

char xdata * vlazVaz=0x9001;        /* trenutna vlaznost vazduha */

char xdata * osv    =0xA002;         /* trenutno osvetljenje */

char xdata * tempOsvKom=0xA001;

char xdata * vlazKom=0x9002;

char xdata * p1ctrl =0x9003;

char xdata * p2ctrl =0xA003;

sbit        ERR  = P1^0;                  /* diode */

sbit        COM  = P1^1;

sbit        TEMP = P1^2;

sbit        HUM1 = P1^3;

sbit        HUM2 = P1^4;

 

void salji() ;             /* samo prototip */

         

void main () using 0

{                           /* inicijalizacija 8051 */

   TL1=0xFD;            /* reload value */

   TMOD=0x20;         /* tajmer/kaunter1: soft.kontrola, tajmer, mod 2 */

   TR1=1;                /* pokreni tajmer 1 */

   REN=1;                /* dozvoli prijem serijskom vezom */

   EA=1;                  /* omoguci prekide */

   ES=1;                  /* omoguci prekid od serijskog porta */

   EX0=1;                 /* omoguci spoljasnji prekid od casovnika */

   PS=1;                  /* prekid serijskog porta ima visok prioritet */

   PX0=0;                /* prekid casovnika ima nizak prioritet */

   P1=0;                  /* ugasi sve signalizacione diode */

                             /* inicijalizacija casovnika: */

   *ra12887=0x20;    /* ukljuci oscilator */

   *rb12887=0x27;    /* alarm zahteva prekid, binarni podaci, 24h mod, ds */

   *secal=0;             /* alarm */

   *minal=0;

   *hral=0xFF;

  

   *p1ctrl=0x92;       /* prvi 8255: Mod 0; PA,PB - input, PC - output  */

   *p2ctrl=0x91;       /* drugi: Mod 0; PA,PCL - input, PB,PCH - output  */

         

   while (1) {

          while (manual)

          {

             ERR=0;

             if (*osv^(*tempOsvKom&0x0F)) ERR=1; /* crkla sijalica ili foto detektor*/

             if (*temp>80) ERR=1;                          /* crko termometar */

             if (*vlazZem>100) ERR=1;                    /* crko merac vlaznosti */

             if (*vlazVaz>100) ERR=1;                     /* crko merac vlaznosti */

          }

         

          if (*temp<Tmin)

          {

             iskljuciHladnjak;

             ukljuciGrejac;

             TEMP=1;

          }

             else if (*temp>Tmax)

             {

                iskljuciGrejac;

                ukljuciHladnjak;

                TEMP=1;

             }

                else

                {

                   TEMP=0;                                     /* temperatura je u granicama */

                   if (*temp == (Tmin+Tmax)/2)

                   {

                      iskljuciGrejac;

                      iskljuciHladnjak;

                   }  

                }             

          if (*vlazZem<VZmin)

          {

             neSusiZemlju;

             zalivaj;

             HUM1=1;

          }

             else if (*vlazZem>VZmax)

             {

                neZalivaj;

                susiZemlju;

                HUM1=1;

             }

                else

                {

                   HUM1=0;

                   if (*vlazZem == (VZmin+VZmax)/2)

                   {

                      neZalivaj;

                      neSusiZemlju;

                   }  

                } 

          if (*vlazVaz<VVmin)

          {

             neSusiVazduh;

             vlaziVazduh;

             HUM2=1;

          }

             else if (*vlazVaz>VVmax)

             {

                neVlaziVazduh;

                susiVazduh;

                HUM2=1;

             }

                else

                {

                   HUM2=0         ;

                   if (*vlazVaz == (VVmin+VVmax)/2)

                   {

                      neVlaziVazduh;

                      neSusiVazduh;

                   }  

                } 

         

          ERR=0;

          if (*osv^(*tempOsvKom&0x0F)) ERR=1;    /* crkla sijalica ili foto detektor*/

          if (*temp<Tmin-10) ERR=1;                      /* crko grejac */

          if (*temp>Tmax+10) ERR=1;                    /* crko hladnjak */

          if (*vlazZem<VZmin-10) ERR=1;               /* crko ventil */

          if (*temp>80) ERR=1;                             /* crko termometar */

          if (*vlazZem>100) ERR=1;                       /* crko merac vlaznosti */

          if (*vlazVaz>100) ERR=1;                        /* crko merac vlaznosti */

          podesiSvetlo;

         

          if (osvezi)

          {                                                        /* nadzorni centar trazi sveze podatke */

             salji();

             osvezi=0;

          }  

         

   } /*od while*/

}

 

/* Procedura koja salje nadzornom centru trenutne parametre */

void salji () using 1

{

         

          SBUF=*temp;           /* posalji temperaturu */

          while (!TI) {}           /* cekaj da ode */

          TI=0;                     /* oznaci serijskom portu da je prekid prihvacen */

          SBUF=*vlazZem;      /* posalji vlaznost zemljista */

          while (!TI) {}           /* cekaj da ode */

          TI=0;                     /* oznaci serijskom portu da je prekid prihvacen */

          SBUF=*vlazVaz;       /* posalji vlaznost vazduha */

          while (!TI) {}           /* cekaj da ode */

          TI=0;                     /* oznaci serijskom portu da je prekid prihvacen */

          SBUF=*osv;             /* posalji osvetljenje */

          while (!TI) {}           /* cekaj da ode */

          TI=0;                     /* oznaci serijskom portu da je prekid prihvacen */

          SBUF=*sati;            /* posalji vreme  i datum */

          while (!TI) {}           /* cekaj da ode */

          TI=0;                     /* oznaci serijskom portu da je prekid prihvacen */

          SBUF=*dan;

          while (!TI) {}           /* cekaj da ode */

          TI=0;                     /* oznaci serijskom portu da je prekid prihvacen */

          SBUF=*mesec;

          while (!TI) {}           /* cekaj da ode */

          TI=0;                     /* oznaci serijskom portu da je prekid prihvacen */

          SBUF=*godina;

          while (!TI) {}           /* cekaj da ode */

          TI=0;                     /* oznaci serijskom portu da je prekid prihvacen */

}

 

/* Prekidna rutina za prekid od eksternog sata,

   na svakih sat vremena salje nadzornom centru podatke serijskom vezom */

void casovnik () interrupt 0 using 2

{

          COM=1;                  /* signaliziraj da je u toku komunikacija */ 

          ACC=rc12887;          /* procitaj registar C da bi sat prekinuo zahtev za prekid */

          salji();                    /* posalji parametre */

          COM=0;                  /* signaliziraj da je komunikacija zavrsena */       

}

 

/* Prekidna rutina za prekid pri zavrsenom prenosu jednog podatka

  serijskom vezom */

void serijska () interrupt 4 using 3

{

          if (TI) {return;}                           /* slanje */

          ACC=SBUF;                                 /* ako je prijem , ucitaj primljeni podatak */

          RI=0;                                         /* kazi serijskom portu da je prihvacen prekid */

          if (automatic&&brojac)                  /* u toku je prijem podataka za */     

          {                                               /* automatski rezim */

             podaci[--brojac]=ACC;

             if (!brojac) {COM=0;manual=0;}   /* zavrsen prenos */

             return;

          }

          if (ACC&0x80) {

             manual=1;                                /* 1xxx xxxx je rucna komanda */

             automatic=0;

             if (ACC&0x40)

             {                                            /* 11xx xxxx je komanda za vlaznost*/

                *vlazKom=ACC&0x0F;

                return;

             }

                else 

                   *tempOsvKom=ACC&0x3F;    /* 10xx xxxx je za temp. i osv. */

             return;

          }

          switch (ACC)          

          {

             case 0x00:           /* 0000 0000 je ulazak u */

                automatic=1;     /* automatski mod */

                brojac=14;        /* posle cega stizu novi podaci */

                COM=1;

                break;

             case 0x01:           /* 0000 0001 je ulazak u */

                automatic=1;     /* automatski mod */

                brojac=0;           /* sa starim podacima */

                manual=0;

                break;

             case 0x40:           /* 0100 0000 je zahtev */

                osvezi=1; /* za slanje novih podataka */

                break;

          }

          return;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


3.      Električna šema