Orice sistem embedded presupune interconectarea mai multor circuite care, împreuna, sa contribuie la realizarea (de obicei) a unui singur scop. Sa luam spre exemplu un sistem a carui funcție este sa monitorizeze confortul ambiental (o stație meteo simplificata). Pentru a crea acest sistem avem nevoie de un microcontroller si mai mulți senzori: de temperatura, de umiditate, de presiune, de calitate a aerului, etc.
Microcontrollerul este „creierul” care colecteaza și proceseaza datele, iar senzorii sunt furnizorii datelor. Cum ajung datele de la senzori la microcontroller? Avem nevoie de o schema/un protocol pe care sa îl cunoasca atât uC cât și senzorii pentru a putea interschimba date. În prezent, exista numeroase astfel de standarde care descriu modalitati de transmisie de date, dar, în principiu, le putem grupa în 2 mari categorii: paralele sau seriale. Doua protocoale foarte populare ce se incadreaza în cea de-a 2 categorie sunt SPI si I2C.
Interfata I2C este un standard sincron multi-master, multi-slave pentru transmisia de date dezvoltat de Philips Semiconductor (NXP Semiconductors). Un master este componenta care initiaza transferul de date și genereaza semnalul de ceas necesar pentru sincronizare. I2C folosește doar 2 linii de comunicatie, una pentru semnalul de ceas (SCL) și alta pentru date (SDA), deci comunicatia este half-duplex, functionand cu pana la 400Kbps.
SDA și SCL sunt 2 linii bidirectionale, open-drain, conectate la o sursa pozitiva de tensiune, prin intermediul unor rezistente de pull-up.
Cum începem o tranzactie de date în I2C? Când magistrala este libera, și SDA și SCL sunt în starea HIGH. Pentru a initia o tranzactie, trebuie sa trimitem conditia de START: SCL rămâne în starea HIGH, iar SDA trece din HIGH în LOW. Similar, dacă dorim sa încheiem o tranzactie, conditia de STOP corespunzatoare este reprezentata de trecerea SDA din LOW în HIGH, iar SCL rămâne HIGH. După trimiterea conditiei de START, magistrala este considerată a fi ocupata. Revenind la exemplul cu stația meteo, avem 3 senzori conectați la aceeași magistrala I2C a microcontrolerului, care are rolul de master. Dacă uC vrea sa citească date de la senzorul de presiune, bmp180, atunci va initia o tranzactie pe magistrala trimitand START.
Magistrala este aceeași pentru toți senzorii, deci cum îl alegem pe cel cu care vrem sa comunicam la un moment dat ? In I2C, fiecare „slave device” este referit printr-o adresa. Astfel, dacă avem mai multe circuite slave conectate pe magistrala, masterul alege cu care dintre ele dorește sa initieze comunicatia, precizand adresa specificata în datasheetul senzorului. Cel mai adesea, se folosesc adrese reprezentate pe 7 biti, iar cel mai nesemnificativ bit din octetul adresei ne arata daca urmeaza o operatie de scriere sau citire. După stabilirea device-ului cu care se comunica, se poate începe transimiterea datelor.
Uneori “slave” device-ul are nevoie de mai mult timp pentru a trimite datele. Dupa cum am spus, masterul controleaza linia de ceas si asteapta ca slave-ul sa trimita datele, tinand cont de ciclii sai de ceas. Daca datele nu sunt gata, slave-ul trebuie sa mai “traga de timp” si face acest lucru aducand linia SCL in starea LOW, imediat dupa ce masterul a eliberat-o.
Sa consideram unul dintre senzorii din exemplul cu statia meteo: senzorul de umiditate si temperatura si7020 si sa-l conectam la MCU pentru a realiza citirea umiditatii.
Primul pas este conectarea fizica a liniilor de date si ceas la MCU, ce are rolul de master. In datasheet-ul senzorului gasim o descriere elaborata despre cum se realizeaza o masuratoare:
In figura de mai sus sunt realizate urmatoarele codificari:
Prin urmare, pentru citirea umiditatii masurate de senzor se procedeaza in felul urmator:
SPI se incadreaza tot în categoria standardelor seriale sincrone, conectand un master și mai multe device-uri „slave”. Spre deosebire de I2C nu sunt suportate mai multe dispozitive master, însă comunicatia este full-duplex. Folosește 4 legături pentru comunicare:
Pentru fiecare dispozitiv slave este necesar câte un semnal de slave select separat, iar pentru selectarea slave-ului se pune linia SS corespunzatoare pe 0.
Mai întâi masterul pune pe 0 linia SS corespunzatoare slave-ului cu care dorește sa comunice. Apoi, transmisiunea fiind full-duplex, masterul va trimite biti pe linia MOSI, ce vor fi citiți de slave iar slave-ul va trimite, în același timp pe linia MISO, biti care vor fi interpretati de master. Acest lucru este posibil datorită unor registrii de shiftare, conectați circular.
Deși SPI-ul are numeroase avantaje, exista situații când avem nevoie sa conectam foarte multe dispozitive „slave”. Acest lucru se traduce în foarte multe linii de slave select. Atunci când nu avem suficiente linii disponibile, se pot folosi decodoare care sa permita referirea mai multor dispozitive slave decât linii SS disponibile.