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