- Kaj je komunikacijski protokol I2C?
- Kako deluje komunikacija I2C?
- Kje uporabiti komunikacijo I2C?
- I2C s PIC16F877a z uporabo prevajalnika XC8
- Programiranje z uporabo datotek glave I2C:
- Simulacija proteja:
Mikrokrmilniki PIC so zmogljiva platforma, ki jo zagotavlja mikročip za vdelane projekte, zaradi svoje vsestranske narave je našel poti do številnih aplikacij, faza pa še poteka. Če bi sledili našim vadnicam PIC, bi opazili, da smo že od samih osnov pokrili širok spekter vadnic o mikrokrmilniku PIC. Od zdaj smo pokrivali osnove, s katerimi lahko pridemo do bolj zanimivih stvari, kot je komunikacijski portal.
V obsežnem sistemu vdelanih aplikacij noben mikrokrmilnik ne more sam izvajati vseh dejavnosti. V določeni fazi časa mora komunicirati z drugimi napravami za izmenjavo informacij, obstaja veliko različnih vrst komunikacijskih protokolov za izmenjavo teh informacij, najpogosteje pa se uporabljajo USART, IIC, SPI in CAN. Vsak komunikacijski protokol ima svojo prednost in slabost. Zaenkrat se osredotočimo na del IIC, saj se bomo tega naučili v tej vadnici.
Kaj je komunikacijski protokol I2C?
Izraz IIC pomeni " Inter integrirana vezja ". Običajno je označen kot I2C ali I na kvadrat C ali celo kot dvožični vmesniški protokol (TWI), ponekod pa vseeno pomeni enako. I2C je sinhroni komunikacijski protokol, kar pomeni, da morata obe napravi, ki si delita informacije, deliti skupen signal ure. Ima le dve žici za izmenjavo informacij, od katerih se ena uporablja za signal petelina, druga pa za pošiljanje in sprejemanje podatkov.
Kako deluje komunikacija I2C?
Komunikacijo I2C je prvi predstavil Phillips. Kot že rečeno, ima dve žici, ti dve žici bosta povezani med dvema napravama. Tu se ena naprava imenuje master, druga pa kot slave. Komunikacija bi morala in bo vedno potekala med dvema Master in Sužnjem. Prednost komunikacije I2C je v tem, da je na glavno enoto mogoče povezati več kot eno pomožno enoto.
Popolna komunikacija poteka prek teh dveh žic, in sicer serijske ure (SCL) in serijskih podatkov (SDA).
Serijska ura (SCL): deli urni signal, ki ga generira poveljnik, s pomožnim
Zaporedni podatki (SDA): pošlje podatke med glavno in pomožno enoto in med njimi.
Kadar koli bo komunikacijo lahko sprožil samo poveljnik. Ker je v vodilu več podrejenih naprav, se mora poveljnik sklicevati na vsakega podrejenega z drugim naslovom. Ko bo naslovljen, bo samo odgovor s tem naslovom odgovoril z informacijami, medtem ko bodo drugi nehali. Na ta način lahko z istim vodilom komuniciramo z več napravami.
Kje uporabiti komunikacijo I2C?
Komunikacija I2C se uporablja samo za komunikacijo na kratke razdalje. Vsekakor je zanesljiv do neke mere, saj ima sinhroniziran urni impulz, da postane pameten. Ta protokol se v glavnem uporablja za komunikacijo s senzorjem ali drugimi napravami, ki morajo informacije pošiljati glavnemu. Zelo priročno je, kadar mora mikrokrmilnik komunicirati s številnimi drugimi pomožnimi moduli z najmanj samo žicami. Če iščete komunikacijo na dolge razdalje, poskusite RS232, če pa iščete bolj zanesljivo komunikacijo, poskusite s protokolom SPI.
I2C s PIC16F877a z uporabo prevajalnika XC8
Dovolj uvodov, pojdimo vanj in se naučimo, kako lahko uporabimo mikrokrmilnik za izvajanje komunikacije I2C. Preden začnemo jasno povedati, da ta vadnica govori samo o I2C v PIC16F877a z uporabo prevajalnika XC8, bo postopek enak za druge mikrokrmilnike, vendar bodo morda potrebne manjše spremembe. Ne pozabite tudi, da ima za napredne mikrokrmilnike, kot je serija PIC18F, lahko sam prevajalnik vgrajeno nekaj knjižnice za uporabo funkcij I2C, vendar za PIC16F877A nič takega ne obstaja, zato ga zgradimo sami. Tu pojasnjena knjižnica bo dana na dnu kot datoteka z glavo, ki jo lahko PIC16F877A uporablja za komunikacijo z drugimi napravami I2C.
Kot vedno je najboljše mesto za začetek karkoli. Poiščite podrobnosti o I2C v obrazcu in preverite, katere registre je treba konfigurirati. Ne bom podrobneje razlagal, ker je v obrazcu to že storilo za vas. Nadalje bom razložil različne funkcije, ki so prisotne v zaglavni datoteki, in njihovo odgovornost v programu.
void I2C_Initialize ()
Funkcija inicializacije se uporablja, da mikrokrmilniku pove, da bomo uporabljali protokol I2C. To lahko storite z nastavitvijo potrebnih bitov v registru SSPCON in SSPCON2. Prvi korak bi bil razglasiti zatiče IIC kot vhodne zatiče, tu je treba zatiči RC3 in RC4 uporabiti za komunikacijo I2C, zato jih razglasimo kot vhodne zatiče. Nato bi morali nastaviti SSPCON in SSPCON2, ki sta nadzorna registra MSSP. PIC upravljamo v glavnem načinu IIC s taktno frekvenco FOSC / (4 * (SSPADD + 1)). Oglejte si številke strani obrazca, omenjene v spodnjih vrsticah za komentarje, da boste razumeli, zakaj je določen register nastavljen tako.
V nadaljevanju moramo torej nastaviti frekvenco ure, frekvenca takta za različne aplikacije se lahko razlikuje, zato od spremenljivke feq_k izbiramo od uporabnika in jo uporabimo v naših formulah za nastavitev registra SSPADD.
void I2C_Initialize (const unsigned long feq_K) // Začni IIC kot glavni { TRISC3 = 1; TRISC4 = 1; // Nastavite zatiče SDA in SCL kot vhodne zatiče SSPCON = 0b00101000; // pg84 / 234 SSPCON2 = 0b00000000; // pg85 / 234 SSPADD = (_XTAL_FREQ / (4 * feq_K * 100)) - 1; // Nastavitev takta pg99 / 234 SSPSTAT = 0b00000000; // pg83 / 234 }
Praznina I2C_Hold ()
Naslednja pomembna funkcija je funkcija I2C_hold, ki se uporablja za zadrževanje izvajanja naprave, dokler ni končana trenutna operacija I2C. Pred začetkom kakršne koli nove operacije bi morali preveriti, ali je treba opraviti operacije I2C. To lahko storite s preverjanjem registrov SSPSTAT in SSPCON2. SSPSTAT vsebuje informacije o stanju vodila I2C.
Zdi se, da je program nekoliko zapleten, saj vključuje operaterja "in" in "ali". Ko ga razbiješ kot
SSPSTAT & 0b00000100 SSPCON2 & 0b00011111
U
To pomeni, da skrbimo , da je drugi bit SSPSTAT nič in podobno bitov od 0 do 4 nič na SSPCON2. Nato vse to združimo, da preverimo, ali je rezultat enak nič. Če je rezultat enak nič, bo program nadaljeval, če ne, bo ostal tam, dokler ne dobi ničle, saj se uporablja v zanki while .
void I2C_Hold () { while ((SSPCON2 & 0b00011111) - (SSPSTAT & 0b00000100)); // preverite to v registrih in se prepričajte, da IIC ne deluje }
Void I2C_Begin () in void I2C_End ()
Vsakič, ko pišemo ali beremo podatke s pomočjo vodila I2C, moramo začeti in končati povezavo I2C. Za začetek komunikacije I2C moramo nastaviti bit SEN, za konec komunikacije pa bit stanja PEN. Preden preklopimo katerega koli od teh bitov, bi morali s funkcijo I2C_Hold, kot je opisano zgoraj, preveriti tudi, ali je vodilo I2C zasedeno.
void I2C_Begin () { I2C_Hold (); // Zadržite, da je program I2C zaseden SEN = 1; // Začetek IIC pg85 / 234 } void I2C_End () { I2C_Hold (); // Zadržite, da je program I2C zaseden PEN = 1; // konec IIC pg85 / 234 }
Praznina I2C_Write ()
Funkcija pisanja se uporablja za pošiljanje kakršnih koli podatkov iz glavnega modula v modul salve. Ta funkcija se običajno uporablja po funkciji začetka I2C in ji sledi funkcija konca I2C. Podatki, ki jih je treba zapisati v vodilo IIC, se posredujejo skozi spremenljivko podatkov. Ti podatki se nato naložijo v vmesni register SSPBUF in jih pošljejo preko vodila I2C.
Običajno bo pred pisanjem podatkov zapisan naslov, zato boste morali funkcijo pisanja uporabiti dvakrat, enkrat za nastavitev naslova in drugič za pošiljanje dejanskih podatkov.
void I2C_Write (nepodpisani podatki) { I2C_Hold (); // Zadržite, da je program I2C zaseden SSPBUF = podatki; // pg82 / 234 }
nepodpisana kratka I2C_Read ()
Končna funkcija, ki jo moramo vedeti, je funkcija I2C_Read . Ta funkcija se uporablja za branje podatkov, ki so trenutno na vodilu I2C. Uporablja se po tem, ko suženj prosi, da vpiše neko vrednost v vodilo. Prejeta vrednost bo v SSPBUF, ki jo lahko prenesemo v katero koli spremenljivko za naše delovanje.
Med komunikacijo I2C bo pomožni sistem po pošiljanju podatkov, ki jih zahteva Master, poslal še en bit, ki je potrditveni bit, tudi ta bit mora preveriti poveljnik, da se prepriča, ali je bila komunikacija uspešna. Po preverjanju potrdila bita ACKDT mora biti omogočeno z nastavitvijo bita ACKEN.
nepodpisan kratek I2C_Read (nepodpisan kratki ack) { nepodpisan kratek dohodni; I2C_Hold (); RCEN = 1; I2C_Hold (); dohodni = SSPBUF; // pridobimo podatke, shranjene v SSPBUF I2C_Hold (); ACKDT = (ack)? 0: 1; // preverimo, če je bit bit prejel ACKEN = 1; // str 85/234 vrnitev dohodne; }
To je to, te funkcije bi morale biti dovolj za vzpostavitev komunikacije I2C in pisanje ali branje podatkov iz naprave. Upoštevajte tudi, da lahko komunikacija I2C izvaja številne druge funkcije, vendar jih zaradi enostavnosti tukaj ne obravnavamo. Vedno se lahko obrnete na podatkovni list, da boste seznanjeni s celotnim delovanjem
Popolno kodo z glavo datoteke za komunikacijo I2C PIC16F877A lahko prenesete s povezave.
Programiranje z uporabo datotek glave I2C:
Zdaj, ko smo se naučili, kako deluje komunikacija I2C in kako lahko uporabimo datoteko glave, ustvarjeno zanjo, naredimo preprost program, v katerem bomo uporabili datoteko glave in v vrstice I2C zapisali nekaj vrednosti. Nato bomo simulirali ta program in preverili, ali so te vrednosti zapisane na vodilu.
Kot vedno se program začne z nastavitvijo nastavitvenih bitov in nastavitvijo frekvence ure na 20 MHz, kot je prikazano spodaj
#pragma config FOSC = HS // Oscilator bitov za izbiro (HS oscilator) #pragma config WDTE = OFF // Bit Watchg Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) # pragma config BOREN = ON // Rit-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Nizkonapetostni (enojni napajalnik) vklopni serijski programirni bit (RB3 je digitalni I / O, HV vklopljen) Za programiranje je treba uporabiti MCLR) #pragma config CPD = OFF // Bit EEPROM Data Protection Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bit (Write protection off; all programski pomnilnik lahko pošljejo na naslov EECON) #pragma config CP = OFF // Bit programa za zaščito pomnilniške kode Flash programa (zaščita kode izklopljena) #define _XTAL_FREQ 20000000
Naslednji korak bi bil dodati datoteko glave, o kateri smo pravkar razpravljali. Datoteka glave se imenuje PIC16F877a_I2C.h in jo je mogoče prenesti s povezave, o kateri smo govorili zgoraj. Prepričajte se, da je datoteka glave dodana v datoteko glave na seznamu projektov, struktura datoteke projekta mora biti videti tako
Ko se prepričate, da je datoteka glave dodana v datoteko projekta, vključite datoteko glave v glavno datoteko C.
#include
Znotraj zanke while bomo začeli komunikacijo I2C zapisati nekaj naključnih vrednosti na vodilo I2C in nato končati komunikacijo I2C. Naključne vrednosti, ki sem jih izbral, so D0, 88 in FF. Vnesete lahko poljubne vrednosti. Toda zapomnite si te vrednosti, saj jih bomo preverjali v naši simulaciji.
medtem ko (1) { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0x88); I2C_Write (0xFF); I2C_End (); __zakasnitev_ms (1000); }
Celoten program je mogoče najti na dnu strani, ga lahko uporabite ali prenesete celotno datoteko zip programa od tukaj. Potem ko ga program sestavi, se pripravite na simulacijo.
Simulacija proteja:
Proteus ima lep instrument, imenovan razhroščevalnik I2C, s katerim lahko beremo podatke na vodilu I2C, zato z njim zgradimo vezje in preverimo, ali se podatki uspešno zapisujejo. Celoten diagram vezja je prikazan spodaj
Naložite šestnajstiško datoteko, ki jo je ustvaril naš program, z dvojnim klikom na mikrokrmilnik. Nato simulirajte program. Opazili boste, da se prikaže okno, ki bi prikazovalo vse informacije o vodilu I2C. Okno za naš program je prikazano spodaj.
Če natančno pogledate podatke, ki jih pišete, lahko opazite, da so enaki kot smo jih zapisali v našem programu. Vrednosti so D0, 88 in FF. Vrednosti se zapisujejo vsakih 1 sekundo, zato se čas tudi posodablja, kot je prikazano spodaj. Modra puščica označuje, da je zapisano od glavnega do pomožnega, da bi bilo obrnjeno v nasprotni smeri, če ne. Podrobnejši pregled poslanih podatkov je prikazan spodaj.
To je le pogled na to, kaj lahko naredi I2C, lahko tudi bere in zapisuje podatke v več naprav. Več o I2C bomo obravnavali v naslednjih vajah s povezovanjem različnih modulov, ki delujejo s protokolom I2C.
Upam, da ste projekt razumeli in se iz njega naučili kaj koristnega. Če imate kakršne koli dvome, jih objavite v spodnjem oddelku za komentarje ali uporabite forum za tehnično pomoč.
Popolna koda je navedena spodaj; Datoteke z glavo z vso kodo lahko prenesete od tukaj.