- Hva er I2C kommunikasjonsprotokoll?
- Hvordan fungerer I2C-kommunikasjon?
- Hvor skal jeg bruke I2C-kommunikasjon?
- I2C med PIC16F877a ved bruk av XC8 Compiler
- Programmering ved hjelp av I2C-headerfiler:
- Proteus simulering:
PIC Microcontrollers er en kraftig plattform levert av mikrochip for innebygde prosjekter, den allsidige naturen har gjort det mulig å finne veier til mange applikasjoner, og fasen fortsetter. Hvis du har fulgt PIC-opplæringen, ville du ha lagt merke til at vi allerede har dekket et bredt spekter av opplæringsprogrammer om PIC-mikrokontroller, helt fra det grunnleggende. Siden nå har vi dekket det grunnleggende vi kan komme inn på mer interessante ting som kommunikasjonsportalen.
I det enorme systemet med innebygde applikasjoner kan ingen mikrokontroller utføre alle aktivitetene av seg selv. På et tidspunkt av tiden må den kommunisere til andre enheter for å dele informasjon, det er mange forskjellige typer kommunikasjonsprotokoller for å dele denne informasjonen, men de mest brukte er USART, IIC, SPI og CAN. Hver kommunikasjonsprotokoll har sin egen fordel og ulempe. La oss fokusere på IIC-delen for nå, siden det er det vi skal lære i denne opplæringen.
Hva er I2C kommunikasjonsprotokoll?
Begrepet IIC står for " Inter Integrated Circuits ". Det er vanligvis betegnet som I2C eller jeg kvadratisk C eller til og med som 2-leder grensesnittprotokoll (TWI) noen steder, men alt betyr det samme. I2C er en synkron kommunikasjonsprotokoll som betyr at begge enhetene som deler informasjonen må dele et vanlig klokkesignal. Den har bare to ledninger for å dele informasjon hvorav den ene brukes til cocksignalet og den andre brukes til å sende og motta data.
Hvordan fungerer I2C-kommunikasjon?
I2C-kommunikasjon ble først introdusert av Phillips. Som sagt tidligere har den to ledninger, disse to ledningene vil være koblet på tvers av to enheter. Her kalles den ene enheten en mester og den andre enheten kalles slave. Kommunikasjon skal og vil alltid skje mellom to en mester og en slave. Fordelen med I2C-kommunikasjon er at mer enn en slave kan kobles til en Master.
Den komplette kommunikasjonen skjer gjennom disse to ledningene, nemlig Serial Clock (SCL) og Serial Data (SDA).
Serial Clock (SCL): Deler kloksignalet som genereres av mesteren med slaven
Serial Data (SDA): Sender dataene til og fra mellom Master og slave.
Til enhver tid er det bare mesteren som kan starte kommunikasjonen. Siden det er mer enn en slave i bussen, må mesteren henvise til hver slave ved hjelp av en annen adresse. Når bare adressen til salven med den aktuelle adressen blir adressert, vil den svare tilbake med informasjonen mens de andre slutter. På denne måten kan vi bruke den samme bussen til å kommunisere med flere enheter.
Hvor skal jeg bruke I2C-kommunikasjon?
I2C-kommunikasjon brukes bare for kortdistansekommunikasjon. Det er absolutt pålitelig til en viss grad siden det har en synkronisert klokkepuls for å gjøre det smart. Denne protokollen brukes hovedsakelig til å kommunisere med sensor eller andre enheter som må sende informasjon til en master. Det er veldig praktisk når en mikrokontroller må kommunisere med mange andre slave-moduler ved å bruke minimum bare ledninger. Hvis du er ute etter kommunikasjon over lang rekkevidde, bør du prøve RS232, og hvis du leter etter mer pålitelig kommunikasjon, bør du prøve SPI-protokollen.
I2C med PIC16F877a ved bruk av XC8 Compiler
Nok av introduksjoner, kan komme inn i det og lære hvordan vi kan bruke en mikrokontroller for å utføre I2C-kommunikasjon. Før vi begynner å gjøre det klart at denne opplæringen bare snakker om I2C i PIC16F877a ved bruk av XC8-kompilator, vil prosessen være den samme for andre mikrokontrollere, men det kan være nødvendig med små endringer. Husk også at for avanserte mikrokontrollere som PIC18F-serien, kan kompilatoren selv ha noe bibliotek innebygd for å bruke I2C-funksjonene, men for PIC16F877A eksisterer ingenting som det, så la oss bygge et på egen hånd. Biblioteket som er forklart her vil bli gitt som en headerfil for nedlasting nederst, som kan brukes til PIC16F877A for å kommunisere med andre I2C-enheter.
Som alltid er det beste stedet å starte noe vårt datablad. Se etter detaljer om I2C i databladet og sjekk hvilke registre som må konfigureres. Jeg kommer ikke til å forklare i detalj siden databladet allerede har gjort det for deg. Videre nedenfor skal jeg forklare de forskjellige funksjonene som er til stede i topptekstfilen og deres ansvar i programmet.
ugyldig I2C_Initialize ()
Initialiseringsfunksjonen brukes til å fortelle mikrokontrolleren at vi skal bruke I2C-protokollen. Dette kan gjøres ved å sette de nødvendige bitene i SSPCON- og SSPCON2-registeret. Det første trinnet ville være å erklære IIC-pinnene som inngangspinner, her skal pinnene RC3 og RC4 brukes til I2C-kommunikasjon, så vi erklærer dem som inngangspinner. Deretter bør vi sette SSPCON og SSPCON2 som er et MSSP-kontrollregister. Vi bruker PIC i IIC-hovedmodus med en klokkefrekvens på FOSC / (4 * (SSPADD + 1)). Henvis til sidetallene på databladet som er nevnt i kommentarlinjene nedenfor for å forstå hvorfor det aktuelle registeret er satt på den måten.
Så neste gang må vi stille klokkefrekvensen, klokkefrekvensen for forskjellige applikasjoner kan variere, derfor får vi valget fra brukeren via variabelen feq_k og bruker den i våre formler for å sette SSPADD-registeret.
ugyldig I2C_Initialize (const usignert lang feq_K) // Begynn IIC som master { TRISC3 = 1; TRISC4 = 1; // Sett SDA- og SCL-pinner som inngangspinner SSPCON = 0b00101000; // pg84 / 234 SSPCON2 = 0b00000000; // pg85 / 234 SSPADD = (_XTAL_FREQ / (4 * feq_K * 100)) - 1; // Innstilling av klokkehastighet pg99 / 234 SSPSTAT = 0b00000000; // pg83 / 234 }
Ugyldig I2C_Hold ()
Den neste viktige funksjonen er I2C_hold- funksjonen som brukes til å holde kjøringen av enheten til den nåværende I2C-operasjonen er fullført. Vi må sjekke om I2C-operasjonene må holdes før vi starter en ny operasjon. Dette kan gjøres ved å sjekke registeret SSPSTAT og SSPCON2. SSPSTAT inneholder informasjon om status for I2C-bussen.
Programmet kan synes å være litt komplisert siden det involverer en “og” og en “eller” operatør. Når du bryter det som
SSPSTAT & 0b00000100 SSPCON2 & 0b00011111
</s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s> </s>
Det vil si at vi har å sørge for at to nd litt på SSPSTAT er null og tilsvarende biter fra 0 til 4 er null på SSPCON2. Da kombinerer vi alle disse for å sjekke at resultatet er null. Hvis resultatet er null, vil programmet fortsette hvis ikke, vil det holde der til det blir null siden det brukes i en periode .
ugyldig I2C_Hold () { mens ((SSPCON2 & 0b00011111) - (SSPSTAT & 0b00000100)); // sjekk dette på registre for å sikre at IIC ikke er i gang }
Ugyldig I2C_Begin () og ugyldig I2C_End ()
Hver gang mens vi skriver eller leser data ved hjelp av I2C-bussen, bør vi starte og avslutte I2C-forbindelsen. For å starte en I2C-kommunikasjon må vi stille inn SEN-biten og for å avslutte kommunikasjonen, må vi sette PEN-statusbit. Før du bytter til noen av disse bitene, bør vi også sjekke om I2C-bussen er opptatt ved å bruke funksjonen I2C_Hold som diskutert ovenfor.
ugyldig I2C_Begin () { I2C_Hold (); // Hold programmet er I2C er opptatt SEN = 1; // Begynn IIC pg85 / 234 } ugyldig I2C_End () { I2C_Hold (); // Hold programmet er I2C er opptatt PEN = 1; // Slutt IIC pg85 / 234 }
Ugyldig I2C_Write ()
Skrivefunksjonen brukes til å sende data fra mastermodulen til salvemodulen. Denne funksjonen brukes normalt etter en I2C-startfunksjon og etterfølges av en I2C-sluttfunksjon. Dataene som må skrives til IIC-bussen sendes gjennom de variable dataene. Disse dataene blir deretter lastet inn i SSPBUF-bufferregisteret for å sende dem over I2C-bussen.
Før du skriver data, blir det vanligvis skrevet en adresse, så du må bruke skrivefunksjonen to ganger, en gang for å angi adressen og den andre gangen for å sende de faktiske dataene.
ugyldig I2C_Write (usignerte data) { I2C_Hold (); // Hold programmet er I2C er opptatt SSPBUF = data; // pg82 / 234 }
usignert kort I2C_Read ()
Den siste funksjonen som vi må vite om er I2C_Read- funksjonen. Denne funksjonen brukes til å lese dataene som for øyeblikket er på I2C-bussen. Den brukes etter å ha bedt om en slave for å skrive noen verdi til bussen. Verdien som mottas vil være i SSPBUF. Vi kan overføre den verdien til hvilken som helst variabel for vår virksomhet.
Under en I2C-kommunikasjon vil slaven etter å ha sendt dataene som Master har bedt om, sende en annen bit som er bekreftelsesbiten. Denne biten bør også sjekkes av mesteren for å sikre at kommunikasjonen var vellykket. Etter å ha sjekket ACKDT-biten for bekreftelse, bør den aktiveres ved å sette ACKEN-biten.
usignert kort I2C_Read (usignert kort ack) { usignert kort innkommende; I2C_Hold (); RCEN = 1; I2C_Hold (); innkommende = SSPBUF; // få dataene lagret i SSPBUF I2C_Hold (); ACKDT = (ack)? 0: 1; // sjekk om ack-bit mottok ACKEN = 1; // sg 85/234 retur innkommende; }
Det er det, disse funksjonene skal være nok til å sette opp en I2C-kommunikasjon og skrive eller lese data fra en enhet. Vær også oppmerksom på at det er mange andre funksjoner som I2C-kommunikasjonen kan utføre, men for enkelhets skyld diskuterer vi dem ikke her. Du kan alltid henvise databladet for å få vite fullstendig bearbeiding av
Den komplette koden med topptekstfil for PIC16F877A I2C-kommunikasjon kan lastes ned fra lenken.
Programmering ved hjelp av I2C-headerfiler:
Nå som vi har lært hvordan en I2C-kommunikasjon fungerer og hvordan vi kan bruke toppfilen som er opprettet for den, la oss lage et enkelt program der vi skal bruke toppfilen og skrive noen verdier til I2C-linjene. Vi vil deretter simulere dette programmet og sjekke om disse verdiene skrives på bussen.
Som alltid begynner programmet med å sette opp konfigurasjonsbitene og stille klokkefrekvensen til 20 MHz som vist nedenfor
#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 is digital I / O, HV on MCLR må brukes for 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 programm memory) kan skrives til av EECON-kontroll) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) #define _XTAL_FREQ 20000000
Det neste trinnet ville være å legge til topptekstfilen som vi nettopp diskuterte om. Overskriftsfilen heter PIC16F877a_I2C.h og kan lastes ned fra lenken vi diskuterte ovenfor. Forsikre deg om at headerfilen er lagt til i headerfilen til prosjektlisten, prosjektfilstrukturen din skal se slik ut
Etter at du har forsikret deg om at headerfilen er lagt til i prosjektfilen, inkluderer du headerfilen i hoved-C-filen
#inkludere
Inne i mens sløyfen vil vi begynne I2C-kommunikasjonen, skrive noen tilfeldige verdier til I2C-bussen og deretter avslutte I2C-kommunikasjonen. De tilfeldige verdiene jeg har valgt er D0, 88 og FF. Du kan legge inn eventuelle verdier du vil ha. Men husk disse verdiene da vi skal verifisere dem i vår simulering.
mens (1) { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0x88); I2C_Write (0xFF); I2C_End (); __forsink_ms (1000); }
Hele programmet finner du nederst på siden, du kan bruke det eller laste ned hele zip-filen til programmet herfra. Etter å ha fått programmet, kompiler det og gjør deg klar for simulering.
Proteus simulering:
Proteus har et fint instrument som heter I2C debugger som kan brukes til å lese dataene på en I2C-buss, så la oss bygge en krets ved hjelp av den og sjekke om dataene blir skrevet. Hele kretsskjemaet er vist nedenfor
Last inn hex-filen som ble generert av programmet vårt ved å dobbeltklikke på Microcontroller. Simuler deretter programmet. Du vil legge merke til at et vindu dukker opp som viser all informasjon om I2C-bussen. Vinduet for programmet vårt vises nedenfor.
Hvis du ser nærmere på dataene som skrives, kan du legge merke til at de er de samme som vi skrev i vårt program. Verdiene er D0, 88 og FF. Verdiene skrives for hvert 1 sekund, så tiden oppdateres også som vist nedenfor. Den blå pilen indikerer at den er skrevet fra mester til slave, den vil peke i motsatt retning hvis ikke annet. En nærmere titt på dataene som sendes er vist nedenfor.
Dette er bare et glimt av hva I2C kan gjøre, det kan også lese og skrive data til flere enheter. Vi vil dekke mer om I2C i våre kommende opplæringsprogrammer ved å koble sammen forskjellige moduler som fungerer med I2C-protokollen.
Håper du forsto prosjektet og lærte noe nyttig av det. Hvis du er i tvil, legg dem inn i kommentarfeltet nedenfor, eller bruk forumene for teknisk hjelp.
Fullstendig kode er gitt nedenfor; du kan laste ned headerfiler med all koden herfra.