- Hvad er I2C kommunikationsprotokol?
- Hvordan fungerer I2C-kommunikation?
- Hvor skal jeg bruge I2C-kommunikation?
- I2C med PIC16F877a ved hjælp af XC8 Compiler
- Programmering ved hjælp af I2C-headerfiler:
- Proteus Simulation:
PIC Microcontrollers er en kraftfuld platform leveret af mikrochip til indlejrede projekter, dens alsidige natur har gjort det muligt at finde veje til mange applikationer, og fasen fortsætter stadig. Hvis du har fulgt vores PIC-tutorials, ville du have bemærket, at vi allerede har dækket en bred vifte af tutorials om PIC-mikrocontroller startende fra det grundlæggende. Siden nu har vi dækket det grundlæggende, vi kan komme ind i mere interessante ting som kommunikationsportalen.
I det store system af integrerede applikationer kan ingen mikrokontroller udføre alle aktiviteterne alene. På et tidspunkt er det nødvendigt at kommunikere til andre enheder for at dele information, der er mange forskellige typer kommunikationsprotokoller til at dele disse oplysninger, men de mest anvendte er USART, IIC, SPI og CAN. Hver kommunikationsprotokol har sin egen fordel og ulempe. Lad os fokusere på IIC-delen for nu, da det er det, vi skal lære i denne vejledning.
Hvad er I2C kommunikationsprotokol?
Udtrykket IIC står for " Inter Integrated Circuits ". Det betegnes normalt som I2C eller I kvadrat C eller endda som 2-leder interface-protokol (TWI) nogle steder, men det hele betyder det samme. I2C er en synkron kommunikationsprotokol, der betyder, at begge enheder, der deler informationen, skal dele et fælles ursignal. Den har kun to ledninger til at dele information, hvoraf den ene bruges til cocksignalet, og den anden bruges til at sende og modtage data.
Hvordan fungerer I2C-kommunikation?
I2C-kommunikation blev først introduceret af Phillips. Som sagt tidligere har den to ledninger, disse to ledninger forbindes på tværs af to enheder. Her kaldes en enhed en master, og den anden enhed kaldes slave. Kommunikation skal og vil altid forekomme mellem to en mester og en slave. Fordelen ved I2C-kommunikation er, at mere end en slave kan forbindes til en Master.
Den komplette kommunikation finder sted gennem disse to ledninger, nemlig Serial Clock (SCL) og Serial Data (SDA).
Serielt ur (SCL): Deler det ursignal, der genereres af masteren, med slaven
Serial Data (SDA): Sender dataene til og fra mellem Master og slave.
På ethvert givet tidspunkt er det kun mesteren, der er i stand til at starte kommunikationen. Da der er mere end en slave i bussen, skal mesteren henvise til hver slave ved hjælp af en anden adresse. Når der kun er tale om salven med den pågældende adresse, svarer den tilbage med informationen, mens de andre holder op. På denne måde kan vi bruge den samme bus til at kommunikere med flere enheder.
Hvor skal jeg bruge I2C-kommunikation?
I2C-kommunikation bruges kun til kortdistancekommunikation. Det er bestemt pålideligt i et omfang, da det har en synkroniseret urpuls for at gøre det smart. Denne protokol bruges hovedsageligt til at kommunikere med sensorer eller andre enheder, der skal sende information til en master. Det er meget praktisk, når en mikrocontroller skal kommunikere med mange andre slave-moduler ved hjælp af et minimum af kun ledninger. Hvis du leder efter langkommunikation, skal du prøve RS232, og hvis du leder efter mere pålidelig kommunikation, skal du prøve SPI-protokollen.
I2C med PIC16F877a ved hjælp af XC8 Compiler
Nok af introduktioner, lad os komme ind i det og lære, hvordan vi kan bruge en mikrocontroller til at udføre I2C-kommunikation. Før vi begynder at gøre det klart, at denne tutorial kun taler om I2C i PIC16F877a ved hjælp af XC8-kompilator, vil processen være den samme for andre mikrocontrollere, men der kan være behov for små ændringer. Husk også, at for avancerede mikrokontrollere som PIC18F-serien, kan compileren selv have noget bibliotek indbygget til at bruge I2C-funktionerne, men til PIC16F877A findes der ikke noget lignende, så lad os bygge et på vores egen. Biblioteket, der er forklaret her, gives som en headerfil til download i bunden, som kan bruges til PIC16F877A til at kommunikere med andre I2C-enheder.
Som altid er vores datablad det bedste sted at starte noget. Se efter detaljer om I2C i databladet, og kontroller hvilke registre der skal konfigureres. Jeg vil ikke forklare i detaljer, da databladet allerede har gjort det for dig. Længere nedenfor vil jeg forklare de forskellige funktioner, der findes i headerfilen, og deres ansvar i programmet.
ugyldigt I2C_Initialize ()
Initialiseringsfunktionen bruges til at fortælle mikrocontrolleren, at vi skal bruge I2C-protokollen. Dette kan gøres ved at indstille de nødvendige bits i SSPCON- og SSPCON2-registeret. Det første skridt ville være at erklære IIC-stifterne som inputstifter, her skal stifterne RC3 og RC4 bruges til I2C-kommunikation, så vi erklærer dem som inputstifter. Dernæst skal vi indstille SSPCON og SSPCON2, som er et MSSP-kontrolregister. Vi betjener PIC'en i IIC-mastertilstand med en urfrekvens på FOSC / (4 * (SSPADD + 1)). Se sidetalene på databladet nævnt i kommentarlinjerne nedenfor for at forstå, hvorfor det pågældende register er indstillet på den måde.
Så næste gang er vi nødt til at indstille urfrekvensen, urfrekvensen for forskellige applikationer kan variere, derfor får vi valget fra brugeren via variablen feq_k og bruger den i vores formler til at indstille SSPADD-registret.
ugyldigt I2C_Initialize (const usigneret lang feq_K) // Begynd IIC som master { TRISC3 = 1; TRISC4 = 1; // Indstil SDA- og SCL-ben som inputpinde SSPCON = 0b00101000; // pg84 / 234 SSPCON2 = 0b00000000; // pg85 / 234 SSPADD = (_XTAL_FREQ / (4 * feq_K * 100)) - 1; // Indstilling af urets hastighed pg99 / 234 SSPSTAT = 0b00000000; // pg83 / 234 }
Ugyldig I2C_Hold ()
Den næste vigtige funktion er I2C_hold- funktionen, som bruges til at holde udførelsen af enheden, indtil den aktuelle I2C-operation er afsluttet. Vi bliver nødt til at kontrollere, om I2C-operationerne skal afholdes, inden vi starter en ny operation. Dette kan gøres ved at kontrollere registeret SSPSTAT og SSPCON2. SSPSTAT indeholder oplysninger om status for I2C-bussen.
Programmet kan synes at være lidt kompliceret, da det involverer en “og” og en “eller” operatør. Når du bryder det som
SSPSTAT & 0b00000100 SSPCON2 & 0b00011111
</s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s>
Det betyder, at vi sørger for, at 2. bit på SSPSTAT er nul, og tilsvarende er bits fra 0 til 4 nul på SSPCON2. Derefter kombinerer vi alle disse for at kontrollere, at resultatet er nul. Hvis resultatet er nul, fortsætter programmet, hvis ikke, holder det der, indtil det bliver nul, da det bruges i et stykke tid .
ugyldigt I2C_Hold () { mens ((SSPCON2 & 0b00011111) - (SSPSTAT & 0b00000100)); // tjek dette i registre for at sikre, at IIC ikke er i gang }
Ugyldigt I2C_Begin () og ugyldigt I2C_End ()
Hver gang mens vi skriver eller læser data ved hjælp af I2C-bussen, skal vi starte og afslutte I2C-forbindelsen. For at starte en I2C-kommunikation er vi nødt til at indstille SEN-bit og for at afslutte kommunikationen skal vi indstille PEN-statusbit. Før vi skifter nogle af disse bits, skal vi også kontrollere, om I2C-bussen er optaget ved hjælp af funktionen I2C_Hold som beskrevet ovenfor.
ugyldigt I2C_Begin () { I2C_Hold (); // Hold programmet er I2C er optaget SEN = 1; // Begynd IIC pg85 / 234 } ugyldig I2C_End () { I2C_Hold (); // Hold programmet er I2C er optaget PEN = 1; // Afslut IIC pg85 / 234 }
Ugyldig I2C_Write ()
Skrivfunktionen bruges til at sende data fra mastermodulet til salvemodulet. Denne funktion bruges normalt efter en I2C-startfunktion og efterfølges af en I2C-slutfunktion. De data, der skal skrives til IIC-bussen, sendes gennem de variable data. Disse data indlæses derefter i SSPBUF-bufferregisteret for at sende dem over I2C-bussen.
Normalt før der skrives en data, vil der blive skrevet en adresse, så du bliver nødt til at bruge skrivefunktionen to gange, en gang til indstilling af adressen og den anden gang til afsendelse af de faktiske data.
ugyldig I2C_Write (usignerede data) { I2C_Hold (); // Hold programmet er I2C er optaget SSPBUF = data; // pg82 / 234 }
usigneret kort I2C_Read ()
Den sidste funktion, som vi skal vide om, er I2C_Read- funktionen. Denne funktion bruges til at læse de data, der i øjeblikket findes på I2C-bussen. Det bruges efter at have bedt om en slave til at skrive en værdi til bussen. Den værdi, der modtages, er i SSPBUF, vi kan overføre denne værdi til en hvilken som helst variabel til vores operation.
Under en I2C-kommunikation vil slaven efter at have sendt de data, som Master har anmodet om, sende en anden bit, som er bekræftelsesbit, denne bit skal også kontrolleres af masteren for at sikre, at kommunikationen var vellykket. Efter kontrol af ACKDT-bit for bekræftelse skal den aktiveres ved at indstille ACKEN-bit.
usigneret kort I2C_Read (usigneret kort ack) { usigneret kort indgående; I2C_Hold (); RCEN = 1; I2C_Hold (); indkommende = SSPBUF; // få dataene gemt i SSPBUF I2C_Hold (); ACKDT = (ack)? 0: 1; // kontrollere om ACK- bit modtog ACKEN = 1; // s. 85/234 retur indgående; }
Det er det, disse funktioner skal være nok til at oprette en I2C-kommunikation og skrive eller læse data fra en enhed. Bemærk også, at der er mange andre funktioner, som I2C-kommunikationen kan udføre, men for enkelheds skyld diskuterer vi dem ikke her. Du kan altid henvise databladet for at kende den komplette funktion af
Den komplette kode med header-fil til PIC16F877A I2C-kommunikation kan downloades fra linket.
Programmering ved hjælp af I2C-headerfiler:
Nu hvor vi har lært, hvordan en I2C-kommunikation fungerer, og hvordan vi kan bruge headerfilen oprettet til den, lad os lave et simpelt program, hvor vi bruger headerfilen og skrive nogle værdier til I2C-linjerne. Vi simulerer derefter dette program og kontrollerer, om disse værdier skrives på bussen.
Som altid begynder programmet med at konfigurere konfigurationsbits og indstille urfrekvensen til 20 MHz som vist nedenfor
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT deaktiveret) # 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 er digital I / O, HV til MCLR skal bruges til programmering) #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 (Write protection off; all program memory) kan skrives til af EECON-kontrol) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) #define _XTAL_FREQ 20000000
Det næste trin ville være at tilføje headerfilen, som vi lige har diskuteret om. Overskriftsfilen er navngivet som PIC16F877a_I2C.h og kan downloades fra det link, vi diskuterede ovenfor. Sørg for, at headerfilen er tilføjet i headerfilen på din projektliste, din projektfilstruktur skal se sådan ud
Efter at have sørget for, at headerfilen føjes til din projektfil, skal du inkludere headerfilen i C-hovedfilen
#omfatte
Inde i while- sløjfen begynder I2C-kommunikationen at skrive få tilfældige værdier til I2C-bussen og derefter afslutte I2C-kommunikationen. De tilfældige værdier, som jeg har valgt, er D0, 88 og FF. Du kan indtaste de ønskede værdier. Men husk disse værdier, da vi vil verificere dem i vores simulering.
mens (1) { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0x88); I2C_Write (0xFF); I2C_End (); __forsink_ms (1000); }
Det komplette program kan findes nederst på siden, du kan bruge det eller downloade den komplette zip-fil af programmet herfra. Efter at have fået programmet, kompiler det og gør dig klar til simulering.
Proteus Simulation:
Proteus har et dejligt instrument kaldet I2C debugger, som kan bruges til at læse dataene på en I2C-bus, så lad os bygge et kredsløb ved hjælp af det og kontrollere, om dataene skrives med succes. Det komplette kredsløbsdiagram er vist nedenfor
Indlæs den hex-fil, der blev genereret af vores program, ved at dobbeltklikke på Microcontroller. Simuler derefter programmet. Du vil bemærke, at der vises et vindue, der viser alle oplysninger om I2C-bussen. Vinduet til vores program vises nedenfor.
Hvis du ser nærmere på de data, der skrives, kan du bemærke, at de er de samme, som vi skrev i vores program. Værdierne er D0, 88 og FF. Værdierne skrives for hvert 1 sekund, så tiden opdateres også som vist nedenfor. Den blå pil indikerer, at den er skrevet fra master til slave, hvis den ellers peger i modsat retning. Et nærmere kig på de data, der sendes, er vist nedenfor.
Dette er bare et glimt af, hvad I2C kan, det kan også læse og skrive data til flere enheder. Vi vil dække mere om I2C i vores kommende tutorials ved at interfacere forskellige moduler, der fungerer med I2C-protokollen.
Håber du forstod projektet og lærte noget nyttigt af det. Hvis du er i tvivl, send dem i kommentarfeltet nedenfor eller brug foraerne til teknisk hjælp.
Komplet kode er angivet nedenfor; Du kan downloade headerfiler med al koden herfra.