- Què és el protocol de comunicació I2C?
- Com funciona la comunicació I2C?
- On utilitzar la comunicació I2C?
- I2C amb PIC16F877a mitjançant el compilador XC8
- Programació mitjançant fitxers de capçalera I2C:
- Simulació de Proteus:
Els microcontroladors PIC són una potent plataforma proporcionada pel microxip per a projectes incrustats, la seva versatilitat li ha permès trobar vies per a moltes aplicacions i la fase continua. Si heu seguit els nostres tutorials PIC, hauríeu notat que ja hem cobert una àmplia gamma de tutorials sobre el microcontrolador PIC a partir dels fonaments bàsics. Des d’ara, hem tractat els conceptes bàsics que ens permeten aprofundir en coses més interessants, com ara el portal de comunicació.
En el vast sistema d'aplicacions incrustades, cap microcontrolador pot realitzar totes les activitats per si mateix. En algun moment del temps ha de comunicar-se amb altres dispositius per compartir informació, hi ha molts tipus diferents de protocols de comunicació per compartir aquesta informació, però els més utilitzats són USART, IIC, SPI i CAN. Cada protocol de comunicació té el seu propi avantatge i desavantatge. Centrem-nos en la part IIC per ara, ja que això és el que aprendrem en aquest tutorial.
Què és el protocol de comunicació I2C?
El terme IIC significa " Circuits integrats inter ". Normalment es denomina I2C o I al quadrat C o fins i tot com a protocol d'interfície de dos fils (TWI) en alguns llocs, però tot significa el mateix. I2C és un protocol de comunicació síncrona que significa que tots dos dispositius que comparteixen la informació han de compartir un senyal de rellotge comú. Només té dos cables per compartir informació, dels quals un s'utilitza per al senyal del gall i l'altre s'utilitza per enviar i rebre dades.
Com funciona la comunicació I2C?
Phillips va introduir per primera vegada la comunicació I2C. Com s'ha dit anteriorment, té dos cables, aquests dos cables es connectaran a través de dos dispositius. Aquí un dispositiu s’anomena mestre i l’altre es diu esclau. La comunicació s'ha de produir i es produirà sempre entre dos Mestres i Esclaus. L’avantatge de la comunicació I2C és que es pot connectar més d’un esclau a un mestre.

La comunicació completa es realitza a través d'aquests dos cables, a saber, el rellotge en sèrie (SCL) i les dades en sèrie (SDA).
Rellotge en sèrie (SCL): comparteix el senyal de rellotge generat pel mestre amb l’esclau
Dades de sèrie (SDA): envia les dades entre i des del mestre fins a l'esclau.
En qualsevol moment, només el mestre podrà iniciar la comunicació. Com que hi ha més d’un esclau al bus, el mestre ha de referir-se a cada esclau amb una adreça diferent. Quan s'adreça només la bomba amb aquesta adreça en particular respondrà amb la informació mentre els altres continuen deixant de fumar. D’aquesta manera podem utilitzar el mateix bus per comunicar-nos amb diversos dispositius.
On utilitzar la comunicació I2C?
La comunicació I2C només s’utilitza per a comunicacions a curta distància. Sens dubte, és fiable fins a un cert punt, ja que té un pols de rellotge sincronitzat per fer-lo intel·ligent. Aquest protocol s’utilitza principalment per comunicar-se amb sensors o altres dispositius que han d’enviar informació a un mestre. És molt útil quan un microcontrolador ha de comunicar-se amb molts altres mòduls esclaus mitjançant un mínim de només cables. Si busqueu una comunicació de llarg abast, proveu RS232 i si busqueu una comunicació més fiable, proveu el protocol SPI.
I2C amb PIC16F877a mitjançant el compilador XC8
Ja n’hi ha prou d’introduccions, hi podem entrar i aprendre com podem utilitzar un microcontrolador per realitzar comunicacions I2C. Abans de començar, deixeu clar que aquest tutorial només parla d’ I2C a PIC16F877a mitjançant el compilador XC8, el procés serà el mateix per a altres microcontroladors, però és possible que siguin necessaris canvis lleus. Recordeu també que per a microcontroladors avançats com la sèrie PIC18F, el propi compilador pot tenir alguna biblioteca incorporada per utilitzar les funcions I2C, però per a PIC16F877A no existeix res semblant, així que en construïm un pel nostre compte. La biblioteca que s'explica aquí es donarà com a fitxer de capçalera per descarregar a la part inferior, que es pot utilitzar per a PIC16F877A per comunicar-se amb altres dispositius I2C.
Com sempre, el millor lloc per començar és el nostre full de dades. Cerqueu detalls sobre I2C al full de dades i comproveu quins registres s'han de configurar. No ho explicaré en detalls, ja que el full de dades ja ho ha fet per vosaltres. Més endavant explicaré les diferents funcions presents al fitxer de capçalera i la seva responsabilitat en el programa.
void I2C_Initialize ()
La funció d’inicialització s’utilitza per dir al microcontrolador que farem servir el protocol I2C. Això es pot fer configurant els bits necessaris al registre SSPCON i SSPCON2. El primer pas seria declarar els pins IIC com a pins d’entrada, aquí els pins RC3 i RC4 s’han d’utilitzar per a la comunicació I2C, de manera que els declarem com a pins d’entrada. A continuació hauríem d’establir SSPCON i SSPCON2, que és un registre de control MSSP. Estem operant el PIC en mode mestre IIC amb una freqüència de rellotge de FOSC / (4 * (SSPADD + 1)). Consulteu els números de pàgina del full de dades esmentats a les línies de comentaris següents per entendre per què es defineix aquest registre concret.
Per tant, a continuació, hem d’establir la freqüència de rellotge, la freqüència de rellotge per a diferents aplicacions pot variar, per tant, podem triar de l’usuari mitjançant la variable feq_k i l’utilitzarem a les nostres fórmules per establir el registre SSPADD.
void I2C_Initialize (const unsigned long feq_K) // Comenceu la IIC com a mestre { TRISC3 = 1; TRISC4 = 1; // Estableix els pins SDA i SCL com a pins d'entrada SSPCON = 0b00101000; // pg84 / 234 SSPCON2 = 0b00000000; // pg85 / 234 SSPADD = (_XTAL_FREQ / (4 * feq_K * 100)) - 1; // Configuració de la velocitat de rellotge pg99 / 234 SSPSTAT = 0b00000000; // pàg83 / 234 }
Buida I2C_Hold ()
La següent funció important és la funció I2C_hold que s'utilitza per mantenir l'execució del dispositiu fins que finalitzi l'operació I2C actual. Hauríem de comprovar si les operacions I2C s’han de mantenir abans de començar qualsevol nova operació. Això es pot fer comprovant el registre SSPSTAT i SSPCON2. SSPSTAT conté informació sobre l'estat del bus I2C.
Pot semblar que el programa és una mica complicat, ja que implica un operador “i” i un “o”. Quan el trenques com
SSPSTAT i 0b00000100 SSPCON2 i 0b00011111
(…)
Vol dir que ens assegurem que el segon bit a SSPSTAT sigui zero i que els bits de 0 a 4 siguin zero a SSPCON2. A continuació, combinem tots aquests per comprovar que el resultat és zero. Si el resultat és zero, el programa continuarà si no que roman ancorat a ella fins que es posa a zero ja que s'utilitza en un temps bucle.
void I2C_Hold () { while ((SSPCON2 & 0b00011111) - (SSPSTAT & 0b00000100)); // comproveu això als registres per assegurar-vos que la IIC no està en curs }
Buida I2C_Begin () i buida I2C_End ()
Cada vegada que escrivim o llegim dades amb el bus I2C , hauríem de començar i finalitzar la connexió I2C. Per començar una comunicació I2C hem d’establir el bit SEN i per acabar la comunicació hem d’establir el bit d’estat PEN. Abans de canviar qualsevol d'aquests bits, també hauríem de comprovar si el bus I2C està ocupat mitjançant la funció I2C_Hold tal com s'ha comentat anteriorment.
void I2C_Begin () { I2C_Hold (); // Mantingueu el programa estant I2C està ocupat SEN = 1; // Començar la IIC pg85 / 234 } void I2C_End () { I2C_Hold (); // Mantingueu el programa estant I2C està ocupat PEN = 1; // Finalitza la IIC pg85 / 234 }
Buida I2C_Write ()
La funció d’escriptura s’utilitza per enviar qualsevol dada del mòdul mestre al mòdul salve. Aquesta funció s'utilitza normalment després d'una funció d'inici I2C i és seguida d'una funció Final I2C. Les dades que s’han d’escriure al bus IIC es passen per les dades variables. Tot seguit, aquestes dades es carreguen al registre de memòria intermèdia SSPBUF per enviar-les a través del bus I2C.
Normalment, abans d’escriure una dada, s’escriurà una adreça, de manera que haureu d’utilitzar la funció d’escriptura dues vegades, una per definir l’adreça i l’altra per enviar les dades reals.
void I2C_Write (dades sense signar) { I2C_Hold (); // Mantingueu el programa estant I2C està ocupat SSPBUF = data; // pàg82 / 234 }
curt sense signar I2C_Read ()
La funció final que hem de conèixer és la funció I2C_Read . Aquesta funció s’utilitza per llegir les dades que hi ha actualment al bus I2C. S'utilitza després de demanar a un esclau que escrigui algun valor al bus. El valor que es rebi serà a SSPBUF , podem transferir aquest valor a qualsevol variable per a la nostra operació.
Durant una comunicació I2C, l’esclau després d’enviar les dades sol·licitades pel mestre enviarà un altre bit que és el bit de confirmació, aquest bit també hauria de ser verificat pel mestre per assegurar-se que la comunicació ha estat correcta. Després de comprovar el bit ACKDT per confirmar-ho, s'hauria d'activar configurant el bit ACKEN.
unsigned short I2C_Read (sense signar curt ack) { sense signar curt entrant; I2C_Hold (); RCEN = 1; I2C_Hold (); entrant = SSPBUF; // obtenir les dades desades a SSPBUF I2C_Hold (); ACKDT = (ack)? 0: 1; // comproveu si el bit ack ha rebut ACKEN = 1; // pg 85/234 retorn entrant; }
És a dir, aquestes funcions haurien de ser suficients per configurar una comunicació I2C i escriure o llegir dades des d’un dispositiu. Tingueu en compte també que hi ha moltes altres funcionalitats que pot realitzar la comunicació I2C, però per motius de simplicitat no les discutim aquí. Sempre podeu consultar el full de dades per conèixer el funcionament complet del fitxer
El codi complet amb el fitxer de capçalera per a la comunicació I2C PIC16F877A es pot descarregar des de l'enllaç.
Programació mitjançant fitxers de capçalera I2C:
Ara que hem après com funciona una comunicació I2C i com podem utilitzar el fitxer de capçalera creat per a això, fem un programa senzill en què utilitzarem el fitxer de capçalera i escriurem alguns valors a les línies I2C. A continuació, simularem aquest programa i comprovarem si s’escriuen aquests valors al bus.
Com sempre, el programa comença configurant els bits de configuració i ajustant la freqüència del rellotge a 20 MHz, tal com es mostra a continuació
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #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 enabled) #pragma config LVP = OFF // Low Voltage (Single-Supply) In-Circuit Serial Programming Enable Bit (RB3 és E / S digital, HV activat S'ha d'utilitzar MCLR per a la programació) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Protecció contra escriptura desactivada; tota la memòria del programa) pot ser escrit per control EECON) #pragma config CP = OFF // Bit de protecció del codi de memòria del programa Flash (protecció de codi desactivada) #define _XTAL_FREQ 20000000
El següent pas seria afegir el fitxer de capçalera del qual acabem de parlar. El fitxer de capçalera s’anomena PIC16F877a_I2C.h i es pot descarregar des de l’enllaç que hem comentat anteriorment. Assegureu-vos que el fitxer de capçalera s'afegeixi al fitxer de capçalera de la llista de projectes, l'estructura del fitxer de projecte hauria de ser així

Després d'assegurar-vos que el fitxer de capçalera s'afegeix al fitxer de projecte, incloeu el fitxer de capçalera al fitxer C. principal
#incloure
Dins el temps de bucle que començarem les comunicacions I2C escriure uns valors aleatoris a el bus I2C i després Finalitzar la comunicació I2C. Els valors aleatoris que he triat són D0, 88 i FF. Podeu introduir els valors que vulgueu. Però recordeu aquests valors ja que els verificarem a la nostra simulació.
while (1) { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0x88); I2C_Write (0xFF); I2C_End (); __delay_ms (1000); }
El programa complet es pot trobar a la part inferior de la pàgina, podeu utilitzar-lo o descarregar el fitxer zip complet del programa des d’aquí. Després d'obtenir el programa, compileu-lo i prepareu-vos per a la simulació.
Simulació de Proteus:
Proteus té un bon instrument anomenat depurador I2C que es pot utilitzar per llegir les dades d’un bus I2C, així que anem a construir un circuit amb ell i comprovem si les dades s’escriuen amb èxit. El diagrama complet del circuit es mostra a continuació

Carregueu el fitxer hexadecimal que va generar el nostre programa fent doble clic al microcontrolador. A continuació, simula el programa. Notareu que apareix una finestra que mostrarà tota la informació sobre el bus I2C. A continuació es mostra la finestra del nostre programa.

Si mireu de prop les dades que s’escriuen, podreu notar que són les mateixes que vam escriure al nostre programa. Els valors són D0, 88 i FF. Els valors s’escriuen per cada 1 s, de manera que el temps també s’actualitza com es mostra a continuació. La fletxa blava indica que està escrita de mestre a esclau si apuntaria en sentit contrari si fos el contrari. A continuació es mostra una visió més detallada de les dades que s’envien.

Això és només una visió del que pot fer I2C, també pot llegir i escriure dades en diversos dispositius. Trobarem més informació sobre I2C en els nostres propers tutorials mitjançant la interfície de diversos mòduls que funcionen amb el protocol I2C.
Espero que hagueu entès el projecte i n’heu après alguna cosa útil. Si teniu cap dubte, publiqueu-los a la secció de comentaris de sota o utilitzeu els fòrums per obtenir ajuda tècnica.
A continuació s’ha indicat el codi complet; aquí podeu descarregar fitxers de capçalera amb tot el codi.
