- Ce este protocolul de comunicare I2C?
- Cum funcționează comunicarea I2C?
- Unde se utilizează comunicarea I2C?
- I2C cu PIC16F877a folosind XC8 Compiler
- Programarea utilizând fișierele antet I2C:
- Simulare Proteus:
Microcontrolerele PIC sunt o platformă puternică oferită de microcip pentru proiecte încorporate, caracterul său versatil a făcut să găsească căi în multe aplicații și faza este încă în desfășurare. Dacă ați urmărit tutorialele noastre PIC, atunci ați fi observat că am acoperit deja o gamă largă de tutoriale pe microcontrolerul PIC începând de la elementele de bază. De acum, am acoperit elementele de bază în care putem intra în lucruri mai interesante, cum ar fi portalul de comunicare.
În vastul sistem de aplicații încorporate, niciun microcontroler nu poate efectua toate activitățile singur. La un moment dat, trebuie să comunice cu alte dispozitive pentru a partaja informații, există multe tipuri diferite de protocoale de comunicații pentru a partaja aceste informații, dar cele mai utilizate sunt USART, IIC, SPI și CAN. Fiecare protocol de comunicare are propriul avantaj și dezavantaj. Să ne concentrăm pe partea IIC pentru moment, deoarece asta vom învăța în acest tutorial.
Ce este protocolul de comunicare I2C?
Termenul IIC înseamnă „ Circuite integrate integrate ”. În mod normal este notat ca I2C sau I pătrat C sau chiar ca protocol de interfață cu 2 fire (TWI) în unele locuri, dar totul înseamnă același lucru. I2C este un protocol de comunicație sincron, ceea ce înseamnă că ambele dispozitive care partajează informațiile trebuie să partajeze un semnal de ceas comun. Are doar două fire pentru a partaja informații, dintre care unul este utilizat pentru semnalul cock și celălalt este utilizat pentru trimiterea și primirea de date.
Cum funcționează comunicarea I2C?
Comunicarea I2C a fost introdusă pentru prima dată de Phillips. Așa cum am spus mai devreme, are două fire, aceste două fire vor fi conectate pe două dispozitive. Aici un dispozitiv este numit master și celălalt este numit slave. Comunicarea ar trebui și va avea loc întotdeauna între doi un Maestru și un Sclav. Avantajul comunicației I2C este că mai mult de un sclav poate fi conectat la un Master.
Comunicarea completă are loc prin intermediul acestor două fire și anume Serial Clock (SCL) și Serial Data (SDA).
Serial Clock (SCL): Partajează semnalul de ceas generat de master cu sclavul
Serial Data (SDA): Trimite datele către și de la Master și slave.
În orice moment, numai comandantul va putea iniția comunicarea. Deoarece există mai mult de un sclav în autobuz, comandantul trebuie să se refere la fiecare sclav folosind o adresă diferită. Când este adresat, numai salvarea cu adresa respectivă va răspunde înapoi cu informațiile, în timp ce ceilalți continuă să renunțe. Astfel putem folosi același autobuz pentru a comunica cu mai multe dispozitive.
Unde se utilizează comunicarea I2C?
Comunicarea I2C este utilizată numai pentru comunicarea pe distanțe scurte. Cu siguranță, este sigur într-o anumită măsură, deoarece are un impuls de ceas sincronizat pentru a-l face inteligent. Acest protocol este utilizat în principal pentru a comunica cu senzori sau alte dispozitive care trebuie să trimită informații unui master. Este foarte la îndemână atunci când un microcontroler trebuie să comunice cu multe alte module slave folosind un minim de numai fire. Dacă sunteți în căutarea unei comunicații pe termen lung, ar trebui să încercați RS232 și dacă căutați o comunicare mai fiabilă, ar trebui să încercați protocolul SPI
I2C cu PIC16F877a folosind XC8 Compiler
Destul de introduceri, să intrăm în el și să aflăm cum putem folosi un microcontroler pentru efectuarea comunicării I2C. Înainte de a începe clarificați că acest tutorial vorbește doar despre I2C în PIC16F877a folosind compilatorul XC8, procesul va fi același pentru alte microcontrolere, dar ar putea fi necesare modificări ușoare. De asemenea, amintiți-vă că pentru microcontrolere avansate precum seria PIC18F, compilatorul în sine ar putea avea o bibliotecă încorporată pentru a utiliza caracteristicile I2C, dar pentru PIC16F877A nu există așa ceva, așa că haideți să construim unul singur. Biblioteca explicată aici va fi dată ca fișier antet pentru descărcare în partea de jos, care poate fi utilizată pentru PIC16F877A pentru a comunica cu alte dispozitive I2C.
Ca întotdeauna cel mai bun loc pentru a începe orice este fișa noastră tehnică. Căutați detalii despre I2C în foaia de date și verificați ce registre trebuie configurate. Nu voi explica în detalii, deoarece foaia tehnică a făcut deja acest lucru pentru dvs. Mai jos, voi explica diferitele funcții prezente în fișierul antet și responsabilitatea lor în program.
void I2C_Initialize ()
Funcția de inițializare este utilizată pentru a spune microcontrolerului că vom folosi protocolul I2C. Acest lucru se poate face prin setarea biților necesari pe registrul SSPCON și SSPCON2. Primul pas ar fi să declarăm pinii IIC drept pini de intrare, aici pinii RC3 și RC4 ar trebui folosiți pentru comunicarea I2C, deci le declarăm ca pini de intrare. Apoi ar trebui să setăm SSPCON și SSPCON2, care este un registru de control MSSP. Operăm PIC în modul master IIC cu o frecvență de ceas de FOSC / (4 * (SSPADD + 1)). Consultați numerele de pagină ale fișei tehnice menționate în liniile de comentarii de mai jos pentru a înțelege de ce acel anumit registru este setat în acest fel.
Deci, în continuare, trebuie să setăm frecvența ceasului, frecvența ceasului pentru diferite aplicații ar putea varia, prin urmare, alegem de la utilizator prin variabila feq_k și o folosim în formulele noastre pentru a seta registrul SSPADD.
void I2C_Initialize (const unsigned long feq_K) // Începeți IIC ca master { TRISC3 = 1; TRISC4 = 1; // Setați pinii SDA și SCL ca pini de intrare SSPCON = 0b00101000; // pg84 / 234 SSPCON2 = 0b00000000; // pg85 / 234 SSPADD = (_XTAL_FREQ / (4 * feq_K * 100)) - 1; // Setarea vitezei de ceas pg99 / 234 SSPSTAT = 0b00000000; // pg83 / 234 }
Vid I2C_Hold ()
Următoarea funcție importantă este funcția I2C_hold care este utilizată pentru a menține execuția dispozitivului până la finalizarea operației I2C curente. Ar trebui să verificăm dacă operațiunile I2C trebuie ținute înainte de a începe orice operație nouă. Acest lucru se poate face verificând registrul SSPSTAT și SSPCON2. SSPSTAT conține informații despre starea magistralei I2C.
Programul ar putea părea puțin complicat, deoarece implică un operator „și” și un „sau”. Când o spargi ca
SSPSTAT și 0b00000100 SSPCON2 și 0b00011111
(…)
Înseamnă că ne asigurăm că al doilea bit pe SSPSTAT este zero și în mod similar biții de la 0 la 4 sunt zero pe SSPCON2. Apoi combinăm toate acestea pentru a verifica dacă rezultatul este zero. Dacă rezultatul este zero, programul va continua, dacă nu, va rămâne acolo până când devine zero, deoarece este utilizat într-o buclă while .
void I2C_Hold () { while ((SSPCON2 & 0b00011111) - (SSPSTAT & 0b00000100)); // verificați acest lucru în registre pentru a vă asigura că IIC nu este în desfășurare }
Anulați I2C_Begin () și anulați I2C_End ()
De fiecare dată când scriem sau citim date folosind magistrala I2C , ar trebui să începem și să terminăm conexiunea I2C. Pentru a începe o comunicare I2C trebuie să setăm bitul SEN și pentru a termina comunicarea trebuie să setăm bitul de stare PEN. Înainte de a comuta oricare dintre acești biți, ar trebui să verificăm dacă magistrala I2C este ocupată utilizând funcția I2C_Hold așa cum s-a discutat mai sus.
void I2C_Begin () { I2C_Hold (); // Țineți programul I2C ocupat SEN = 1; // Începeți IIC pg85 / 234 } void I2C_End () { I2C_Hold (); // Țineți programul I2C ocupat PEN = 1; // Sfârșitul IIC pg85 / 234 }
Anulează I2C_Write ()
Funcția de scriere este utilizată pentru a trimite orice date din modulul master către modulul salve. Această funcție este utilizată în mod normal după o funcție de început I2C și este urmată de o funcție I2C End. Datele care trebuie scrise în magistrala IIC sunt transmise prin datele variabile. Aceste date sunt apoi încărcate în registrul tampon SSPBUF pentru a le trimite prin magistrala I2C.
În mod normal, înainte de scrierea unei date, se va scrie o adresă, astfel încât va trebui să utilizați funcția de scriere de două ori, o dată pentru setarea adresei și cealaltă dată pentru trimiterea datelor reale.
void I2C_Write (date nesemnate) { I2C_Hold (); // Țineți programul I2C este ocupat SSPBUF = date; // pg82 / 234 }
nesemnat scurt I2C_Read ()
Funcția finală despre care trebuie să știm este funcția I2C_Read . Această funcție este utilizată pentru a citi datele care se află în prezent pe magistrala I2C. Se folosește după ce ai cerut unui sclav să scrie o valoare în autobuz. Valoarea primită va fi în SSPBUF , putem transfera acea valoare către orice variabilă pentru operațiunea noastră.
În timpul unei comunicații I2C, sclavul după trimiterea datelor solicitate de master va trimite un alt bit care este bitul de confirmare, acest bit ar trebui să fie verificat și de master pentru a se asigura că comunicarea a avut succes. După verificarea bitului ACKDT pentru confirmare, acesta trebuie activat prin setarea bitului ACKEN.
unsigned short I2C_Read (nesemnat short ack) { nesemnat short incoming; I2C_Hold (); RCEN = 1; I2C_Hold (); incoming = SSPBUF; // obțineți datele salvate în SSPBUF I2C_Hold (); ACKDT = (ack)? 0: 1; // verifică dacă bitul ack a primit ACKEN = 1; // pg 85/234 returnează intrările; }
Asta este, aceste funcții ar trebui să fie suficiente pentru a configura o comunicație I2C și pentru a scrie sau citi date de pe un dispozitiv. De asemenea, rețineți că există multe alte funcționalități pe care le poate realiza comunicația I2C, dar, din simplitate, nu le discutăm aici. Puteți consulta întotdeauna foaia tehnică pentru a cunoaște funcționarea completă a
Codul complet cu fișierul antet pentru comunicația PIC16F877A I2C poate fi descărcat de pe link.
Programarea utilizând fișierele antet I2C:
Acum, că am aflat cum funcționează o comunicație I2C și cum putem folosi fișierul de antet creat pentru aceasta, să facem un program simplu în care vom folosi fișierul de antet și să scriem câteva valori pe liniile I2C. Vom simula apoi acest program și vom verifica dacă aceste valori sunt scrise pe autobuz.
Ca întotdeauna programul începe cu setarea biților de configurare și setarea frecvenței ceasului la 20 MHz, așa cum se arată mai jos
#pragma config FOSC = HS // Oscillator Selection bits (HS oscilator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) # pragma config BOREN = ON // Brown-out Reset Enable bit (BOR activat) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 este I / O digital, HV activat MCLR trebuie utilizat pentru programare) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Protection write off; all memory program poate fi scris către controlul EECON) #pragma config CP = OFF // Bit program de protecție cod memorie program Flash (protecție cod dezactivată) #define _XTAL_FREQ 20000000
Următorul pas ar fi adăugarea fișierului antet despre care tocmai am discutat. Fișierul antet este denumit PIC16F877a_I2C.h și poate fi descărcat de pe linkul pe care l-am discutat mai sus. Asigurați-vă că fișierul antet este adăugat în fișierul antet din lista dvs. de proiecte, structura fișierului proiect ar trebui să arate astfel
După ce vă asigurați că fișierul antet este adăugat la fișierul proiectului, includeți fișierul antet în fișierul C. principal
#include
În interiorul buclei while vom începe comunicarea I2C scrieți câteva valori aleatorii pe magistrala I2C și apoi Încheiați comunicarea I2C. Valorile aleatoare pe care le-am ales sunt D0, 88 și FF. Puteți introduce orice valoare doriți. Dar amintiți-vă acele valori așa cum le vom verifica în simularea noastră.
while (1) { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0x88); I2C_Write (0xFF); I2C_End (); __delay_ms (1000); }
Programul complet poate fi găsit în partea de jos a paginii, îl puteți utiliza sau puteți descărca fișierul zip complet al programului de aici. După ce obțineți programul, compilați-l și pregătiți-vă pentru simulare.
Simulare Proteus:
Proteus are un instrument drăguț numit debugger I2C, care poate fi folosit pentru a citi datele de pe o magistrală I2C, așa că hai să construim un circuit folosindu-l și să verificăm dacă datele sunt scrise cu succes. Schema completă a circuitului este prezentată mai jos
Încărcați fișierul hex generat de programul nostru făcând dublu clic pe microcontroler. Apoi simulați programul. Veți observa o fereastră care va afișa toate informațiile despre autobuzul I2C. Fereastra pentru programul nostru este prezentată mai jos.
Dacă aruncați o privire atentă la datele scrise, puteți observa că acestea sunt aceleași pe care le-am scris în programul nostru. Valorile sunt D0, 88 și FF. Valorile sunt scrise pentru fiecare 1 sec, deci timpul se actualizează și după cum se arată mai jos. Săgeata albastră indică faptul că este scrisă de la stăpân la sclav, dacă ar fi altfel indicată în direcție opusă. O privire mai atentă a datelor trimise este prezentată mai jos.
Aceasta este doar o privire asupra a ceea ce poate face I2C, poate citi și scrie date pe mai multe dispozitive. Vom acoperi mai multe despre I2C în tutorialele noastre viitoare prin interfațarea diferitelor module care funcționează cu protocolul I2C.
Sper că ați înțeles proiectul și ați învățat ceva util din acesta. Dacă aveți nelămuriri, postați-le în secțiunea de comentarii de mai jos sau folosiți forumurile pentru ajutor tehnic.
Codul complet a fost dat mai jos; puteți descărca fișiere antet cu tot codul de aici.