Sunteți pe pagina 1din 9

Universistatea Politehnica Timioara

Facultatea de Automatica i Calculatoare

Proiect la Comunicaii de Date

Comunicarea Master - Slave

Tnase Flaviu Alexandru


Vasile Mario Ctlin
An 3, IS, Grupa 3.2

1. Tema proiectului

Se consider o structur hardware constnd din dou sisteme de dezvoltare


echipate cu microcontrolere de tip 80C552. Acest tip de microcontroler integreaz n cip
facilitile hardware necesare pentru a comunica pe o magistral serial n standard
I2C. Acest hardware are structura unui automat cu stri finite, exploatabil prin
intermediul unor registre ale microcontrolerului. Modul de exploatare este descris pe
larg n paragraful 2.
Se cere s se lege ntre ele dou sisteme, unul care funcioneaz ca master i
unul care funcioneaz ca sclav. Pentru fiecare dintre sisteme se va scrie un program,
n limbaj C, care s permit comunicaia ntre cele dou sisteme astfel:
1. La nceputul rulrii aplicaiei (dup reset), fiecare modul iniializeaz interfaa
I2C.
2. Dup iniializare, sistemul master intr n modul transmitor i transmite ctre
sclav dou iruri de octei. Aceste iruri snt preluate din memorie, unde se presupune
c au fost declarate prin program, ca constante. Sistemul sclav va recepiona aceste
iruri de octei i le va memora ntr-un buffer. Transmisia celor dou iruri se va face ca
o operaie indivizibil, prin generarea unui start repetat dup transmiterea primului ir.
3. Dup terminarea transmisiei de ctre master, acesta va trece n mod receptor,
iar
sclavul va trece n mod transmitor. Acum sistemul sclav va transmite dou iruri de
octei, iar sistemul master le va recepiona, deasemenea cu start repetat. Apariia unei
erori de magistral va avea ca efect abandonarea operaiei curente (de transmitere,
respectiv de recepie) i ncercarea de reluare a ei. Deoarece n sistem exist un singur
master, apariia unei stri de pierdere a arbitrrii va fi tratat la fel ca o eroare.
Deasemenea, absena semnalului de acknoledge de la sclav va fi tratat ca eroare.
ncercarea de repetare a transferului se va face de trei ori, dup care se va aborta
ntreaga sesiune de comunicaie.
Intr-o aplicaie, lucrul cu interfaa serial I2C ( SIO1 ) se poate realiza, n principiu,
n doua moduri :

prin interogare (polling) cu ntreruperea serial SIO1 invalidat. n acest caz, se


testeaz prin program bitul SI pentru a detecta momentul n care interfaa ajunge ntr-o
stare definit (codul strii se citete din registrul S1STA).

prin ntreruperi. n acest caz programatorul trebuie s scrie o subrutin de tratare a


ntreruperii la care se ajunge automat (prin mecanisme hardware) atunci cnd bitul de
ntrerupere SI este setat.

n principiu, un program pentru interfaa serial I 2C ar trebui s cuprind o funcie


de iniializare a interfeei, cte o funcie pentru implementarea fiecrui mod de lucru i o
funcie de ntrerupere (dac se lucreaz cu ntreruperi).
Funcia de iniializare trebuie s realizeze programarea S1CON (validare, rata de
transfer, etc).
Funcia care implementeaz un mod de lucru trebuie s realizeze un automat
secvenial cu un numr finit de stri. Ea va cuprinde o bucl de ateptare, n care se
testeaz fanionul SI pn cnd acesta este setat prin hardware, eveniment ce indic
trecerea ntr-o nou stare. n continuare, aciunea ntreprins depinde de codul strii
curente din S1STA.
Funcia de tratare a ntreruperii trebuie s realizeze, n principiu, aceleai aciuni
prezentate anterior, adic implementarea modurilor de lucru, cu diferena c nu se mai
face testarea bitului SI, deoarece aceast funcie este apelat automat atunci cnd se
schimb starea i SI este setat.
Sistemele pe care se va implementa aceast aplicaie snt concepute n principal
ca platformre de dezvoltare i testare a aplicaiilor. Aceasta nseamn c dispun de
resurse mai mari dect ale unui sistem dedicat (embedded) dar mai mici dect ale unui
calculator PC.
De regul, astfel de aplicaii de dezvolt, la nivel software, pe un calculator PC
pe care ruleaz un crosscompilator. Acesta genereaz cod obiect care va fi transportat,
de obicei printr-o cale de comunicaie serial (RS232), pe sistemul int.
Compilatorul C pentru microcontrolerul 80552 recunoate numele registrelor SFR
i ale biilor din aceste registre. Ele snt asimilate unor variabile predefinite i pot aprea
n expresii i n instrucii de atribuire. De exemplu:
x = S1STA; sau
while(~SI);

sau

SI = 1;
snt instrucii valide.
Pentru interfaa cu dispozitivele de intrare-ieire presupunem c snt disponibile
dou funcii de bibliotec care au urmtoarele prototipuri:
unsigned char citeste(void);
void scrie(unsigned char);
Interfaa serial I2C (notat SIO1) permite conectarea microcontrolerului 80C552 la o
magistral I2C care utilizeaz doar dou linii, SDA (linia de date) i SCL (linia de ceas),
pentru transferul informaiei ntre dispozitivele conectate la magistral. Principalele
caracteristici ale acesteia snt :
transfer bidirecional ntre dispozitive master i sclav
magistral multimaster, fr un master central

arbitrare pentru tentativa de acces simultan la magistral a mai multor dispozitive


master
sincronizarea ceasului, care permite comunicarea dispozitivelor cu diferite rate de
transfer
Conectarea interfeei interne la magistrala externa I2C se face prin doi pini de port
(P1.6/SCL i P1.7/SDA). Aceti pini corespund unor linii bidirecionale, care pot
funciona att ca intrri, ct i ca ieiri. Unitatea central se interfaeaz cu SIO1 prin
1. Transfer de date de la un master transmitor la un sclav receptor. Primul octet transmis
de master este adresa sistemului sclav. Urmeaz un numr de octei de date, sclavul
returnnd un bit de confirmare (acknowledge bit - ACK) dupa fiecare octet recepionat.
2. Transfer de date de la un sclav transmitor la un master receptor. Primul octet (adresa
sclavului) este transmis de master, dupa care sclavul returneaza un bit de confirmare.
Urmeaz un numr de octei de date trimii de sclav ctre master. Dup fiecare octet
recepionat, masterul trimite un bit de confirmare, cu excepia ultimului octet, cnd trimite
un bit not acknowledge (NOT_ACK) pentru a comanda ncheierea transferului.
intermediul a patru registre de tip numite generic SFR (Special Function Register)
S1CON - registru de control
S1STA - registru de stare
S1DAT - registru de date
S1ADR - registru de adres (n modul sclav).

Masterul este ntotdeauna cel care iniiaz un transfer pe magistral, indiferent


de sensul transferului. El genereaz impulsurile de ceas, pe linia SCL, i condiiile de
START (S), STOP (P) sau START repetat, pe linia SDA. O condiie de START repetat
ncheie un transfer, dar masterul nu cedeaz magistrala, ci o pstreaz i pentru
urmtorul trasnsfer.
In funcie de bitul de direcie R/W\, snt posibile dou tipuri de transferuri de date :
S1CON trebuie iniializat astfel :
- bitul ENS1 =1 pentru validarea SIO1
- biii STA, STO, SI trebuie resetai
- bitul AA trebuie setat pentru ca SIO1 s recunoasc propria adres sau adresa
general
- bitii CR0, CR1, CR2 nu au importan n modul sclav
Dup ce S1ADR i S1CON au fost iniializai, SIO1 rmne n ateptare pn cnd

este adresat prin octetul SLA+W de un master transmitor. n continuare bitul SI este
setat i un numr de stri snt posibile (codul lor este n registrul S1STA). n modul sclav
receptor se poate ajunge i din modul master dac SIO1 pierde arbitrarea pentru acces
la magistral (vezi starile 68H i 78H).
Dac bitul AA este resetat n timpul unui transfer, SIO1 va returna un bit
NOT_ACK dup urmtorul octet de date; n continuare SIO1 nu i va mai recunoate
propria adres sau adresa general. Totui, magistrala este monitorizat i revenirea la
recunoaterea adreselor poate fi fcut prin setarea bitului AA (bitul AA poate fi, deci,
folosit pentru izolarea temporar de magistral).

Modul Sclav Transmitor


n acest mod, un numr de octei de date snt transmii ctre un master receptor.
Iniializarea transferului se face prin incrcarea S1ADR i S1CON la fel ca n cazul
sclav receptor.
Dup ce S1ADR i S1CON au fost iniializai, SIO1 rmne n ateptare pn cnd
este adresat prin octetul SLA+R de un master receptor. n continuare bitul SI este setat
i un numr de stri snt posibile (codul lor este n registrul S1STA). n modul sclav
transmitor se poate ajunge i din modul master dac SIO1 pierde arbitrarea pentru
acces la magistral (vezi starea B0H).
Dac bitul AA este resetat n timpul unui transfer, SIO1 va transmite un ultim octet
de date dup care va intra n una din strile C0H sau C8H. n continuare SIO1 nu i va
mai recunoate propria adres, sau adresa general, ignornd masterul dac acesta
continu transferul (masterul va recepiona n acest caz valoarea 1 pe linia serial).
Totui, magistrala este monitorizat i revenirea la recunoaterea adreselor poate fi
fcut prin setarea bitului AA.

Modul Master Receptor


n acest mod, un numar de octei de date snt recepionati de un master receptor
de la un sclav transmiator. Iniializarea transferului se face la fel ca n modul master
transmitor.
Cnd START este generat, bitul SI este setat i se intr n starea 08H n care
trebuie ncrcat registrul S1DAT cu adresa sclavului i bitul de sens (SLA+R). Bitul SI
trebuie resetat pentru ca transferul s continue.
Cnd SLA+R a fost transmis i bitul ACK a fost recepionat, bitul SI este setat din nou i
un numr de stri n S1STA snt posibile. Acestea snt 40H, 48H sau 38H pentru modul
master i 68H, 78H sau B0H dac modul sclav a fost validat (bitul AA = 1).
Dup un START repetat (starea 10H), SIO1 poate comuta n modul master transmitor
ncrcnd registrul S1DAT cu SLA+W.

//Programul pentru Master:


#include<reg552.h>
#include<ap_lib.h>
char slv=0xA;
char key=0x9;
//initializez S1CON
void initializare()
{
ENS=1;//pentru validarea lui SIO1
STA=0;//se reseteaza
STO=0;//se reseteaza
SI=0;//se reseteaza
AA=0;//poate fi setat sau resetat
CR0=0;//cei trei biti
CR1=0;//sunt pozitionati pentru
CR2=0;//rata de transfer dorita
}

//trimite tasta citita la Slave


void master_send()
STA=1;//aici se intra in modul Master
while(1)
{
if(SI)//testare SI
{
switch(S1STA)//aici este analizata starea curenta
{
case 0x0://eroare de comunicatie pe bus
lcd_Write(1, "*");//se afiseaza semnul *
break;
case 0x8://s-a transmis conditia de start
case 0x10://start repetat a fost transmis
STO=0;
S1DAT=slv<<1;//shift left pentru a obtine
//ultimul bit=0
break;
case 0x18://se trimite SLA+W; se primeste ACK
S1DAT=key;//se trimite tasta apasata
STA=0;
STO=0;
break;
case 0x20://s-a transmis SLA+W; se primeste NOT_ACK
STA=1;
STO=0;
break;

case 0x28://in acest caz tasta e transmisa; ACK receptionat


STA=0;
STO=1;//trimit stop
break;
case 0x30://in acest caz tasta e transmisa; NOT_ACK receptionat
S1DAT=key;//se incearca o retransmitere a tastei
STA=0;
STO=0;
break;
case 0x38://arbitrare pierduta
break;
}
SI=0;//resetare SI
}
}
}
//aici se citeste raspunsul transmis de slave
void master_recieve()
{
STA=1;//generare start
while(1)
{
if(SI)//testare SI
{
switch(S1STA)//aici se analizeaza starea curenta
{
case 0x0://eroare de comunicatie pe bus
lcd_Write(1, "*");//se afiseaza *
break;
case 0x8://s-a transmis conditia de start
case 0x10://start repetat a fost transmis
S1DAT=slv<<1;//shift left pentru a obtine
//ultimul bit=0
S1DAT=S1DAT || 1;//il punem pe 1
STO=0;
break;
case 0x38://arbitrare pierduta
break;
case 0x40://in acest caz se transmite SLA+R; se primeste ACK
STA=0;
STO=0;
AA=1;//se trimite ACK
break;
case 0x48://in acest caz s-a transmis SLA+R; se primeste NOT_ACK
STA=1;
STO=0;

break;
case 0x50://tasta a fost receptionata; ACK returnat
key=S1DAT;
AA=0;
STA=0;
STO=0;
break;
case 0x58://tasta a fost receptionata; NOT_ACK returnat
STA=1;
STO=0;
break;
}
SI=0;//resetare SI
}
}
}
void main()
{
lcd_InitDisplay();//initializarea afisajului LCD
initializare();//initializarea valorilor variabile
while(1)
{
master_send();//se trimite la slave
master_receive();//se receptioneaza de la slave
}
}

Programul pentru slave


#include <reg552.h>
#include <ap_lib.h>
char slv=0xA;
char key=0x8;
void initi2c()
{
ENS=1; //pentru validarea SIO1
STA=0; //se reseteaza bitul de start
STO=0; //se reseteaza bitul de stop
SI=0; //nu se folosesc intreruperile
AA=1; //se seteaza ACK
//setarea bitilor pentru comunicarea pe 16Mhz
CR0=0;

CR1=0;
CR2=0;
}
//trimitere tasta incrementata
void slave_send()
{
S1ADR=slv<<1; //adresa slave
while (1)
{
if (SI) //testare SI
{
switch(S1STA) //aici se analizeaza starea curenta
{
case 0x0: //eroare de comunicatie pe bus
lcd_Write(1, "*"); //se afiseaza caracterul *
break;
case 0xA8: //SLA+R receptionat; ACK receptionat
S1DAT=key; //data transmisa
STO=0;
AA=1;
break;
case 0xB0: //arbitrare pierduta
break;
case 0xB8: //data transmisa; ACK este receptionat de la master
S1DAT=key;
STO=0;
AA=1;
break;
case 0xC0: //data transmisa; NOT_ACK receptionat
STA=0;
STO=0;
AA=1;
break;